From f61bed2bdbae57a7ed2c54b660d29cd09d872ed4 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 11 Nov 2006 14:24:35 +0000 Subject: [PATCH] * Add cursor and handle support to canvases. Unused yet. --- TODO | 2 - cucul/canvas.c | 97 +++++++++++++++++++++++++++++++++++++++++ cucul/cucul.c | 5 +++ cucul/cucul.h | 6 +++ cucul/cucul_internals.h | 2 + cucul/export.c | 12 +++-- cucul/frame.c | 9 +++- cucul/import.c | 10 ++++- 8 files changed, 133 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index c7ed7cf..db0b6b2 100644 --- a/TODO +++ b/TODO @@ -6,8 +6,6 @@ - allow to change the canvas size in a per-frame basis. - export attribute parsing functions such as attr_to_ansi4fg etc. - - add cursor support in the canvas, so that we can load ANSI files - in stream mode. \subsection indep API-independent stuff diff --git a/cucul/canvas.c b/cucul/canvas.c index 7a5ad3c..eefcab2 100644 --- a/cucul/canvas.c +++ b/cucul/canvas.c @@ -41,6 +41,55 @@ #include "cucul.h" #include "cucul_internals.h" +/** \brief Set cursor position. + * + * Put the cursor at the given coordinates. Functions making use of the + * cursor will use the new values. Setting the cursor position outside the + * canvas is legal but the cursor will not be shown. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \param x X cursor coordinate. + * \param y Y cursor coordinate. + * \return This function always returns 0. + */ +int cucul_gotoxy(cucul_canvas_t *cv, int x, int y) +{ + cv->frames[cv->frame].x = x; + cv->frames[cv->frame].y = y; + + return 0; +} + +/** \brief Get X cursor position. + * + * Retrieve the X coordinate of the cursor's position. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \return The cursor's X coordinate. + */ +int cucul_get_cursor_x(cucul_canvas_t *cv) +{ + return cv->frames[cv->frame].x; +} + +/** \brief Get Y cursor position. + * + * Retrieve the Y coordinate of the cursor's position. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \return The cursor's Y coordinate. + */ +int cucul_get_cursor_y(cucul_canvas_t *cv) +{ + return cv->frames[cv->frame].y; +} + /** \brief Print an ASCII or Unicode character. * * Print an ASCII or Unicode character at the given coordinates, using @@ -264,6 +313,54 @@ int cucul_clear_canvas(cucul_canvas_t *cv) return 0; } +/** \brief Set cursor handle. + * + * Set the canvas' handle. Blitting functions will use the handle value + * to put the canvas at the proper coordinates. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \param x X handle coordinate. + * \param y Y handle coordinate. + * \return This function always returns 0. + */ +int cucul_set_canvas_handle(cucul_canvas_t *cv, int x, int y) +{ + cv->frames[cv->frame].handlex = x; + cv->frames[cv->frame].handley = y; + + return 0; +} + +/** \brief Get X handle position. + * + * Retrieve the X coordinate of the canvas' handle. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \return The canvas' handle's X coordinate. + */ +int cucul_get_canvas_handle_x(cucul_canvas_t *cv) +{ + return cv->frames[cv->frame].handlex; +} + +/** \brief Get Y handle position. + * + * Retrieve the Y coordinate of the canvas' handle. + * + * This function never fails. + * + * \param cv A handle to the libcucul canvas. + * \return The canvas' handle's Y coordinate. + */ +int cucul_get_canvas_handle_y(cucul_canvas_t *cv) +{ + return cv->frames[cv->frame].handley; +} + /** \brief Blit a canvas onto another one. * * Blit a canvas onto another one at the given coordinates. diff --git a/cucul/cucul.c b/cucul/cucul.c index b63378e..b552231 100644 --- a/cucul/cucul.c +++ b/cucul/cucul.c @@ -43,6 +43,9 @@ * \e libcucul function to be called in a function. cucul_free_canvas() * should be called at the end of the program to free all allocated resources. * + * Both the cursor and the canvas' handle are initialised at the top-left + * corner. + * * If an error occurs, NULL is returned and \b errno is set accordingly: * - \c ENOMEM Not enough memory for the requested canvas size. * @@ -78,6 +81,8 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height) cv->frames[0].width = cv->frames[0].height = 0; cv->frames[0].chars = NULL; cv->frames[0].attrs = NULL; + cv->frames[0].x = cv->frames[0].y = 0; + cv->frames[0].handlex = cv->frames[0].handley = 0; cv->frames[0].curattr = cv->curattr; if(_cucul_set_canvas_size(cv, width, height) < 0) diff --git a/cucul/cucul.h b/cucul/cucul.h index 56a5b31..4821e84 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -89,6 +89,9 @@ int cucul_rand(int, int); * * @{ */ #define CUCUL_MAGIC_FULLWIDTH 0x000ffffe /**< Used to indicate that the previous character was a fullwidth glyph. */ +int cucul_gotoxy(cucul_canvas_t *, int, int); +int cucul_get_cursor_x(cucul_canvas_t *); +int cucul_get_cursor_y(cucul_canvas_t *); unsigned long int cucul_get_attr(cucul_canvas_t *, int, int); int cucul_set_attr(cucul_canvas_t *, unsigned long int); int cucul_putattr(cucul_canvas_t *, int, int, unsigned long int); @@ -99,6 +102,9 @@ unsigned long int cucul_getchar(cucul_canvas_t *, int, int); int cucul_putstr(cucul_canvas_t *, int, int, char const *); int cucul_printf(cucul_canvas_t *, int, int, char const *, ...); int cucul_clear_canvas(cucul_canvas_t *); +int cucul_set_canvas_handle(cucul_canvas_t *, int, int); +int cucul_get_canvas_handle_x(cucul_canvas_t *); +int cucul_get_canvas_handle_y(cucul_canvas_t *); int cucul_blit(cucul_canvas_t *, int, int, cucul_canvas_t const *, cucul_canvas_t const *); int cucul_set_canvas_boundaries(cucul_canvas_t *, int, int, diff --git a/cucul/cucul_internals.h b/cucul/cucul_internals.h index 7283025..7fdc941 100644 --- a/cucul/cucul_internals.h +++ b/cucul/cucul_internals.h @@ -28,6 +28,8 @@ struct cucul_frame uint32_t *attrs; /* Painting context */ + int x, y; + int handlex, handley; uint32_t curattr; }; diff --git a/cucul/export.c b/cucul/export.c index ebbf080..a5daf58 100644 --- a/cucul/export.c +++ b/cucul/export.c @@ -171,14 +171,14 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) * - 16 bytes for the canvas header * - 24 bytes for the frame info * 8 bytes for each character cell */ - *bytes = 44 + 8 * cv->width * cv->height; + *bytes = 52 + 8 * cv->width * cv->height; cur = data = malloc(*bytes); /* magic */ cur += sprintf(cur, "%s", "\xCA\xCA" "CV"); /* canvas_header */ - cur += sprintu32(cur, 16 + 24); + cur += sprintu32(cur, 16 + 32 * 1); cur += sprintu32(cur, cv->width * cv->height * 8); cur += sprintu16(cur, 0x0001); cur += sprintu32(cur, 1); @@ -189,8 +189,10 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) cur += sprintu32(cur, cv->height); cur += sprintu32(cur, 0); cur += sprintu32(cur, cv->curattr); - cur += sprintu32(cur, 0); - cur += sprintu32(cur, 0); + cur += sprintu32(cur, cv->frames[0].x); + cur += sprintu32(cur, cv->frames[0].y); + cur += sprintu32(cur, cv->frames[0].handlex); + cur += sprintu32(cur, cv->frames[0].handley); /* canvas_data */ for(n = cv->height * cv->width; n--; ) @@ -236,6 +238,8 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) * uint32_t duration; // Frame duration in milliseconds, 0 to * // not specify a duration * uint32_t attr; // Graphics context attribute + * int32_t cursor_x; // Cursor X coordinate + * int32_t cursor_y; // Cursor Y coordinate * int32_t handle_x; // Handle X coordinate * int32_t handle_y; // Handle Y coordinate * } diff --git a/cucul/frame.c b/cucul/frame.c index 2148fb7..6ce447f 100644 --- a/cucul/frame.c +++ b/cucul/frame.c @@ -114,6 +114,9 @@ int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int id) for(f = cv->framecount - 1; f > id; f--) cv->frames[f] = cv->frames[f - 1]; + if(cv->frame >= id) + cv->frame++; + cv->frames[id].width = cv->width; cv->frames[id].height = cv->height; cv->frames[id].chars = malloc(size * sizeof(uint32_t)); @@ -122,8 +125,10 @@ int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int id) memcpy(cv->frames[id].attrs, cv->attrs, size * sizeof(uint32_t)); cv->frames[id].curattr = cv->curattr; - if(cv->frame >= id) - cv->frame++; + cv->frames[id].x = cv->frames[cv->frame].x; + cv->frames[id].y = cv->frames[cv->frame].y; + cv->frames[id].handlex = cv->frames[cv->frame].handlex; + cv->frames[id].handley = cv->frames[cv->frame].handley; return 0; } diff --git a/cucul/import.c b/cucul/import.c index 936aeac..0fe91da 100644 --- a/cucul/import.c +++ b/cucul/import.c @@ -247,14 +247,14 @@ static long int import_caca(cucul_canvas_t *cv, if(size < 4 + control_size + data_size) return 0; - if(control_size < 16 + frames * 24) + if(control_size < 16 + frames * 32) goto invalid_caca; for(expected_size = 0, f = 0; f < frames; f++) { unsigned int width, height, duration; uint32_t attr; - int x, y; + int x, y, handlex, handley; width = sscanu32(buf + 4 + 16 + f * 24); height = sscanu32(buf + 4 + 16 + f * 24 + 4); @@ -262,6 +262,8 @@ static long int import_caca(cucul_canvas_t *cv, attr = sscanu32(buf + 4 + 16 + f * 24 + 12); x = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 16); y = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 20); + handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 24); + handley = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 28); expected_size += width * height * 8; } @@ -283,6 +285,10 @@ static long int import_caca(cucul_canvas_t *cv, } cv->curattr = sscanu32(buf + 4 + 16 + 12); + cv->frames[0].x = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 16); + cv->frames[0].y = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 20); + cv->frames[0].handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 24); + cv->frames[0].handley = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 28); return 4 + control_size + data_size;