drivers no longer need to access the cv->refcount private member and __cucul_set_canvas_size() is no longer needed.tags/v0.99.beta14
@@ -42,6 +42,7 @@ | |||
# define x11_install(p) caca_plugin_install("x11", p) | |||
#endif | |||
static int caca_can_resize(caca_display_t *); | |||
static int caca_select_driver(caca_display_t *); | |||
#if defined(USE_PLUGINS) | |||
static int caca_plugin_install(char const *, caca_display_t *); | |||
@@ -61,7 +62,7 @@ static int caca_plugin_install(char const *, caca_display_t *); | |||
* \param cv The cucul cavas. | |||
* \return The caca graphical context or NULL if an error occurred. | |||
*/ | |||
caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||
caca_display_t * caca_create_display(cucul_canvas_t *cv) | |||
{ | |||
caca_display_t *dp = malloc(sizeof(caca_display_t)); | |||
@@ -71,6 +72,13 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||
return NULL; | |||
} | |||
if(cucul_manage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp)) | |||
{ | |||
free(dp); | |||
seterrno(EBUSY); | |||
return NULL; | |||
} | |||
dp->cv = cv; | |||
#if defined(USE_PLUGINS) | |||
dp->plugin = NULL; | |||
@@ -82,6 +90,7 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||
if(dp->plugin) | |||
dlclose(dp->plugin); | |||
#endif | |||
cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||
free(dp); | |||
seterrno(ENODEV); | |||
return NULL; | |||
@@ -93,14 +102,12 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||
if(dp->plugin) | |||
dlclose(dp->plugin); | |||
#endif | |||
cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||
free(dp); | |||
seterrno(ENODEV); | |||
return NULL; | |||
} | |||
/* Attached! */ | |||
dp->cv->refcount++; | |||
/* Graphics stuff */ | |||
dp->delay = 0; | |||
dp->rendertime = 0; | |||
@@ -127,6 +134,7 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||
/* Resize events */ | |||
dp->resize.resized = 0; | |||
dp->resize.allow = 0; | |||
return dp; | |||
} | |||
@@ -149,7 +157,7 @@ int caca_free_display(caca_display_t *dp) | |||
if(dp->plugin) | |||
dlclose(dp->plugin); | |||
#endif | |||
dp->cv->refcount--; | |||
cucul_unmanage_canvas(dp->cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||
free(dp); | |||
return 0; | |||
@@ -159,6 +167,11 @@ int caca_free_display(caca_display_t *dp) | |||
* XXX: The following functions are local. | |||
*/ | |||
static int caca_can_resize(caca_display_t *dp) | |||
{ | |||
return dp->resize.allow; | |||
} | |||
static int caca_select_driver(caca_display_t *dp) | |||
{ | |||
#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | |||
@@ -141,6 +141,7 @@ struct caca_display | |||
struct resize | |||
{ | |||
int resized; /* A resize event was requested */ | |||
int allow; /* The display driver allows resizing */ | |||
unsigned w, h; /* Requested width and height */ | |||
} resize; | |||
@@ -834,7 +834,9 @@ static int cocoa_init_graphics(caca_display_t *dp) | |||
return -1; | |||
unsigned int width = dp->cv->width, height = dp->cv->height; | |||
__cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 0; | |||
// first create a full cocoa app if the host has no bundle | |||
if(![[NSBundle mainBundle] bundleIdentifier]) | |||
@@ -58,8 +58,11 @@ static int conio_init_graphics(caca_display_t *dp) | |||
# else | |||
/* FIXME */ | |||
# endif | |||
__cucul_set_canvas_size(dp->cv, dp->drv.p->ti.screenwidth, | |||
dp->drv.p->ti.screenheight); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, dp->drv.p->ti.screenwidth, | |||
dp->drv.p->ti.screenheight); | |||
dp->resize.allow = 0; | |||
return 0; | |||
} | |||
@@ -102,7 +102,9 @@ static int gl_init_graphics(caca_display_t *dp) | |||
sscanf(geometry, "%ux%u", &width, &height); | |||
#endif | |||
__cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 0; | |||
/* Load a libcucul internal font */ | |||
fonts = cucul_get_font_list(); | |||
@@ -301,7 +301,9 @@ static int ncurses_init_graphics(caca_display_t *dp) | |||
} | |||
} | |||
__cucul_set_canvas_size(dp->cv, COLS, LINES); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, COLS, LINES); | |||
dp->resize.allow = 0; | |||
return 0; | |||
} | |||
@@ -40,7 +40,9 @@ static int raw_init_graphics(caca_display_t *dp) | |||
sscanf(geometry, "%ux%u", &width, &height); | |||
#endif | |||
__cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 24); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 24); | |||
dp->resize.allow = 0; | |||
return 0; | |||
} | |||
@@ -170,7 +170,9 @@ static int slang_init_graphics(caca_display_t *dp) | |||
SLtt_utf8_enable(1); | |||
#endif | |||
__cucul_set_canvas_size(dp->cv, SLtt_Screen_Cols, SLtt_Screen_Rows); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, SLtt_Screen_Cols, SLtt_Screen_Rows); | |||
dp->resize.allow = 0; | |||
return 0; | |||
} | |||
@@ -76,7 +76,9 @@ static int vga_init_graphics(caca_display_t *dp) | |||
outb(tmp, 0x3d5); | |||
/* We don't have much choice */ | |||
__cucul_set_canvas_size(dp->cv, 80, 25); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, 80, 25); | |||
dp->resize.allow = 0; | |||
return 0; | |||
} | |||
@@ -126,9 +126,11 @@ static int win32_init_graphics(caca_display_t *dp) | |||
if(!GetConsoleScreenBufferInfo(dp->drv.p->screen, &csbi)) | |||
return -1; | |||
__cucul_set_canvas_size(dp->cv, | |||
csbi.srWindow.Right - csbi.srWindow.Left + 1, | |||
csbi.srWindow.Bottom - csbi.srWindow.Top + 1); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, | |||
csbi.srWindow.Right - csbi.srWindow.Left + 1, | |||
csbi.srWindow.Bottom - csbi.srWindow.Top + 1); | |||
dp->resize.allow = 0; | |||
SetConsoleMode(dp->drv.p->screen, 0); | |||
@@ -88,7 +88,9 @@ static int x11_init_graphics(caca_display_t *dp) | |||
sscanf(geometry, "%ux%u", &width, &height); | |||
#endif | |||
__cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, width ? width : 80, height ? height : 32); | |||
dp->resize.allow = 0; | |||
dp->drv.p->dpy = XOpenDisplay(NULL); | |||
if(dp->drv.p->dpy == NULL) | |||
@@ -238,7 +238,11 @@ void _caca_handle_resize(caca_display_t *dp) | |||
/* Tell libcucul we changed size */ | |||
if(dp->resize.w != dp->cv->width || dp->resize.h != dp->cv->height) | |||
__cucul_set_canvas_size(dp->cv, dp->resize.w, dp->resize.h); | |||
{ | |||
dp->resize.allow = 1; | |||
cucul_set_canvas_size(dp->cv, dp->resize.w, dp->resize.h); | |||
dp->resize.allow = 0; | |||
} | |||
} | |||
void _caca_set_term_title(char const *str) | |||
@@ -34,6 +34,8 @@ | |||
#include "cucul.h" | |||
#include "cucul_internals.h" | |||
static int cucul_resize(cucul_canvas_t *, unsigned int, unsigned int); | |||
/** \brief Initialise a \e libcucul canvas. | |||
* | |||
* Initialise internal \e libcucul structures and the backend that will | |||
@@ -60,6 +62,8 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height) | |||
cv->refcount = 0; | |||
cv->autoinc = 0; | |||
cv->resize_callback = NULL; | |||
cv->resize_data = NULL; | |||
cv->frame = 0; | |||
cv->framecount = 1; | |||
@@ -81,7 +85,7 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height) | |||
_cucul_load_frame_info(cv); | |||
cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_TRANSPARENT); | |||
if(__cucul_set_canvas_size(cv, width, height) < 0) | |||
if(cucul_resize(cv, width, height) < 0) | |||
{ | |||
int saved_errno = geterrno(); | |||
free(cv->frames[0].name); | |||
@@ -98,6 +102,70 @@ nomem: | |||
return NULL; | |||
} | |||
/** \brief Manage a canvas. | |||
* | |||
* Lock a canvas to prevent it from being resized. If non-NULL, | |||
* the \e callback function pointer will be called upon each | |||
* \e cucul_set_canvas_size call and if the returned value is zero, the | |||
* canvas resize request will be denied. | |||
* | |||
* This function is only useful for display drivers such as the \e libcaca | |||
* library. | |||
* | |||
* If an error occurs, -1 is returned and \b errno is set accordingly: | |||
* - \c EBUSY The canvas is already being managed. | |||
* | |||
* \param cv A libcucul canvas. | |||
* \param callback An optional callback function pointer. | |||
* \param p The argument to be passed to \e callback. | |||
* \return 0 in case of success, -1 if an error occurred. | |||
*/ | |||
int cucul_manage_canvas(cucul_canvas_t *cv, int (*callback)(void *), void *p) | |||
{ | |||
if(cv->refcount) | |||
{ | |||
seterrno(EBUSY); | |||
return -1; | |||
} | |||
cv->refcount = 1; | |||
return 0; | |||
} | |||
/** \brief Unmanage a canvas. | |||
* | |||
* Unlock a canvas previously locked by cucul_manage_canvas(). For safety | |||
* reasons, the callback and callback data arguments must be the same as for | |||
* the cucul_manage_canvas() call. | |||
* | |||
* This function is only useful for display drivers such as the \e libcaca | |||
* library. | |||
* | |||
* If an error occurs, -1 is returned and \b errno is set accordingly: | |||
* - \c EINVAL The canvas is not managed, or the callback arguments do | |||
* not match. | |||
* | |||
* \param cv A libcucul canvas. | |||
* \param callback The \e callback argument previously passed to | |||
cucul_manage_canvas(). | |||
* \param p The \e p argument previously passed to cucul_manage_canvas(). | |||
* \return 0 in case of success, -1 if an error occurred. | |||
*/ | |||
int cucul_unmanage_canvas(cucul_canvas_t *cv, int (*callback)(void *), void *p) | |||
{ | |||
if(!cv->refcount | |||
|| cv->resize_callback != callback || cv->resize_data != p) | |||
{ | |||
seterrno(EINVAL); | |||
return -1; | |||
} | |||
cv->refcount = 0; | |||
return 0; | |||
} | |||
/** \brief Resize a canvas. | |||
* | |||
* Set the canvas' width and height, in character cells. | |||
@@ -123,21 +191,22 @@ nomem: | |||
* - \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 | |||
* \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. | |||
*/ | |||
int cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||
unsigned int height) | |||
{ | |||
if(cv->refcount) | |||
if(cv->refcount && cv->resize_callback | |||
&& !cv->resize_callback(cv->resize_data)) | |||
{ | |||
seterrno(EBUSY); | |||
return -1; | |||
} | |||
return __cucul_set_canvas_size(cv, width, height); | |||
return cucul_resize(cv, width, height); | |||
} | |||
/** \brief Get the canvas width. | |||
@@ -146,7 +215,7 @@ int cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||
* | |||
* This function never fails. | |||
* | |||
* \param cv A libcucul canvas | |||
* \param cv A libcucul canvas. | |||
* \return The canvas width. | |||
*/ | |||
unsigned int cucul_get_canvas_width(cucul_canvas_t const *cv) | |||
@@ -160,7 +229,7 @@ unsigned int cucul_get_canvas_width(cucul_canvas_t const *cv) | |||
* | |||
* This function never fails. | |||
* | |||
* \param cv A libcucul canvas | |||
* \param cv A libcucul canvas. | |||
* \return The canvas height. | |||
*/ | |||
unsigned int cucul_get_canvas_height(cucul_canvas_t const *cv) | |||
@@ -177,7 +246,7 @@ unsigned int cucul_get_canvas_height(cucul_canvas_t const *cv) | |||
* 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 | |||
* \param cv A libcucul canvas. | |||
* \return 0 in case of success, -1 if an error occurred. | |||
*/ | |||
int cucul_free_canvas(cucul_canvas_t *cv) | |||
@@ -231,8 +300,7 @@ int cucul_rand(int min, int max) | |||
* XXX: The following functions are local. | |||
*/ | |||
int __cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||
unsigned int height) | |||
int cucul_resize(cucul_canvas_t *cv, unsigned int width, unsigned int height) | |||
{ | |||
unsigned int x, y, f, old_width, old_height, new_size, old_size; | |||
@@ -84,6 +84,8 @@ typedef struct cucul_font cucul_font_t; | |||
* | |||
* @{ */ | |||
__extern cucul_canvas_t * cucul_create_canvas(unsigned int, unsigned int); | |||
__extern int cucul_manage_canvas(cucul_canvas_t *, int (*)(void *), void *); | |||
__extern int cucul_unmanage_canvas(cucul_canvas_t *, int (*)(void *), void *); | |||
__extern int cucul_set_canvas_size(cucul_canvas_t *, unsigned int, | |||
unsigned int); | |||
__extern unsigned int cucul_get_canvas_width(cucul_canvas_t const *); | |||
@@ -43,8 +43,11 @@ struct cucul_canvas | |||
unsigned int frame, framecount; | |||
struct cucul_frame *frames; | |||
/* Canvas management */ | |||
unsigned int refcount; | |||
unsigned int autoinc; | |||
int (*resize_callback)(void *); | |||
void *resize_data; | |||
/* Shortcut to the active frame information */ | |||
unsigned int width, height; | |||
@@ -60,10 +63,6 @@ struct cucul_buffer | |||
int user_data; | |||
}; | |||
/* Canvas functions */ | |||
extern int __cucul_set_canvas_size(cucul_canvas_t *, | |||
unsigned int, unsigned int); | |||
/* Colour functions */ | |||
extern uint16_t _cucul_attr_to_rgb12fg(uint32_t); | |||
extern uint16_t _cucul_attr_to_rgb12bg(uint32_t); | |||
@@ -1,4 +0,0 @@ | |||
LIBRARY "libcucul" | |||
EXPORTS | |||
__cucul_set_canvas_size ; Private symbol used by libcaca |