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

Last change on this file since 3148 was 3148, checked in by nico, 11 years ago
  • Remove "_gd" suffix from dithering functions
  • caca_dithering_bitmap can load palette from gd resource
  • Remove caca_set_dither_palette_gd function
  • Adapt sample program "dithering.php"
File size: 56.0 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_get_font_list, NULL)
110        PHP_FE(caca_get_font_width, NULL)
111        PHP_FE(caca_get_font_height, NULL)
112        PHP_FE(caca_get_font_blocks, NULL)
113        PHP_FE(caca_render_canvas, NULL)
114        PHP_FE(caca_canvas_set_figfont, NULL)
115        PHP_FE(caca_put_figchar, NULL)
116        PHP_FE(caca_flush_figlet, NULL)
117        PHP_FE(caca_file_open, NULL)
118        PHP_FE(caca_file_close, NULL)
119        PHP_FE(caca_file_tell, NULL)
120        PHP_FE(caca_file_read, NULL)
121        PHP_FE(caca_file_write, NULL)
122        PHP_FE(caca_file_gets, NULL)
123        PHP_FE(caca_file_eof, NULL)
124        PHP_FE(caca_import_string, NULL)
125        PHP_FE(caca_import_file, NULL)
126        PHP_FE(caca_get_import_list, NULL)
127        PHP_FE(caca_export_string, NULL)
128        PHP_FE(caca_get_export_list, NULL)
129        PHP_FE(caca_create_display, NULL)
130        PHP_FE(caca_create_display_with_driver, NULL)
131        PHP_FE(caca_get_display_driver_list, NULL)
132        PHP_FE(caca_get_display_driver, NULL)
133        PHP_FE(caca_set_display_driver, NULL)
134        PHP_FE(caca_get_canvas, NULL)
135        PHP_FE(caca_refresh_display, NULL)
136        PHP_FE(caca_set_display_time, NULL)
137        PHP_FE(caca_get_display_time, NULL)
138        PHP_FE(caca_get_display_width, NULL)
139        PHP_FE(caca_get_display_height, NULL)
140        PHP_FE(caca_set_display_title, NULL)
141        PHP_FE(caca_set_mouse, NULL)
142        PHP_FE(caca_set_cursor, NULL)
143        PHP_FE(caca_get_event, NULL)
144        PHP_FE(caca_get_mouse_x, NULL)
145        PHP_FE(caca_get_mouse_y, NULL)
146        PHP_FE(caca_get_event_type, NULL)
147        PHP_FE(caca_get_event_key_ch, NULL)
148        PHP_FE(caca_get_event_mouse_button, NULL)
149        PHP_FE(caca_get_event_mouse_x, NULL)
150        PHP_FE(caca_get_event_mouse_y, NULL)
151        PHP_FE(caca_get_event_resize_width, NULL)
152        PHP_FE(caca_get_event_resize_height, NULL)
153
154        {NULL, NULL, NULL}
155};
156
157zend_module_entry caca_module_entry = {
158#if ZEND_MODULE_API_NO >= 20010901
159        STANDARD_MODULE_HEADER,
160#endif
161        PHP_CACA_EXTNAME,
162        caca_functions,
163        PHP_MINIT(caca),
164        NULL,
165        NULL,
166        NULL,
167        PHP_MINFO(caca),
168#if ZEND_MODULE_API_NO >= 20010901
169        PHP_CACA_VERSION,
170#endif
171        STANDARD_MODULE_PROPERTIES
172};
173
174#ifdef COMPILE_DL_CACA
175ZEND_GET_MODULE(caca)
176#endif
177
178PHP_MINFO_FUNCTION(caca) {
179        php_info_print_table_start();
180        php_info_print_table_row(2, "Caca library version", caca_get_version());
181        php_info_print_table_end();
182}
183
184//-------- Caca's ressources destructors -----------//
185
186static void php_caca_canvas_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
187        caca_free_canvas(rsrc->ptr);
188}
189
190static void php_caca_dither_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
191        caca_free_dither(rsrc->ptr);
192}
193
194static void php_caca_font_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
195        caca_free_font(rsrc->ptr);
196}
197
198static void php_caca_file_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
199}
200
201static void php_caca_display_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
202        caca_free_display(rsrc->ptr);
203}
204
205static void php_caca_event_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
206        efree((caca_event_t *) rsrc->ptr);
207}
208
209//-------- Initialization ---------//
210
211PHP_MINIT_FUNCTION(caca) {
212
213        le_caca_canvas = zend_register_list_destructors_ex(php_caca_canvas_dtor, NULL, PHP_CACA_CANVAS_RES_NAME, module_number);
214        le_caca_dither = zend_register_list_destructors_ex(php_caca_dither_dtor, NULL, PHP_CACA_DITHER_RES_NAME, module_number);
215        le_caca_font = zend_register_list_destructors_ex(php_caca_font_dtor, NULL, PHP_CACA_FONT_RES_NAME, module_number);
216        le_caca_file = zend_register_list_destructors_ex(php_caca_file_dtor, NULL, PHP_CACA_FILE_RES_NAME, module_number);
217        le_caca_display = zend_register_list_destructors_ex(php_caca_display_dtor, NULL, PHP_CACA_DISPLAY_RES_NAME, module_number);
218        le_caca_event = zend_register_list_destructors_ex(php_caca_event_dtor, NULL, PHP_CACA_EVENT_RES_NAME, module_number);
219       
220        REGISTER_LONG_CONSTANT("CACA_BLACK", CACA_BLACK, CONST_CS | CONST_PERSISTENT);
221        REGISTER_LONG_CONSTANT("CACA_BLUE", CACA_BLUE, CONST_CS | CONST_PERSISTENT);
222        REGISTER_LONG_CONSTANT("CACA_GREEN", CACA_GREEN, CONST_CS | CONST_PERSISTENT);
223        REGISTER_LONG_CONSTANT("CACA_CYAN", CACA_CYAN, CONST_CS | CONST_PERSISTENT);
224        REGISTER_LONG_CONSTANT("CACA_RED", CACA_RED, CONST_CS | CONST_PERSISTENT);
225        REGISTER_LONG_CONSTANT("CACA_MAGENTA", CACA_MAGENTA, CONST_CS | CONST_PERSISTENT);
226        REGISTER_LONG_CONSTANT("CACA_BROWN", CACA_BROWN, CONST_CS | CONST_PERSISTENT);
227        REGISTER_LONG_CONSTANT("CACA_LIGHTGRAY", CACA_LIGHTGRAY, CONST_CS | CONST_PERSISTENT);
228        REGISTER_LONG_CONSTANT("CACA_DARKGRAY", CACA_DARKGRAY, CONST_CS | CONST_PERSISTENT);
229        REGISTER_LONG_CONSTANT("CACA_LIGHTBLUE", CACA_LIGHTBLUE, CONST_CS | CONST_PERSISTENT);
230        REGISTER_LONG_CONSTANT("CACA_LIGHTGREEN", CACA_LIGHTGREEN, CONST_CS | CONST_PERSISTENT);
231        REGISTER_LONG_CONSTANT("CACA_LIGHTCYAN", CACA_LIGHTCYAN, CONST_CS | CONST_PERSISTENT);
232        REGISTER_LONG_CONSTANT("CACA_LIGHTRED", CACA_LIGHTRED, CONST_CS | CONST_PERSISTENT);
233        REGISTER_LONG_CONSTANT("CACA_LIGHTMAGENTA", CACA_LIGHTMAGENTA, CONST_CS | CONST_PERSISTENT);
234        REGISTER_LONG_CONSTANT("CACA_YELLOW", CACA_YELLOW, CONST_CS | CONST_PERSISTENT);
235        REGISTER_LONG_CONSTANT("CACA_WHITE", CACA_WHITE, CONST_CS | CONST_PERSISTENT);
236        REGISTER_LONG_CONSTANT("CACA_DEFAULT", CACA_DEFAULT, CONST_CS | CONST_PERSISTENT);
237        REGISTER_LONG_CONSTANT("CACA_TRANSPARENT", CACA_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
238        REGISTER_LONG_CONSTANT("CACA_BOLD", CACA_BOLD, CONST_CS | CONST_PERSISTENT);
239        REGISTER_LONG_CONSTANT("CACA_ITALICS", CACA_ITALICS, CONST_CS | CONST_PERSISTENT);
240        REGISTER_LONG_CONSTANT("CACA_UNDERLINE", CACA_UNDERLINE, CONST_CS | CONST_PERSISTENT);
241        REGISTER_LONG_CONSTANT("CACA_BLINK", CACA_BLINK, CONST_CS | CONST_PERSISTENT);
242
243        REGISTER_LONG_CONSTANT("CACA_EVENT_NONE", CACA_EVENT_NONE, CONST_CS | CONST_PERSISTENT);
244        REGISTER_LONG_CONSTANT("CACA_EVENT_KEY_PRESS", CACA_EVENT_KEY_PRESS, CONST_CS | CONST_PERSISTENT);
245        REGISTER_LONG_CONSTANT("CACA_EVENT_KEY_RELEASE", CACA_EVENT_KEY_RELEASE, CONST_CS | CONST_PERSISTENT);
246        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_PRESS", CACA_EVENT_MOUSE_PRESS, CONST_CS | CONST_PERSISTENT);
247        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_RELEASE", CACA_EVENT_MOUSE_RELEASE, CONST_CS | CONST_PERSISTENT);
248        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_MOTION", CACA_EVENT_MOUSE_MOTION, CONST_CS | CONST_PERSISTENT);
249        REGISTER_LONG_CONSTANT("CACA_EVENT_RESIZE", CACA_EVENT_RESIZE, CONST_CS | CONST_PERSISTENT);
250        REGISTER_LONG_CONSTANT("CACA_EVENT_QUIT", CACA_EVENT_QUIT, CONST_CS | CONST_PERSISTENT);
251        REGISTER_LONG_CONSTANT("CACA_EVENT_ANY", CACA_EVENT_ANY, CONST_CS | CONST_PERSISTENT);
252
253        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_A", CACA_KEY_CTRL_A, CONST_CS | CONST_PERSISTENT);
254        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_B", CACA_KEY_CTRL_B, CONST_CS | CONST_PERSISTENT);
255        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_C", CACA_KEY_CTRL_C, CONST_CS | CONST_PERSISTENT);
256        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_D", CACA_KEY_CTRL_D, CONST_CS | CONST_PERSISTENT);
257        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_E", CACA_KEY_CTRL_E, CONST_CS | CONST_PERSISTENT);
258        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_F", CACA_KEY_CTRL_F, CONST_CS | CONST_PERSISTENT);
259        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_G", CACA_KEY_CTRL_G, CONST_CS | CONST_PERSISTENT);
260        REGISTER_LONG_CONSTANT("CACA_KEY_BACKSPACE", CACA_KEY_BACKSPACE, CONST_CS | CONST_PERSISTENT);
261        REGISTER_LONG_CONSTANT("CACA_KEY_TAB", CACA_KEY_TAB, CONST_CS | CONST_PERSISTENT);
262        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_J", CACA_KEY_CTRL_J, CONST_CS | CONST_PERSISTENT);
263        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_K", CACA_KEY_CTRL_K, CONST_CS | CONST_PERSISTENT);
264        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_L", CACA_KEY_CTRL_L, CONST_CS | CONST_PERSISTENT);
265        REGISTER_LONG_CONSTANT("CACA_KEY_RETURN", CACA_KEY_RETURN, CONST_CS | CONST_PERSISTENT);
266        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_N", CACA_KEY_CTRL_N, CONST_CS | CONST_PERSISTENT);
267        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_O", CACA_KEY_CTRL_O, CONST_CS | CONST_PERSISTENT);
268        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_P", CACA_KEY_CTRL_P, CONST_CS | CONST_PERSISTENT);
269        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Q", CACA_KEY_CTRL_Q, CONST_CS | CONST_PERSISTENT);
270        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_R", CACA_KEY_CTRL_R, CONST_CS | CONST_PERSISTENT);
271        REGISTER_LONG_CONSTANT("CACA_KEY_PAUSE", CACA_KEY_PAUSE, CONST_CS | CONST_PERSISTENT);
272        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_T", CACA_KEY_CTRL_T, CONST_CS | CONST_PERSISTENT);
273        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_U", CACA_KEY_CTRL_U, CONST_CS | CONST_PERSISTENT);
274        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_V", CACA_KEY_CTRL_V, CONST_CS | CONST_PERSISTENT);
275        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_W", CACA_KEY_CTRL_W, CONST_CS | CONST_PERSISTENT);
276        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_X", CACA_KEY_CTRL_X, CONST_CS | CONST_PERSISTENT);
277        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Y", CACA_KEY_CTRL_Y, CONST_CS | CONST_PERSISTENT);
278        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Z", CACA_KEY_CTRL_Z, CONST_CS | CONST_PERSISTENT);
279        REGISTER_LONG_CONSTANT("CACA_KEY_ESCAPE", CACA_KEY_ESCAPE, CONST_CS | CONST_PERSISTENT);
280        REGISTER_LONG_CONSTANT("CACA_KEY_DELETE", CACA_KEY_DELETE, CONST_CS | CONST_PERSISTENT);
281        REGISTER_LONG_CONSTANT("CACA_KEY_UP", CACA_KEY_UP, CONST_CS | CONST_PERSISTENT);
282        REGISTER_LONG_CONSTANT("CACA_KEY_DOWN", CACA_KEY_DOWN, CONST_CS | CONST_PERSISTENT);
283        REGISTER_LONG_CONSTANT("CACA_KEY_LEFT", CACA_KEY_LEFT, CONST_CS | CONST_PERSISTENT);
284        REGISTER_LONG_CONSTANT("CACA_KEY_RIGHT", CACA_KEY_RIGHT, CONST_CS | CONST_PERSISTENT);
285        REGISTER_LONG_CONSTANT("CACA_KEY_INSERT", CACA_KEY_INSERT, CONST_CS | CONST_PERSISTENT);
286        REGISTER_LONG_CONSTANT("CACA_KEY_HOME", CACA_KEY_HOME, CONST_CS | CONST_PERSISTENT);
287        REGISTER_LONG_CONSTANT("CACA_KEY_END", CACA_KEY_END, CONST_CS | CONST_PERSISTENT);
288        REGISTER_LONG_CONSTANT("CACA_KEY_PAGEUP", CACA_KEY_PAGEUP, CONST_CS | CONST_PERSISTENT);
289        REGISTER_LONG_CONSTANT("CACA_KEY_PAGEDOWN", CACA_KEY_PAGEDOWN, CONST_CS | CONST_PERSISTENT);
290        REGISTER_LONG_CONSTANT("CACA_KEY_F1", CACA_KEY_F1, CONST_CS | CONST_PERSISTENT);
291        REGISTER_LONG_CONSTANT("CACA_KEY_F2", CACA_KEY_F2, CONST_CS | CONST_PERSISTENT);
292        REGISTER_LONG_CONSTANT("CACA_KEY_F3", CACA_KEY_F3, CONST_CS | CONST_PERSISTENT);
293        REGISTER_LONG_CONSTANT("CACA_KEY_F4", CACA_KEY_F4, CONST_CS | CONST_PERSISTENT);
294        REGISTER_LONG_CONSTANT("CACA_KEY_F5", CACA_KEY_F5, CONST_CS | CONST_PERSISTENT);
295        REGISTER_LONG_CONSTANT("CACA_KEY_F6", CACA_KEY_F6, CONST_CS | CONST_PERSISTENT);
296        REGISTER_LONG_CONSTANT("CACA_KEY_F7", CACA_KEY_F7, CONST_CS | CONST_PERSISTENT);
297        REGISTER_LONG_CONSTANT("CACA_KEY_F8", CACA_KEY_F8, CONST_CS | CONST_PERSISTENT);
298        REGISTER_LONG_CONSTANT("CACA_KEY_F9", CACA_KEY_F9, CONST_CS | CONST_PERSISTENT);
299        REGISTER_LONG_CONSTANT("CACA_KEY_F10", CACA_KEY_F10, CONST_CS | CONST_PERSISTENT);
300        REGISTER_LONG_CONSTANT("CACA_KEY_F11", CACA_KEY_F11, CONST_CS | CONST_PERSISTENT);
301        REGISTER_LONG_CONSTANT("CACA_KEY_F12", CACA_KEY_F12, CONST_CS | CONST_PERSISTENT);
302        REGISTER_LONG_CONSTANT("CACA_KEY_F13", CACA_KEY_F13, CONST_CS | CONST_PERSISTENT);
303        REGISTER_LONG_CONSTANT("CACA_KEY_F14", CACA_KEY_F14, CONST_CS | CONST_PERSISTENT);
304        REGISTER_LONG_CONSTANT("CACA_KEY_F15", CACA_KEY_F15, CONST_CS | CONST_PERSISTENT);
305
306        return SUCCESS;
307}
308
309//---------- Some usefull macros ---------------//
310
311#define FETCH_CANVAS(canvas) \
312        zval *_zval; \
313        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
314                RETURN_FALSE; \
315        } \
316        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
317
318#define FETCH_DISPLAY(display) \
319        zval *_zval; \
320        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
321                RETURN_FALSE; \
322        } \
323        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
324
325#define FETCH_EVENT(event) \
326        zval *_zval; \
327        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
328                RETURN_FALSE; \
329        } \
330        ZEND_FETCH_RESOURCE(event, caca_event_t*, &_zval, -1, PHP_CACA_EVENT_RES_NAME, le_caca_event);
331
332#define FETCH_LONG(l) \
333        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) == FAILURE) { \
334                RETURN_FALSE; \
335        }
336
337#define RETURN_CHAR(c) \
338        char *str = emalloc(2); \
339        str[0] = c; \
340        str[1] = '\0'; \
341        RETURN_STRING(str, 0);
342
343#define RETURN_SUCCESS(i) \
344        RETURN_BOOL((i) == 0);
345
346//---------- Some usefull functions --------------------//
347
348//Fetch external php resources such as gd resouces
349
350void *fetch_external_resource(zval *_zval, char const *type_name) {
351        int resource_id = _zval->value.lval;
352        int resource_type;
353        void *result = zend_list_find(resource_id, &resource_type);
354        if (!result)
355                return NULL;
356        char *resource_type_name = zend_rsrc_list_get_rsrc_type(resource_id);
357        return (strcmp(resource_type_name, type_name) == 0) ? result : NULL;
358}
359
360//Fetch buffer of pixels from gdImage
361
362void *gd_get_pixels(gdImage *img) {
363        if (img->trueColor)  {
364                int line_size = img->sx * sizeof(int);
365                void *result = malloc(img->sy * line_size);
366                int j;         
367                for (j = 0; j < img->sy; j++)
368                        memcpy(result + (j * line_size), (const void *) img->tpixels[j], line_size);
369                return result;
370        }
371        else {
372                int line_size = img->sx * sizeof(char);
373                void *result = malloc(img->sy * line_size);
374                int j;         
375                for (j = 0; j < img->sy; j++)
376                        memcpy(result + (j * line_size), (const void *) img->pixels[j], line_size);
377                return result;
378        }
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        ZEND_REGISTER_RESOURCE(return_value, dither, le_caca_dither);
1041}
1042
1043PHP_FUNCTION(caca_set_dither_palette) {
1044        zval *zval_res, *arr;
1045        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zval_res, &arr) == FAILURE) {
1046                RETURN_FALSE;
1047        }
1048
1049        caca_dither_t *dither;
1050        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &zval_res, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_dither);
1051
1052        uint32_t tbl[4][256];
1053        zval **color, **value;
1054        int i, j;
1055        for (i = 0; i < 256; i++) {
1056                if (zend_hash_index_find(Z_ARRVAL_P(arr), i, (void**) &color) == FAILURE || Z_TYPE_P(*color) != IS_ARRAY) {
1057                        RETURN_FALSE;
1058                }
1059                for (j = 0; j < 4; j++) {
1060                        if (zend_hash_index_find(Z_ARRVAL_P(*color), j, (void**) &value) == FAILURE) {
1061                                RETURN_FALSE;
1062                        }
1063                        convert_to_long_ex(value);
1064                        tbl[j][i] = Z_LVAL_PP(value);
1065                }
1066        }
1067        RETURN_SUCCESS(caca_set_dither_palette(dither, tbl[0], tbl[1], tbl[2], tbl[3]));
1068}
1069
1070PHP_FUNCTION(caca_set_dither_brightness) {
1071        zval *_zval;
1072        double value;
1073        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1074                RETURN_FALSE;
1075        }
1076        caca_dither_t *dither;
1077        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1078        RETURN_SUCCESS(caca_set_dither_brightness(dither, value));
1079}
1080
1081PHP_FUNCTION(caca_get_dither_brightness) {
1082        zval *_zval;
1083        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1084                RETURN_FALSE;
1085        }
1086        caca_dither_t *dither;
1087        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1088        RETURN_DOUBLE(caca_get_dither_brightness(dither));
1089}
1090
1091PHP_FUNCTION(caca_set_dither_gamma) {
1092        zval *_zval;
1093        double value;
1094        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1095                RETURN_FALSE;
1096        }
1097        caca_dither_t *dither;
1098        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1099        RETURN_SUCCESS(caca_set_dither_gamma(dither, value));
1100}
1101
1102PHP_FUNCTION(caca_get_dither_gamma) {
1103        zval *_zval;
1104        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1105                RETURN_FALSE;
1106        }
1107        caca_dither_t *dither;
1108        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1109        RETURN_DOUBLE(caca_get_dither_gamma(dither));
1110}
1111
1112PHP_FUNCTION(caca_set_dither_contrast) {
1113        zval *_zval;
1114        double value;
1115        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1116                RETURN_FALSE;
1117        }
1118        caca_dither_t *dither;
1119        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1120        RETURN_SUCCESS(caca_set_dither_contrast(dither, value));
1121}
1122
1123PHP_FUNCTION(caca_get_dither_contrast) {
1124        zval *_zval;
1125        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1126                RETURN_FALSE;
1127        }
1128        caca_dither_t *dither;
1129        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1130        RETURN_DOUBLE(caca_get_dither_contrast(dither));
1131}
1132
1133PHP_FUNCTION(caca_set_dither_antialias) {
1134        zval *_zval;
1135        int str_len;
1136        char *str;
1137        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1138                RETURN_FALSE;
1139        }
1140        caca_dither_t *dither;
1141        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1142        RETURN_SUCCESS(caca_set_dither_antialias(dither, str));
1143}
1144
1145PHP_FUNCTION(caca_get_dither_antialias_list) {
1146        //TODO: write
1147}
1148
1149PHP_FUNCTION(caca_get_dither_antialias) {
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        RETURN_STRING((char *) caca_get_dither_antialias(dither), 1);
1157}
1158
1159PHP_FUNCTION(caca_set_dither_color) {
1160        zval *_zval;
1161        int str_len;
1162        char *str;
1163        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1164                RETURN_FALSE;
1165        }
1166        caca_dither_t *dither;
1167        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1168        RETURN_SUCCESS(caca_set_dither_color(dither, str));
1169}
1170
1171PHP_FUNCTION(caca_get_dither_color_list) {
1172        zval *_zval;
1173        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1174                RETURN_FALSE;
1175        }
1176        caca_dither_t *dither;
1177        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1178
1179        char const * const *list = caca_get_dither_antialias_list(dither);
1180        int i;
1181        array_init(return_value);       
1182        for(i = 0; list[i]; i += 2)
1183                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1184}
1185
1186PHP_FUNCTION(caca_get_dither_color) {
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        RETURN_STRING((char *) caca_get_dither_color(dither), 1);
1194}
1195
1196PHP_FUNCTION(caca_set_dither_charset) {
1197        zval *_zval;
1198        int str_len;
1199        char *str;
1200        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1201                RETURN_FALSE;
1202        }
1203        caca_dither_t *dither;
1204        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1205        RETURN_SUCCESS(caca_set_dither_charset(dither, str));
1206}
1207
1208PHP_FUNCTION(caca_get_dither_charset_list) {
1209        zval *_zval;
1210        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1211                RETURN_FALSE;
1212        }
1213        caca_dither_t *dither;
1214        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1215
1216        char const * const *list = caca_get_dither_charset_list(dither);
1217        int i;
1218        array_init(return_value);       
1219        for(i = 0; list[i]; i += 2)
1220                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1221}
1222
1223PHP_FUNCTION(caca_get_dither_charset) {
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        RETURN_STRING((char *) caca_get_dither_charset(dither), 1);
1231}
1232
1233PHP_FUNCTION(caca_set_dither_algorithm) {
1234        zval *_zval;
1235        int str_len;
1236        char *str;
1237        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1238                RETURN_FALSE;
1239        }
1240        caca_dither_t *dither;
1241        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1242        RETURN_SUCCESS(caca_set_dither_algorithm(dither, str));
1243}
1244
1245PHP_FUNCTION(caca_get_dither_algorithm_list) {
1246        zval *_zval;
1247        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1248                RETURN_FALSE;
1249        }
1250        caca_dither_t *dither;
1251        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1252
1253        char const * const *list = caca_get_dither_algorithm_list(dither);
1254        int i;
1255        array_init(return_value);       
1256        for(i = 0; list[i]; i += 2)
1257                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1258}
1259
1260PHP_FUNCTION(caca_get_dither_algorithm) {
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        RETURN_STRING((char *) caca_get_dither_algorithm(dither), 1);
1268}
1269
1270PHP_FUNCTION(caca_dither_bitmap) {
1271        zval *_zval1, *_zval2, *_zval3;
1272        long x, y, w, h = 0;
1273        zend_bool load_palette = 1;
1274        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllllrr|b", &_zval1, &x, &y, &w, &h, &_zval2, &_zval3, &load_palette) == FAILURE) {
1275                RETURN_FALSE;
1276        }
1277
1278        caca_canvas_t *canvas;
1279        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval1, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1280        caca_dither_t *dither;
1281        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval2, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1282
1283        gdImage *img = fetch_external_resource(_zval3, "gd");
1284        if (!img) {
1285                RETURN_FALSE;
1286        }
1287
1288        void *pixels = gd_get_pixels(img);
1289        if (!pixels) {
1290                RETURN_FALSE;
1291        }
1292
1293        //load palette if image is not true color
1294        if (load_palette && !img->trueColor && gd_load_palette(img, dither) != 0) {
1295                RETURN_FALSE;
1296        }
1297
1298        caca_dither_bitmap(canvas, x, y, w, h, dither, pixels);
1299        free(pixels);
1300        RETURN_TRUE;
1301}
1302
1303PHP_FUNCTION(caca_load_font) {
1304        char *str;
1305        long str_len;
1306        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1307                RETURN_FALSE;
1308        }
1309        caca_font_t *font = caca_load_font(str, str_len);
1310        ZEND_REGISTER_RESOURCE(return_value, font, le_caca_font);
1311}
1312
1313PHP_FUNCTION(caca_get_font_list) {
1314        char const * const *list = caca_get_font_list();
1315        int i;
1316        array_init(return_value);       
1317        for(i = 0; list[i]; i += 1)
1318                add_next_index_string(return_value, (char*) list[i], 1);
1319}
1320
1321PHP_FUNCTION(caca_get_font_width) {
1322        zval *_zval;
1323        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1324                RETURN_FALSE;
1325        }
1326        caca_font_t *font;
1327        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1328        RETURN_LONG(caca_get_font_width(font));
1329}
1330
1331PHP_FUNCTION(caca_get_font_height) {
1332        zval *_zval;
1333        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1334                RETURN_FALSE;
1335        }
1336        caca_font_t *font;
1337        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1338        RETURN_LONG(caca_get_font_height(font));
1339}
1340
1341PHP_FUNCTION(caca_get_font_blocks) {
1342        zval *_zval;
1343        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1344                RETURN_FALSE;
1345        }
1346        caca_font_t *font;
1347        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1348
1349        uint32_t const *list = caca_get_font_blocks(font);
1350
1351        int i;
1352        array_init(return_value);       
1353        for(i = 0; list[i]; i += 1)
1354                add_next_index_long(return_value, list[i]);
1355}
1356
1357PHP_FUNCTION(caca_render_canvas) {
1358        //TODO: write
1359}
1360
1361PHP_FUNCTION(caca_canvas_set_figfont) {
1362        zval *_zval;
1363        char *font;
1364        long font_len;
1365        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &font, &font_len) == FAILURE) {
1366                RETURN_FALSE;
1367        }
1368        caca_canvas_t *canvas;
1369        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1370        RETURN_SUCCESS(caca_canvas_set_figfont(canvas, font));
1371}
1372
1373PHP_FUNCTION(caca_put_figchar) {
1374        zval *_zval;
1375        long c;
1376        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &c) == FAILURE) {
1377                RETURN_FALSE;
1378        }
1379        caca_canvas_t *canvas;
1380        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1381
1382        RETURN_SUCCESS(caca_put_figchar(canvas, c));
1383}
1384
1385PHP_FUNCTION(caca_flush_figlet) {
1386        zval *_zval;
1387        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1388                RETURN_FALSE;
1389        }
1390        caca_canvas_t *canvas;
1391        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1392        RETURN_SUCCESS(caca_flush_figlet(canvas));
1393}
1394
1395PHP_FUNCTION(caca_file_open) {
1396        char *path, *mode;
1397        long path_len, mode_len;
1398        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &mode, &mode_len) == FAILURE) {
1399                RETURN_FALSE;
1400        }
1401        caca_file_t *file = caca_file_open(path, mode);
1402        ZEND_REGISTER_RESOURCE(return_value, file, le_caca_file);
1403}
1404
1405PHP_FUNCTION(caca_file_close) {
1406        zval *_zval;
1407        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1408                RETURN_FALSE;
1409        }
1410        caca_file_t *file;
1411        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1412        //TODO: check that file was not already closed
1413        RETURN_SUCCESS(caca_file_close(file));
1414}
1415
1416PHP_FUNCTION(caca_file_tell) {
1417        zval *_zval;
1418        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1419                RETURN_FALSE;
1420        }
1421        caca_file_t *file;
1422        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1423        RETURN_LONG(caca_file_tell(file));
1424}
1425
1426PHP_FUNCTION(caca_file_read) {
1427        zval *_zval;
1428        long len;
1429        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &len) == FAILURE) {
1430                RETURN_FALSE;
1431        }
1432        caca_file_t *file;
1433        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1434
1435        if (len < 1) {
1436                RETURN_FALSE;
1437        }
1438        char *buffer = emalloc(len);
1439        if (!buffer) {
1440                RETURN_FALSE;
1441        }
1442        caca_file_read(file, buffer, len);
1443
1444        return_value->type = IS_STRING;
1445        return_value->value.str.len = len;
1446        return_value->value.str.val = buffer;
1447}
1448
1449PHP_FUNCTION(caca_file_write) {
1450        zval *_zval;
1451        char *buf;
1452        long buf_len = 0;
1453        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &buf, &buf_len) == FAILURE) {
1454                RETURN_FALSE;
1455        }
1456        caca_file_t *file;
1457        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1458        RETURN_LONG(caca_file_write(file, buf, buf_len));
1459}
1460
1461PHP_FUNCTION(caca_file_gets) {
1462        zval *_zval;
1463        long len = 0;
1464        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &len) == FAILURE) {
1465                RETURN_FALSE;
1466        }
1467        caca_file_t *file;
1468        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1469
1470        if (len < 1) {
1471                RETURN_FALSE;
1472        }
1473        char *buffer = emalloc(len);
1474        if (!buffer) {
1475                RETURN_FALSE;
1476        }
1477        char *result = caca_file_gets(file, buffer, len);
1478        if (!result) {
1479                RETURN_FALSE;
1480        }
1481        return_value->type = IS_STRING;
1482        return_value->value.str.len = len;
1483        return_value->value.str.val = result;
1484}
1485
1486PHP_FUNCTION(caca_file_eof) {
1487        zval *_zval;
1488        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1489                RETURN_FALSE;
1490        }
1491        caca_file_t *file;
1492        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1493        RETURN_BOOL(caca_file_eof(file) != 0);
1494}
1495
1496PHP_FUNCTION(caca_import_string) {
1497        zval *_zval;
1498        char *src, *format;
1499        long src_len, format_len = 0;
1500        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &_zval, &src, &src_len, &format, &format_len) == FAILURE) {
1501                RETURN_FALSE;
1502        }
1503        caca_canvas_t *canvas;
1504        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1505
1506        RETURN_LONG(caca_import_memory(canvas, src, src_len, format));
1507}
1508
1509PHP_FUNCTION(caca_import_file) {
1510        zval *_zval;
1511        char *filename, *format;
1512        long filename_len, format_len = 0;
1513        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &_zval, &filename, &filename_len, &format, &format_len) == FAILURE) {
1514                RETURN_FALSE;
1515        }
1516        caca_canvas_t *canvas;
1517        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1518
1519        RETURN_LONG(caca_import_file(canvas, filename, format));
1520}
1521
1522PHP_FUNCTION(caca_get_import_list) {
1523        char const * const *list = caca_get_import_list();
1524        int i;
1525        array_init(return_value);       
1526        for(i = 0; list[i]; i += 2)
1527                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1528}
1529
1530PHP_FUNCTION(caca_export_string) {
1531        zval *_zval;
1532        char *type;
1533        long type_len;
1534        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &type, &type_len) == FAILURE) {
1535                RETURN_FALSE;
1536        }
1537        caca_canvas_t *canvas;
1538        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1539
1540        void *buffer, *copy;
1541        size_t len;
1542        buffer = caca_export_memory(canvas, type, &len);
1543        copy = emalloc(len);
1544        if (!buffer || !copy) {
1545                RETURN_FALSE;
1546        }
1547        memcpy(copy, buffer, len);
1548        free(buffer);
1549
1550        return_value->type = IS_STRING;
1551        return_value->value.str.len = len;
1552        return_value->value.str.val = copy;
1553}
1554
1555PHP_FUNCTION(caca_get_export_list) {
1556        char const * const *list = caca_get_export_list();
1557        int i;
1558        array_init(return_value);       
1559        for(i = 0; list[i]; i += 2)
1560                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1561}
1562
1563PHP_FUNCTION(caca_create_display) {
1564        caca_canvas_t *canvas;
1565        FETCH_CANVAS(canvas);
1566
1567        caca_display_t *display = caca_create_display(canvas);
1568        ZEND_REGISTER_RESOURCE(return_value, display, le_caca_display);
1569}
1570
1571PHP_FUNCTION(caca_create_display_with_driver) {
1572        zval *_zval;
1573        char *str;
1574        long str_len = 0;
1575        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1576                RETURN_FALSE;
1577        }
1578        caca_canvas_t *canvas;
1579        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1580
1581        caca_display_t *display = caca_create_display_with_driver(canvas, str);
1582        if (!display) {
1583                RETURN_FALSE;
1584        }
1585        ZEND_REGISTER_RESOURCE(return_value, display, le_caca_display);
1586}
1587
1588PHP_FUNCTION(caca_get_display_driver_list) {
1589        char const * const *list = caca_get_display_driver_list();
1590        int i;
1591        array_init(return_value);       
1592        for(i = 0; list[i]; i += 2)
1593                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1594}
1595
1596PHP_FUNCTION(caca_get_display_driver) {
1597        zval *_zval;
1598        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1599                RETURN_FALSE;
1600        }
1601        caca_display_t *display;
1602        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1603        RETURN_STRING((char *) caca_get_display_driver(display), 1);
1604}
1605
1606PHP_FUNCTION(caca_set_display_driver) {
1607        zval *_zval;
1608        char *str;
1609        long str_len;
1610        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1611                RETURN_FALSE;
1612        }
1613        caca_display_t *display;
1614        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1615        RETURN_SUCESS(caca_set_display_driver(display, str));
1616}
1617
1618PHP_FUNCTION(caca_get_canvas) {
1619        zval *_zval;
1620        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1621                RETURN_FALSE;
1622        }
1623        caca_display_t *display;
1624        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1625        caca_canvas_t *canvas = caca_get_canvas(display);
1626        ZEND_REGISTER_RESOURCE(return_value, canvas, le_caca_canvas);
1627}
1628
1629PHP_FUNCTION(caca_refresh_display) {
1630        caca_display_t *display;
1631        FETCH_DISPLAY(display);
1632        RETURN_SUCCESS(caca_refresh_display(display));
1633}
1634
1635PHP_FUNCTION(caca_set_display_time) {
1636        zval *_zval;
1637        long value = 0;
1638        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1639                RETURN_FALSE;
1640        }
1641        caca_display_t *display;
1642        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1643        RETURN_SUCCESS(caca_set_display_time(display, value));
1644}
1645
1646PHP_FUNCTION(caca_get_display_time) {
1647        caca_display_t *display;
1648        FETCH_DISPLAY(display);
1649        RETURN_LONG(caca_get_display_time(display));
1650}
1651
1652PHP_FUNCTION(caca_get_display_width) {
1653        caca_display_t *display;
1654        FETCH_DISPLAY(display);
1655        RETURN_LONG(caca_get_display_width(display));
1656}
1657
1658PHP_FUNCTION(caca_get_display_height) {
1659        caca_display_t *display;
1660        FETCH_DISPLAY(display);
1661        RETURN_LONG(caca_get_display_height(display));
1662}
1663
1664PHP_FUNCTION(caca_set_display_title) {
1665        zval *_zval;
1666        char *str;
1667        long str_len = 0;
1668        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1669                RETURN_FALSE;
1670        }
1671        caca_display_t *display;
1672        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1673        RETURN_SUCCESS(caca_set_display(display, str));
1674}
1675
1676PHP_FUNCTION(caca_set_mouse) {
1677        zval *_zval;
1678        long value = 0;
1679        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1680                RETURN_FALSE;
1681        }
1682        caca_display_t *display;
1683        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1684        RETURN_SUCCESS(caca_set_mouse(display, value));
1685}
1686
1687PHP_FUNCTION(caca_set_cursor) {
1688        zval *_zval;
1689        long value = 0;
1690        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1691                RETURN_FALSE;
1692        }
1693        caca_display_t *display;
1694        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1695        RETURN_SUCCESS(caca_set_cursor(display, value));
1696}
1697
1698PHP_FUNCTION(caca_get_event) {
1699        zval *_zval = NULL;
1700        long g, aa = 0;
1701        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &_zval, &g, &aa) == FAILURE) {
1702                RETURN_FALSE;
1703        }
1704        caca_display_t *display;
1705        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1706
1707        caca_event_t *event = emalloc(sizeof(caca_event_t));
1708        if (!event) {
1709                RETURN_FALSE;
1710        }
1711
1712        caca_get_event(display, g, event, aa);
1713
1714        if (caca_get_event_type(event) == CACA_EVENT_NONE) {
1715                efree(event);   
1716                RETURN_FALSE;
1717        }
1718        ZEND_REGISTER_RESOURCE(return_value, event, le_caca_event);
1719}
1720
1721PHP_FUNCTION(caca_get_mouse_x) {
1722        caca_display_t *display;
1723        FETCH_DISPLAY(display);
1724        RETURN_LONG(caca_get_mouse_x(display));
1725}
1726
1727PHP_FUNCTION(caca_get_mouse_y) {
1728        caca_display_t *display;
1729        FETCH_DISPLAY(display);
1730        RETURN_LONG(caca_get_mouse_y(display));
1731}
1732
1733PHP_FUNCTION(caca_get_event_type) {
1734        caca_event_t *event;
1735        FETCH_EVENT(event);
1736        RETURN_LONG(caca_get_event_type(event));
1737}
1738
1739PHP_FUNCTION(caca_get_event_key_ch) {
1740        caca_event_t *event;
1741        FETCH_EVENT(event);
1742        RETURN_LONG(caca_get_event_key_ch(event));
1743}
1744
1745PHP_FUNCTION(caca_get_event_mouse_button) {
1746        caca_event_t *event;
1747        FETCH_EVENT(event);
1748        RETURN_LONG(caca_get_event_mouse_button(event));
1749}
1750
1751PHP_FUNCTION(caca_get_event_mouse_x) {
1752        caca_event_t *event;
1753        FETCH_EVENT(event);
1754        RETURN_LONG(caca_get_event_mouse_x(event));
1755}
1756
1757PHP_FUNCTION(caca_get_event_mouse_y) {
1758        caca_event_t *event;
1759        FETCH_EVENT(event);
1760        RETURN_LONG(caca_get_event_mouse_y(event));
1761}
1762
1763PHP_FUNCTION(caca_get_event_resize_width) {
1764        caca_event_t *event;
1765        FETCH_EVENT(event);
1766        RETURN_LONG(caca_get_event_resize_width(event));
1767}
1768
1769PHP_FUNCTION(caca_get_event_resize_height) {
1770        caca_event_t *event;
1771        FETCH_EVENT(event);
1772        RETURN_LONG(caca_get_event_resize_height(event));
1773}
1774
Note: See TracBrowser for help on using the repository browser.