Ignore:
Timestamp:
Mar 5, 2006, 7:43:13 PM (15 years ago)
Author:
Sam Hocevar
Message:

A new low-level text management library (canvas for ultrafast compositing

of unicode letters) is now separated from the higher level rendering and I/O
(that is, libcaca). This commit totally breaks the API, but once everything
is polished I will think about source-level backward compatibility. Most
drivers are broken, but X11 still sorta works.

The new design is much more object-oriented and allows having several

active renderers at the same time, changing renderers on the fly, and more
important, having no renderer at all (useful for converters, or when you
want to do your own renderer).

And in case you are still wondering, the libcucul acronym has "Unicode"

because I want to support at least a subset of Unicode. There are awesome
glyphs in it, including the ones inherited from Codepage 437 such as
"gray 25%" that are used in DOS and Win32 ANSI art.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/src/caca.c

    r522 r524  
    2222#include "config.h"
    2323
     24#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
     25#   include <inttypes.h>
     26#else
     27typedef unsigned char uint8_t;
     28#endif
     29
    2430#if defined(USE_SLANG)
    2531#   if defined(HAVE_SLANG_SLANG_H)
     
    5258#include <string.h>
    5359
     60#include "cucul.h"
     61#include "cucul_internals.h"
    5462#include "caca.h"
    5563#include "caca_internals.h"
    5664
    57 static void caca_init_driver(void);
    58 static void caca_init_features(void);
    59 static void caca_init_terminal(void);
    60 
    61 #if !defined(_DOXYGEN_SKIP_ME)
    62 enum caca_driver _caca_driver;
    63 #endif
     65static void caca_init_driver(caca_t *kk);
     66static void caca_init_terminal(caca_t *kk);
    6467
    6568#if defined(USE_NCURSES)
     
    7174#endif
    7275
    73 /** \brief Initialise \e libcaca.
    74  *
    75  *  This function initialises internal \e libcaca structures and the backend
    76  *  that will be used for subsequent graphical operations. It must be the
    77  *  first \e libcaca function to be called in a function. caca_end() should
    78  *  be called at the end of the program to free all allocated resources.
    79  *
    80  *  \return 0 upon success, a non-zero value if an error occurs.
    81  */
    82 int caca_init(void)
     76caca_t * caca_attach(cucul_t * qq)
    8377{
     78    caca_t *kk = malloc(sizeof(caca_t));
     79
    8480#if defined(USE_NCURSES)
    8581    mmask_t newmask;
    8682#endif
    8783
    88     caca_init_driver();
    89 
    90     if(_caca_driver == CACA_DRIVER_NONE)
    91         return -1;
    92 
    93     caca_init_features();
    94     caca_init_terminal();
    95 
    96 #if defined(USE_SLANG)
    97     if(_caca_driver == CACA_DRIVER_SLANG)
     84    caca_init_driver(kk);
     85
     86    if(kk->driver == CACA_DRIVER_NONE)
     87        return NULL;
     88
     89    caca_init_terminal(kk);
     90
     91#if defined(USE_SLANG)
     92    if(kk->driver == CACA_DRIVER_SLANG)
    9893    {
    9994        /* Initialise slang library */
     
    10499        {
    105100            SLsig_unblock_signals();
    106             return -1;
     101            return NULL;
    107102        }
    108103
     
    112107        {
    113108            SLsig_unblock_signals();
    114             return -1;
     109            return NULL;
    115110        }
    116111
     
    130125#endif
    131126#if defined(USE_NCURSES)
    132     if(_caca_driver == CACA_DRIVER_NCURSES)
     127    if(kk->driver == CACA_DRIVER_NCURSES)
    133128    {
    134129        initscr();
     
    151146#endif
    152147#if defined(USE_CONIO)
    153     if(_caca_driver == CACA_DRIVER_CONIO)
     148    if(kk->driver == CACA_DRIVER_CONIO)
    154149    {
    155150        _wscroll = 0;
     
    160155#endif
    161156#if defined(USE_X11)
    162     if(_caca_driver == CACA_DRIVER_X11)
     157    if(kk->driver == CACA_DRIVER_X11)
    163158    {
    164159        /* Nothing to do */
    165     }
    166     else
    167 #endif
    168 #if defined(USE_WIN32)
    169     if(_caca_driver == CACA_DRIVER_WIN32)
     160        kk->x11.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
     161              | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask
     162              | ExposureMask;
     163    }
     164    else
     165#endif
     166#if defined(USE_WIN32)
     167    if(kk->driver == CACA_DRIVER_WIN32)
    170168    {
    171169        /* This call is allowed to fail in cas we already have a console */
     
    178176
    179177        if(win32_hout == INVALID_HANDLE_VALUE)
    180             return -1;
     178            return NULL;
    181179
    182180        GetConsoleCursorInfo(win32_hout, &cci);
     
    189187#endif
    190188#if defined(USE_GL)
    191     if(_caca_driver == CACA_DRIVER_GL)
     189    if(kk->driver == CACA_DRIVER_GL)
    192190    {
    193191        /* Nothing to do */
     
    195193    else
    196194#endif
    197 #if defined(USE_NULL)
    198     if(_caca_driver == CACA_DRIVER_NULL)
    199     {
    200         /* Nothing to do */
    201     }
    202     else
    203 #endif
    204195    {
    205196        /* Dummy */
    206197    }
    207198
    208     if(_caca_init_graphics())
    209         return -1;
    210 
    211     if(_caca_init_bitmap())
    212         return -1;
    213 
    214     return 0;
     199    qq->refcount++;
     200    kk->qq = qq;
     201
     202    kk->resize = 0;
     203    kk->resize_event = 0;
     204
     205    if(_caca_init_graphics(kk))
     206        return NULL;
     207
     208    return kk;
    215209}
    216210
    217 /** \brief Get the screen width.
    218  *
    219  *  This function returns the current screen width, in character cells.
    220  *
    221  *  \return The screen width.
    222  */
    223 unsigned int caca_get_width(void)
     211void caca_detach(caca_t *kk)
    224212{
    225     return _caca_width;
    226 }
    227 
    228 /** \brief Get the screen height.
    229  *
    230  *  This function returns the current screen height, in character cells.
    231  *
    232  *  \return The screen height.
    233  */
    234 unsigned int caca_get_height(void)
    235 {
    236     return _caca_height;
    237 }
    238 
    239 /** \brief Translate a colour index into the colour's name.
    240  *
    241  *  This function translates a caca_color enum into a human-readable
    242  *  description string of the associated colour.
    243  *
    244  *  \param color The colour value.
    245  *  \return A static string containing the colour's name.
    246  */
    247 char const *caca_get_color_name(enum caca_color color)
    248 {
    249     static char const *color_names[] =
    250     {
    251         "black",
    252         "blue",
    253         "green",
    254         "cyan",
    255         "red",
    256         "magenta",
    257         "brown",
    258         "light gray",
    259         "dark gray",
    260         "light blue",
    261         "light green",
    262         "light cyan",
    263         "light red",
    264         "light magenta",
    265         "yellow",
    266         "white",
    267     };
    268 
    269     if(color < 0 || color > 15)
    270         return "unknown";
    271 
    272     return color_names[color];
    273 }
    274 
    275 /** \brief Get the current value of a feature.
    276  *
    277  *  This function retrieves the value of an internal \e libcaca feature. A
    278  *  generic feature value is expected, such as CACA_ANTIALIASING.
    279  *
    280  *  \param feature The requested feature.
    281  *  \return The current value of the feature or CACA_FEATURE_UNKNOWN if an
    282  *          error occurred..
    283  */
    284 enum caca_feature caca_get_feature(enum caca_feature feature)
    285 {
    286     switch(feature)
    287     {
    288         case CACA_BACKGROUND:
    289             return _caca_background;
    290         case CACA_ANTIALIASING:
    291             return _caca_antialiasing;
    292         case CACA_DITHERING:
    293             return _caca_dithering;
    294 
    295         default:
    296             return CACA_FEATURE_UNKNOWN;
    297     }
    298 }
    299 
    300 /** \brief Set a feature.
    301  *
    302  *  This function sets an internal \e libcaca feature such as the antialiasing
    303  *  or dithering modes. If a specific feature such as CACA_DITHERING_RANDOM,
    304  *  caca_set_feature() will set it immediately. If a generic feature is given
    305  *  instead, such as CACA_DITHERING, the default value will be used instead.
    306  *
    307  *  \param feature The requested feature.
    308  */
    309 void caca_set_feature(enum caca_feature feature)
    310 {
    311     switch(feature)
    312     {
    313         case CACA_BACKGROUND:
    314             feature = CACA_BACKGROUND_SOLID;
    315         case CACA_BACKGROUND_BLACK:
    316         case CACA_BACKGROUND_SOLID:
    317             _caca_background = feature;
    318             break;
    319 
    320         case CACA_ANTIALIASING:
    321             feature = CACA_ANTIALIASING_PREFILTER;
    322         case CACA_ANTIALIASING_NONE:
    323         case CACA_ANTIALIASING_PREFILTER:
    324             _caca_antialiasing = feature;
    325             break;
    326 
    327         case CACA_DITHERING:
    328             feature = CACA_DITHERING_FSTEIN;
    329         case CACA_DITHERING_NONE:
    330         case CACA_DITHERING_ORDERED2:
    331         case CACA_DITHERING_ORDERED4:
    332         case CACA_DITHERING_ORDERED8:
    333         case CACA_DITHERING_RANDOM:
    334         case CACA_DITHERING_FSTEIN:
    335             _caca_dithering = feature;
    336             break;
    337 
    338         case CACA_FEATURE_UNKNOWN:
    339             break;
    340     }
    341 }
    342 
    343 /** \brief Translate a feature value into the feature's name.
    344  *
    345  *  This function translates a caca_feature enum into a human-readable
    346  *  description string of the associated feature.
    347  *
    348  *  \param feature The feature value.
    349  *  \return A static string containing the feature's name.
    350  */
    351 char const *caca_get_feature_name(enum caca_feature feature)
    352 {
    353     switch(feature)
    354     {
    355         case CACA_BACKGROUND_BLACK: return "black background";
    356         case CACA_BACKGROUND_SOLID: return "solid background";
    357 
    358         case CACA_ANTIALIASING_NONE:      return "no antialiasing";
    359         case CACA_ANTIALIASING_PREFILTER: return "prefilter antialiasing";
    360 
    361         case CACA_DITHERING_NONE:     return "no dithering";
    362         case CACA_DITHERING_ORDERED2: return "2x2 ordered dithering";
    363         case CACA_DITHERING_ORDERED4: return "4x4 ordered dithering";
    364         case CACA_DITHERING_ORDERED8: return "8x8 ordered dithering";
    365         case CACA_DITHERING_RANDOM:   return "random dithering";
    366         case CACA_DITHERING_FSTEIN:   return "Floyd-Steinberg dithering";
    367 
    368         default: return "unknown";
    369     }
    370 }
    371 
    372 /** \brief Uninitialise \e libcaca.
    373  *
    374  *  This function frees all resources allocated by caca_init(). After
    375  *  caca_end() has been called, no other \e libcaca functions may be used
    376  *  unless a new call to caca_init() is done.
    377  */
    378 void caca_end(void)
    379 {
    380     _caca_end_bitmap();
    381     _caca_end_graphics();
    382 
    383 #if defined(USE_SLANG)
    384     if(_caca_driver == CACA_DRIVER_SLANG)
     213    _caca_end_graphics(kk);
     214
     215#if defined(USE_SLANG)
     216    if(kk->driver == CACA_DRIVER_SLANG)
    385217    {
    386218        SLtt_set_mouse_mode(0, 0);
     
    392224#endif
    393225#if defined(USE_NCURSES)
    394     if(_caca_driver == CACA_DRIVER_NCURSES)
     226    if(kk->driver == CACA_DRIVER_NCURSES)
    395227    {
    396228        mousemask(oldmask, NULL);
     
    402234#endif
    403235#if defined(USE_CONIO)
    404     if(_caca_driver == CACA_DRIVER_CONIO)
     236    if(kk->driver == CACA_DRIVER_CONIO)
    405237    {
    406238        _wscroll = 1;
     
    414246#endif
    415247#if defined(USE_X11)
    416     if(_caca_driver == CACA_DRIVER_X11)
     248    if(kk->driver == CACA_DRIVER_X11)
    417249    {
    418250        /* Nothing to do */
     
    421253#endif
    422254#if defined(USE_WIN32)
    423     if(_caca_driver == CACA_DRIVER_WIN32)
     255    if(kk->driver == CACA_DRIVER_WIN32)
    424256    {
    425257        SetConsoleTextAttribute(win32_hout, FOREGROUND_INTENSITY
     
    434266#endif
    435267#if defined(USE_GL)
    436     if(_caca_driver == CACA_DRIVER_GL)
     268    if(kk->driver == CACA_DRIVER_GL)
    437269    {
    438270        /* Nothing to do */
     
    440272    else
    441273#endif
    442 #if defined(USE_NULL)
    443     if(_caca_driver == CACA_DRIVER_NULL)
    444     {
    445         /* Nothing to do */
    446     }
    447     else
    448 #endif
    449274    {
    450275        /* Dummy */
    451276    }
     277
     278    kk->qq->refcount--;
     279
     280    free(kk);
    452281}
    453282
     
    456285 */
    457286
    458 static void caca_init_driver(void)
     287static void caca_init_driver(caca_t *kk)
    459288{
    460289#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
     
    466295#if defined(USE_WIN32)
    467296        if(!strcasecmp(var, "win32"))
    468             _caca_driver = CACA_DRIVER_WIN32;
     297            kk->driver = CACA_DRIVER_WIN32;
    469298        else
    470299#endif
    471300#if defined(USE_CONIO)
    472301        if(!strcasecmp(var, "conio"))
    473             _caca_driver = CACA_DRIVER_CONIO;
     302            kk->driver = CACA_DRIVER_CONIO;
    474303        else
    475304#endif
    476305#if defined(USE_X11)
    477306        if(!strcasecmp(var, "x11"))
    478             _caca_driver = CACA_DRIVER_X11;
     307            kk->driver = CACA_DRIVER_X11;
    479308        else
    480309#endif
    481310#if defined(USE_GL)
    482311        if(!strcasecmp(var, "gl"))
    483             _caca_driver = CACA_DRIVER_GL;
     312            kk->driver = CACA_DRIVER_GL;
    484313        else
    485314#endif
    486315#if defined(USE_SLANG)
    487316        if(!strcasecmp(var, "slang"))
    488             _caca_driver = CACA_DRIVER_SLANG;
     317            kk->driver = CACA_DRIVER_SLANG;
    489318        else
    490319#endif
    491320#if defined(USE_NCURSES)
    492321        if(!strcasecmp(var, "ncurses"))
    493             _caca_driver = CACA_DRIVER_NCURSES;
    494         else
    495 #endif
    496 #if defined(USE_NULL)
    497         if(!strcasecmp(var, "null"))
    498             _caca_driver = CACA_DRIVER_NULL;
    499         else
    500 #endif
    501 
    502             _caca_driver = CACA_DRIVER_NONE;
     322            kk->driver = CACA_DRIVER_NCURSES;
     323        else
     324#endif
     325
     326            kk->driver = CACA_DRIVER_NONE;
    503327
    504328        return;
     
    507331
    508332#if defined(USE_WIN32)
    509     _caca_driver = CACA_DRIVER_WIN32;
     333    kk->driver = CACA_DRIVER_WIN32;
    510334    return;
    511335#endif
    512336#if defined(USE_CONIO)
    513     _caca_driver = CACA_DRIVER_CONIO;
     337    kk->driver = CACA_DRIVER_CONIO;
    514338    return;
    515339#endif
     
    519343#endif
    520344    {
    521         _caca_driver = CACA_DRIVER_X11;
     345        kk->driver = CACA_DRIVER_X11;
    522346        return;
    523347    }
     
    528352#endif
    529353    {
    530         _caca_driver = CACA_DRIVER_GL;
     354        kk->driver = CACA_DRIVER_GL;
    531355        return;
    532356    }
    533357#endif
    534358#if defined(USE_SLANG)
    535     _caca_driver = CACA_DRIVER_SLANG;
    536     return;
    537 #endif
    538 #if defined(USE_NCURSES)
    539     _caca_driver = CACA_DRIVER_NCURSES;
    540     return;
    541 #endif
    542 #if defined(USE_NULL)
    543     _caca_driver = CACA_DRIVER_NULL;
    544     return;
    545 #endif
    546 
    547     _caca_driver = CACA_DRIVER_NONE;
     359    kk->driver = CACA_DRIVER_SLANG;
     360    return;
     361#endif
     362#if defined(USE_NCURSES)
     363    kk->driver = CACA_DRIVER_NCURSES;
     364    return;
     365#endif
     366
     367    kk->driver = CACA_DRIVER_NONE;
    548368    return;
    549369}
    550370
    551 static void caca_init_features(void)
    552 {
    553     /* FIXME: if strcasecmp isn't available, use strcmp */
    554 #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
    555     char *var;
    556 #endif
    557 
    558     caca_set_feature(CACA_BACKGROUND);
    559     caca_set_feature(CACA_ANTIALIASING);
    560     caca_set_feature(CACA_DITHERING);
    561 
    562 #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
    563     if((var = getenv("CACA_BACKGROUND")) && *var)
    564     {
    565         if(!strcasecmp("black", var))
    566             caca_set_feature(CACA_BACKGROUND_BLACK);
    567         else if(!strcasecmp("solid", var))
    568             caca_set_feature(CACA_BACKGROUND_SOLID);
    569     }
    570 
    571     if((var = getenv("CACA_ANTIALIASING")) && *var)
    572     {
    573         if(!strcasecmp("none", var))
    574             caca_set_feature(CACA_ANTIALIASING_NONE);
    575         else if(!strcasecmp("prefilter", var))
    576             caca_set_feature(CACA_ANTIALIASING_PREFILTER);
    577     }
    578 
    579     if((var = getenv("CACA_DITHERING")) && *var)
    580     {
    581         if(!strcasecmp("none", var))
    582             caca_set_feature(CACA_DITHERING_NONE);
    583         else if(!strcasecmp("ordered2", var))
    584             caca_set_feature(CACA_DITHERING_ORDERED2);
    585         else if(!strcasecmp("ordered4", var))
    586             caca_set_feature(CACA_DITHERING_ORDERED4);
    587         else if(!strcasecmp("ordered8", var))
    588             caca_set_feature(CACA_DITHERING_ORDERED8);
    589         else if(!strcasecmp("random", var))
    590             caca_set_feature(CACA_DITHERING_RANDOM);
    591         else if(!strcasecmp("fstein", var))
    592             caca_set_feature(CACA_DITHERING_FSTEIN);
    593     }
    594 #endif
    595 }
    596 
    597 static void caca_init_terminal(void)
     371static void caca_init_terminal(caca_t *kk)
    598372{
    599373#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) && \
     
    603377
    604378#if defined(USE_SLANG)
    605     if(_caca_driver != CACA_DRIVER_SLANG)
    606 #endif
    607 #if defined(USE_NCURSES)
    608     if(_caca_driver != CACA_DRIVER_NCURSES)
     379    if(kk->driver != CACA_DRIVER_SLANG)
     380#endif
     381#if defined(USE_NCURSES)
     382    if(kk->driver != CACA_DRIVER_NCURSES)
    609383#endif
    610384    return;
     
    621395        {
    622396#if defined(USE_NCURSES)
    623             if(_caca_driver == CACA_DRIVER_NCURSES)
     397            if(kk->driver == CACA_DRIVER_NCURSES)
    624398            {
    625399                SCREEN *screen;
     
    639413        {
    640414#if defined(USE_NCURSES)
    641             if(_caca_driver == CACA_DRIVER_NCURSES)
     415            if(kk->driver == CACA_DRIVER_NCURSES)
    642416            {
    643417                SCREEN *screen;
Note: See TracChangeset for help on using the changeset viewer.