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) | # define x11_install(p) caca_plugin_install("x11", p) | ||||
#endif | #endif | ||||
static int caca_can_resize(caca_display_t *); | |||||
static int caca_select_driver(caca_display_t *); | static int caca_select_driver(caca_display_t *); | ||||
#if defined(USE_PLUGINS) | #if defined(USE_PLUGINS) | ||||
static int caca_plugin_install(char const *, caca_display_t *); | 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. | * \param cv The cucul cavas. | ||||
* \return The caca graphical context or NULL if an error occurred. | * \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)); | 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; | return NULL; | ||||
} | } | ||||
if(cucul_manage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp)) | |||||
{ | |||||
free(dp); | |||||
seterrno(EBUSY); | |||||
return NULL; | |||||
} | |||||
dp->cv = cv; | dp->cv = cv; | ||||
#if defined(USE_PLUGINS) | #if defined(USE_PLUGINS) | ||||
dp->plugin = NULL; | dp->plugin = NULL; | ||||
@@ -82,6 +90,7 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||||
if(dp->plugin) | if(dp->plugin) | ||||
dlclose(dp->plugin); | dlclose(dp->plugin); | ||||
#endif | #endif | ||||
cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||||
free(dp); | free(dp); | ||||
seterrno(ENODEV); | seterrno(ENODEV); | ||||
return NULL; | return NULL; | ||||
@@ -93,14 +102,12 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||||
if(dp->plugin) | if(dp->plugin) | ||||
dlclose(dp->plugin); | dlclose(dp->plugin); | ||||
#endif | #endif | ||||
cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||||
free(dp); | free(dp); | ||||
seterrno(ENODEV); | seterrno(ENODEV); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
/* Attached! */ | |||||
dp->cv->refcount++; | |||||
/* Graphics stuff */ | /* Graphics stuff */ | ||||
dp->delay = 0; | dp->delay = 0; | ||||
dp->rendertime = 0; | dp->rendertime = 0; | ||||
@@ -127,6 +134,7 @@ caca_display_t * caca_create_display(cucul_canvas_t * cv) | |||||
/* Resize events */ | /* Resize events */ | ||||
dp->resize.resized = 0; | dp->resize.resized = 0; | ||||
dp->resize.allow = 0; | |||||
return dp; | return dp; | ||||
} | } | ||||
@@ -149,7 +157,7 @@ int caca_free_display(caca_display_t *dp) | |||||
if(dp->plugin) | if(dp->plugin) | ||||
dlclose(dp->plugin); | dlclose(dp->plugin); | ||||
#endif | #endif | ||||
dp->cv->refcount--; | |||||
cucul_unmanage_canvas(dp->cv, (int (*)(void *))caca_can_resize, (void *)dp); | |||||
free(dp); | free(dp); | ||||
return 0; | return 0; | ||||
@@ -159,6 +167,11 @@ int caca_free_display(caca_display_t *dp) | |||||
* XXX: The following functions are local. | * 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) | static int caca_select_driver(caca_display_t *dp) | ||||
{ | { | ||||
#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | ||||
@@ -141,6 +141,7 @@ struct caca_display | |||||
struct resize | struct resize | ||||
{ | { | ||||
int resized; /* A resize event was requested */ | int resized; /* A resize event was requested */ | ||||
int allow; /* The display driver allows resizing */ | |||||
unsigned w, h; /* Requested width and height */ | unsigned w, h; /* Requested width and height */ | ||||
} resize; | } resize; | ||||
@@ -834,7 +834,9 @@ static int cocoa_init_graphics(caca_display_t *dp) | |||||
return -1; | return -1; | ||||
unsigned int width = dp->cv->width, height = dp->cv->height; | 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 | // first create a full cocoa app if the host has no bundle | ||||
if(![[NSBundle mainBundle] bundleIdentifier]) | if(![[NSBundle mainBundle] bundleIdentifier]) | ||||
@@ -58,8 +58,11 @@ static int conio_init_graphics(caca_display_t *dp) | |||||
# else | # else | ||||
/* FIXME */ | /* FIXME */ | ||||
# endif | # 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; | return 0; | ||||
} | } | ||||
@@ -102,7 +102,9 @@ static int gl_init_graphics(caca_display_t *dp) | |||||
sscanf(geometry, "%ux%u", &width, &height); | sscanf(geometry, "%ux%u", &width, &height); | ||||
#endif | #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 */ | /* Load a libcucul internal font */ | ||||
fonts = cucul_get_font_list(); | 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; | return 0; | ||||
} | } | ||||
@@ -40,7 +40,9 @@ static int raw_init_graphics(caca_display_t *dp) | |||||
sscanf(geometry, "%ux%u", &width, &height); | sscanf(geometry, "%ux%u", &width, &height); | ||||
#endif | #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; | return 0; | ||||
} | } | ||||
@@ -170,7 +170,9 @@ static int slang_init_graphics(caca_display_t *dp) | |||||
SLtt_utf8_enable(1); | SLtt_utf8_enable(1); | ||||
#endif | #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; | return 0; | ||||
} | } | ||||
@@ -76,7 +76,9 @@ static int vga_init_graphics(caca_display_t *dp) | |||||
outb(tmp, 0x3d5); | outb(tmp, 0x3d5); | ||||
/* We don't have much choice */ | /* 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; | return 0; | ||||
} | } | ||||
@@ -126,9 +126,11 @@ static int win32_init_graphics(caca_display_t *dp) | |||||
if(!GetConsoleScreenBufferInfo(dp->drv.p->screen, &csbi)) | if(!GetConsoleScreenBufferInfo(dp->drv.p->screen, &csbi)) | ||||
return -1; | 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); | 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); | sscanf(geometry, "%ux%u", &width, &height); | ||||
#endif | #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); | dp->drv.p->dpy = XOpenDisplay(NULL); | ||||
if(dp->drv.p->dpy == NULL) | if(dp->drv.p->dpy == NULL) | ||||
@@ -238,7 +238,11 @@ void _caca_handle_resize(caca_display_t *dp) | |||||
/* Tell libcucul we changed size */ | /* Tell libcucul we changed size */ | ||||
if(dp->resize.w != dp->cv->width || dp->resize.h != dp->cv->height) | 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) | void _caca_set_term_title(char const *str) | ||||
@@ -34,6 +34,8 @@ | |||||
#include "cucul.h" | #include "cucul.h" | ||||
#include "cucul_internals.h" | #include "cucul_internals.h" | ||||
static int cucul_resize(cucul_canvas_t *, unsigned int, unsigned int); | |||||
/** \brief Initialise a \e libcucul canvas. | /** \brief Initialise a \e libcucul canvas. | ||||
* | * | ||||
* Initialise internal \e libcucul structures and the backend that will | * 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->refcount = 0; | ||||
cv->autoinc = 0; | cv->autoinc = 0; | ||||
cv->resize_callback = NULL; | |||||
cv->resize_data = NULL; | |||||
cv->frame = 0; | cv->frame = 0; | ||||
cv->framecount = 1; | 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_load_frame_info(cv); | ||||
cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_TRANSPARENT); | 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(); | int saved_errno = geterrno(); | ||||
free(cv->frames[0].name); | free(cv->frames[0].name); | ||||
@@ -98,6 +102,70 @@ nomem: | |||||
return NULL; | 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. | /** \brief Resize a canvas. | ||||
* | * | ||||
* Set the canvas' width and height, in character cells. | * 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 | * - \c ENOMEM Not enough memory for the requested canvas size. If this | ||||
* happens, the canvas handle becomes invalid and should not be used. | * 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. | * \return 0 in case of success, -1 if an error occurred. | ||||
*/ | */ | ||||
int cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | int cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | ||||
unsigned int height) | unsigned int height) | ||||
{ | { | ||||
if(cv->refcount) | |||||
if(cv->refcount && cv->resize_callback | |||||
&& !cv->resize_callback(cv->resize_data)) | |||||
{ | { | ||||
seterrno(EBUSY); | seterrno(EBUSY); | ||||
return -1; | return -1; | ||||
} | } | ||||
return __cucul_set_canvas_size(cv, width, height); | |||||
return cucul_resize(cv, width, height); | |||||
} | } | ||||
/** \brief Get the canvas width. | /** \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. | * This function never fails. | ||||
* | * | ||||
* \param cv A libcucul canvas | |||||
* \param cv A libcucul canvas. | |||||
* \return The canvas width. | * \return The canvas width. | ||||
*/ | */ | ||||
unsigned int cucul_get_canvas_width(cucul_canvas_t const *cv) | 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. | * This function never fails. | ||||
* | * | ||||
* \param cv A libcucul canvas | |||||
* \param cv A libcucul canvas. | |||||
* \return The canvas height. | * \return The canvas height. | ||||
*/ | */ | ||||
unsigned int cucul_get_canvas_height(cucul_canvas_t const *cv) | 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: | * 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. | * - \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. | * \return 0 in case of success, -1 if an error occurred. | ||||
*/ | */ | ||||
int cucul_free_canvas(cucul_canvas_t *cv) | 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. | * 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; | 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 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, | __extern int cucul_set_canvas_size(cucul_canvas_t *, unsigned int, | ||||
unsigned int); | unsigned int); | ||||
__extern unsigned int cucul_get_canvas_width(cucul_canvas_t const *); | __extern unsigned int cucul_get_canvas_width(cucul_canvas_t const *); | ||||
@@ -43,8 +43,11 @@ struct cucul_canvas | |||||
unsigned int frame, framecount; | unsigned int frame, framecount; | ||||
struct cucul_frame *frames; | struct cucul_frame *frames; | ||||
/* Canvas management */ | |||||
unsigned int refcount; | unsigned int refcount; | ||||
unsigned int autoinc; | unsigned int autoinc; | ||||
int (*resize_callback)(void *); | |||||
void *resize_data; | |||||
/* Shortcut to the active frame information */ | /* Shortcut to the active frame information */ | ||||
unsigned int width, height; | unsigned int width, height; | ||||
@@ -60,10 +63,6 @@ struct cucul_buffer | |||||
int user_data; | int user_data; | ||||
}; | }; | ||||
/* Canvas functions */ | |||||
extern int __cucul_set_canvas_size(cucul_canvas_t *, | |||||
unsigned int, unsigned int); | |||||
/* Colour functions */ | /* Colour functions */ | ||||
extern uint16_t _cucul_attr_to_rgb12fg(uint32_t); | extern uint16_t _cucul_attr_to_rgb12fg(uint32_t); | ||||
extern uint16_t _cucul_attr_to_rgb12bg(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 |