Browse Source

* More error checking in libcucul.

tags/v0.99.beta14
Sam Hocevar sam 19 years ago
parent
commit
235504d81a
5 changed files with 161 additions and 35 deletions
  1. +22
    -11
      cucul/canvas.c
  2. +30
    -4
      cucul/colour.c
  3. +100
    -11
      cucul/cucul.c
  4. +8
    -8
      cucul/cucul.h
  5. +1
    -1
      cucul/cucul_internals.h

+ 22
- 11
cucul/canvas.c View File

@@ -58,17 +58,18 @@
* \param ch The character to print.
* \return This function always returns 0.
*/
void cucul_putchar(cucul_canvas_t *cv, int x, int y, char ch)
int cucul_putchar(cucul_canvas_t *cv, int x, int y, char ch)
{
if(x < 0 || x >= (int)cv->width ||
y < 0 || y >= (int)cv->height)
return;
if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height)
return 0;

if((unsigned char)ch < 0x20 || (unsigned char)ch > 0x7f)
ch = 0x20;

cv->chars[x + y * cv->width] = ch;
cv->attr[x + y * cv->width] = (cv->bgcolor << 16) | cv->fgcolor;

return 0;
}

/** \brief Print a string.
@@ -86,20 +87,20 @@ void cucul_putchar(cucul_canvas_t *cv, int x, int y, char ch)
* \param s The string to print.
* \return This function always returns 0.
*/
void cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s)
int cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s)
{
uint32_t *chars, *attr;
unsigned int len;

if(y < 0 || y >= (int)cv->height || x >= (int)cv->width)
return;
return 0;

len = _cucul_strlen_utf8(s);

if(x < 0)
{
if(len < (unsigned int)-x)
return;
return 0;
len -= -x;
s = _cucul_skip_utf8(s, -x);
x = 0;
@@ -119,6 +120,8 @@ void cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s)
s = _cucul_skip_utf8(s, 1);
len--;
}

return 0;
}

/** \brief Print a formated string.
@@ -138,14 +141,14 @@ void cucul_putstr(cucul_canvas_t *cv, int x, int y, char const *s)
* \param ... Arguments to the format string.
* \return This function always returns 0.
*/
void cucul_printf(cucul_canvas_t *cv, int x, int y, char const *format, ...)
int cucul_printf(cucul_canvas_t *cv, int x, int y, char const *format, ...)
{
char tmp[BUFSIZ];
char *buf = tmp;
va_list args;

if(y < 0 || y >= (int)cv->height || x >= (int)cv->width)
return;
return 0;

if(cv->width - x + 1 > BUFSIZ)
buf = malloc(cv->width - x + 1);
@@ -163,6 +166,8 @@ void cucul_printf(cucul_canvas_t *cv, int x, int y, char const *format, ...)

if(buf != tmp)
free(buf);

return 0;
}

/** \brief Clear the canvas.
@@ -174,7 +179,7 @@ void cucul_printf(cucul_canvas_t *cv, int x, int y, char const *format, ...)
* \param cv The canvas to clear.
* \return This function always returns 0.
*/
void cucul_clear_canvas(cucul_canvas_t *cv)
int cucul_clear_canvas(cucul_canvas_t *cv)
{
uint32_t color = (cv->bgcolor << 16) | cv->fgcolor;
unsigned int n;
@@ -185,6 +190,8 @@ void cucul_clear_canvas(cucul_canvas_t *cv)
cv->chars[n] = (uint32_t)' ';
cv->attr[n] = color;
}

return 0;
}

/** \brief Blit a canvas onto another one.
@@ -192,12 +199,16 @@ void cucul_clear_canvas(cucul_canvas_t *cv)
* This function blits a canvas onto another one at the given coordinates.
* An optional mask canvas can be used.
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL A mask was specified but the mask size and source canvas
* size do not match.
*
* \param dst The destination canvas.
* \param x X coordinate.
* \param y Y coordinate.
* \param src The source canvas.
* \param mask The mask canvas.
* \return 0 in case of success, -1 otherwise.
* \return 0 in case of success, -1 if an error occurred.
*/
int cucul_blit(cucul_canvas_t *dst, int x, int y,
cucul_canvas_t const *src, cucul_canvas_t const *mask)


+ 30
- 4
cucul/colour.c View File

@@ -19,6 +19,10 @@
#include "config.h"
#include "common.h"

#if defined(HAVE_ERRNO_H)
# include <errno.h>
#endif

#include "cucul.h"
#include "cucul_internals.h"

@@ -37,17 +41,28 @@ static const uint16_t ansitab[16] =
* Color values are those defined in cucul.h, such as CUCUL_COLOR_RED
* or CUCUL_COLOR_TRANSPARENT.
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL At least one of the colour values is invalid.
*
* \param cv A handle to the libcucul canvas.
* \param fg The requested foreground colour.
* \param bg The requested background colour.
* \return 0 in case of success, -1 if an error occurred.
*/
void cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
{
if(fg > 0x20 || bg > 0x20)
return;
{
#if defined(HAVE_ERRNO_H)
errno = EINVAL;
#endif
return -1;
}

cv->fgcolor = fg;
cv->bgcolor = bg;

return 0;
}

/** \brief Set the default colour pair (truecolor version).
@@ -60,14 +75,23 @@ void cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
* instance, 0xf088 is solid dark cyan (A=15 R=0 G=8 B=8), and 0x8fff is
* white with 50% alpha (A=8 R=15 G=15 B=15).
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EINVAL At least one of the colour values is invalid.
*
* \param cv A handle to the libcucul canvas.
* \param fg The requested foreground colour.
* \param bg The requested background colour.
* \return 0 in case of success, -1 if an error occurred.
*/
void cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
{
if(fg > 0xffff || bg > 0xffff)
return;
{
#if defined(HAVE_ERRNO_H)
errno = EINVAL;
#endif
return -1;
}

if(fg < 0x100)
fg += 0x100;
@@ -77,6 +101,8 @@ void cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)

cv->fgcolor = fg;
cv->bgcolor = bg;

return 0;
}

/*


+ 100
- 11
cucul/cucul.c View File

@@ -23,6 +23,9 @@
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# if defined(HAVE_ERRNO_H)
# include <errno.h>
# endif
#endif

#include "cucul.h"
@@ -38,6 +41,9 @@
* If one of the desired canvas coordinates is zero, a default canvas size
* of 80x32 is used instead.
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c ENOMEM Not enough memory for the requested canvas size.
*
* \param width The desired canvas width
* \param height The desired canvas height
* \return A libcucul canvas handle upon success, NULL if an error occurred.
@@ -45,6 +51,10 @@
cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
{
cucul_canvas_t *cv = malloc(sizeof(cucul_canvas_t));
int ret;

if(!cv)
goto nomem;

cv->refcount = 0;

@@ -58,7 +68,18 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
cv->frame = 0;
cv->framecount = 1;
cv->allchars = malloc(sizeof(uint32_t *));
if(!cv->allchars)
{
free(cv);
goto nomem;
}
cv->allattr = malloc(sizeof(uint32_t *));
if(!cv->allattr)
{
free(cv->allchars);
free(cv);
goto nomem;
}
cv->allchars[0] = NULL;
cv->allattr[0] = NULL;

@@ -66,17 +87,34 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
* default X11 window. When a graphic driver attaches to us, it can set
* a different size. */
if(width && height)
_cucul_set_canvas_size(cv, width, height);
ret = _cucul_set_canvas_size(cv, width, height);
else
_cucul_set_canvas_size(cv, 80, 32);
ret = _cucul_set_canvas_size(cv, 80, 32);

if(_cucul_init_dither())
if(ret < 0)
{
#if defined(HAVE_ERRNO_H)
int saved_errno = errno;
#endif
free(cv->allattr);
free(cv->allchars);
free(cv);
#if defined(HAVE_ERRNO_H)
errno = saved_errno;
#endif
return NULL;
}

/* FIXME: this shouldn't happen here */
_cucul_init_dither();

return cv;

nomem:
#if defined(HAVE_ERRNO_H)
errno = ENOMEM;
#endif
return NULL;
}

/** \brief Resize a canvas.
@@ -94,23 +132,36 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height)
* canvas resize through user interaction. See the caca_event() documentation
* for more about this.
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EBUSY The canvas is in use by a display driver and cannot be resized.
* - \c ENOMEM Not enough memory for the requested canvas size. If this
* happens, the canvas handle becomes invalid and should not be used.
*
* \param cv A libcucul canvas
* \param width The desired canvas width
* \param height The desired canvas height
* \return 0 in case of success, -1 if an error occurred.
*/
void cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
unsigned int height)
int cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
unsigned int height)
{
if(cv->refcount)
return;
{
#if defined(HAVE_ERRNO_H)
errno = EBUSY;
#endif
return -1;
}

_cucul_set_canvas_size(cv, width, height);
return _cucul_set_canvas_size(cv, width, height);
}

/** \brief Get the canvas width.
*
* This function returns the current canvas width, in character cells.
*
* This function never fails.
*
* \param cv A libcucul canvas
* \return The canvas width.
*/
@@ -123,6 +174,8 @@ unsigned int cucul_get_canvas_width(cucul_canvas_t *cv)
*
* This function returns the current canvas height, in character cells.
*
* This function never fails.
*
* \param cv A libcucul canvas
* \return The canvas height.
*/
@@ -136,8 +189,11 @@ unsigned int cucul_get_canvas_height(cucul_canvas_t *cv)
* This function translates a cucul_color enum into a human-readable
* description string of the associated colour.
*
* This function never fails.
*
* \param color The colour value.
* \return A static string containing the colour's name.
* \return A static string containing the colour's name, or \c "unknown" if
* the colour is unknown.
*/
char const *cucul_get_color_name(unsigned int color)
{
@@ -173,12 +229,25 @@ char const *cucul_get_color_name(unsigned int color)
* cucul_free_canvas() has been called, no other \e libcucul functions may be
* used unless a new call to cucul_create_canvas() is done.
*
* If an error occurs, -1 is returned and \b errno is set accordingly:
* - \c EBUSY The canvas is in use by a display driver and cannot be freed.
*
* \param cv A libcucul canvas
* \return 0 in case of success, -1 if an error occurred.
*/
void cucul_free_canvas(cucul_canvas_t *cv)
int cucul_free_canvas(cucul_canvas_t *cv)
{
unsigned int f;

if(cv->refcount)
{
#if defined(HAVE_ERRNO_H)
errno = EBUSY;
#endif
return -1;
}

/* FIXME: this shouldn't be here either (see above) */
_cucul_end_dither();

for(f = 0; f < cv->framecount; f++)
@@ -188,9 +257,13 @@ void cucul_free_canvas(cucul_canvas_t *cv)
}

free(cv);

return 0;
}

/** \brief Generate a random integer within a range.
*
* This function never fails.
*
* \param min The lower bound of the integer range.
* \param max The upper bound of the integer range.
@@ -206,8 +279,8 @@ int cucul_rand(int min, int max)
* XXX: The following functions are local.
*/

void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
unsigned int height)
int _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
unsigned int height)
{
unsigned int x, y, f, old_width, old_height, new_size, old_size;

@@ -228,6 +301,13 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
{
#if defined(HAVE_ERRNO_H)
errno = ENOMEM;
#endif
return -1;
}
}
}

@@ -310,11 +390,20 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width,
new_size * sizeof(uint32_t));
cv->allattr[f] = realloc(cv->allattr[f],
new_size * sizeof(uint32_t));
if(!cv->allchars[f] || !cv->allattr[f])
{
#if defined(HAVE_ERRNO_H)
errno = ENOMEM;
#endif
return -1;
}
}
}

/* Reset the current frame shortcut */
cv->chars = cv->allchars[cv->frame];
cv->attr = cv->allattr[cv->frame];

return 0;
}


+ 8
- 8
cucul/cucul.h View File

@@ -72,10 +72,10 @@ typedef struct cucul_font cucul_font_t;
*
* @{ */
cucul_canvas_t * cucul_create_canvas(unsigned int, unsigned int);
void cucul_set_canvas_size(cucul_canvas_t *, unsigned int, unsigned int);
int cucul_set_canvas_size(cucul_canvas_t *, unsigned int, unsigned int);
unsigned int cucul_get_canvas_width(cucul_canvas_t *);
unsigned int cucul_get_canvas_height(cucul_canvas_t *);
void cucul_free_canvas(cucul_canvas_t *);
int cucul_free_canvas(cucul_canvas_t *);
int cucul_rand(int, int);
/* @} */

@@ -95,13 +95,13 @@ int cucul_free_buffer(cucul_buffer_t *);
* higher level graphics functions.
*
* @{ */
void cucul_set_color(cucul_canvas_t *, unsigned char, unsigned char);
void cucul_set_truecolor(cucul_canvas_t *, unsigned int, unsigned int);
int cucul_set_color(cucul_canvas_t *, unsigned char, unsigned char);
int cucul_set_truecolor(cucul_canvas_t *, unsigned int, unsigned int);
char const *cucul_get_color_name(unsigned int);
void cucul_putchar(cucul_canvas_t *, int, int, char);
void cucul_putstr(cucul_canvas_t *, int, int, char const *);
void cucul_printf(cucul_canvas_t *, int, int, char const *, ...);
void cucul_clear_canvas(cucul_canvas_t *);
int cucul_putchar(cucul_canvas_t *, int, int, char);
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_blit(cucul_canvas_t *, int, int, cucul_canvas_t const *, cucul_canvas_t const *);
/* @} */



+ 1
- 1
cucul/cucul_internals.h View File

@@ -50,7 +50,7 @@ extern int _cucul_init_dither(void);
extern int _cucul_end_dither(void);

/* Canvas functions */
extern void _cucul_set_canvas_size(cucul_canvas_t *, unsigned int, unsigned int);
extern int _cucul_set_canvas_size(cucul_canvas_t *, unsigned int, unsigned int);
extern void _cucul_putchar32(cucul_canvas_t *, int, int, uint32_t);

/* Charset functions */


Loading…
Cancel
Save