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 | |||