Changeset 2139 for libcaca/trunk


Ignore:
Timestamp:
Dec 16, 2007, 12:54:02 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Implemented caca_set_display_driver() to change driver at runtime.
Location:
libcaca/trunk
Files:
3 edited

Legend:

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

    r2138 r2139  
    4343
    4444static int caca_can_resize(caca_display_t *);
     45static int caca_install_driver(caca_display_t *, char const *);
     46static int caca_uninstall_driver(caca_display_t *);
    4547static int caca_select_driver(caca_display_t *, char const *);
    4648#if defined(USE_PLUGINS)
     
    7375}
    7476
    75 /** \brief Attach a caca graphical context to a cucul canvas.
     77/** \brief Attach a specific caca graphical context to a cucul canvas.
    7678 *
    7779 *  Create a graphical context using device-dependent features (ncurses for
     
    8385 *  retrieved using caca_get_canvas() and it is automatically destroyed when
    8486 *  caca_free_display() is called.
     87 *
     88 *  If no driver name is provided, \e libcaca will try to autodetect the best
     89 *  output driver it can.
    8590 *
    8691 *  See also caca_create_display().
     
    122127    }
    123128
    124 #if defined(USE_PLUGINS)
    125     dp->plugin = NULL;
    126 #endif
    127 
    128     if(caca_select_driver(dp, driver))
    129     {
    130 #if defined(USE_PLUGINS)
    131         if(dp->plugin)
    132             dlclose(dp->plugin);
    133 #endif
     129    if(caca_install_driver(dp, driver))
     130    {
    134131        cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp);
    135132        if(dp->autorelease)
     
    140137    }
    141138
    142     if(dp->drv.init_graphics(dp))
     139    return dp;
     140}
     141
     142/** \brief Get available display drivers
     143 *
     144 *  Return a list of available display drivers. The list is a NULL-terminated
     145 *  array of strings, interleaving a string containing the internal value for
     146 *  the display driver, and a string containing the natural language
     147 *  description for that driver.
     148 *
     149 *  This function never fails.
     150 *
     151 *  \param dp Display object.
     152 *  \return An array of strings.
     153 */
     154char const * const * caca_get_display_driver_list(void)
     155{
     156    static char const * const list[] =
     157    {
     158#if defined(USE_COCOA)
     159        "cocoa", "Mac OS X Cocoa",
     160#endif
     161#if defined(USE_WIN32)
     162        "win32", "Windows console",
     163#endif
     164#if defined(USE_CONIO)
     165        "conio", "MS-DOS conio",
     166#endif
     167#if defined(USE_X11)
     168        "x11", "X11 graphical window",
     169#endif
     170#if defined(USE_GL)
     171        "gl", "OpenGL window",
     172#endif
     173#if defined(USE_SLANG)
     174        "slang", "S-Lang console library",
     175#endif
     176#if defined(USE_NCURSES)
     177        "ncurses", "ncurses console library",
     178#endif
     179#if defined(USE_VGA)
     180        "vga", "direct VGA memory",
     181#endif
     182#if !defined(__KERNEL__)
     183        "raw", "raw libcaca output",
     184#endif
     185        NULL, NULL
     186    };
     187
     188    return list;
     189}
     190
     191/** \brief Return a caca graphical context's current output driver.
     192 *
     193 *  Return the given display's current output driver.
     194 *
     195 *  This function never fails.
     196 *
     197 *  \param dp The caca display.
     198 *  \return A static string.
     199 */
     200char const * caca_get_display_driver(caca_display_t *dp)
     201{
     202    return dp->drv.driver;
     203}
     204
     205/** \brief Set the output driver.
     206 *
     207 *  Dynamically change the given display's output driver.
     208 *
     209 *  FIXME: decide what to do in case of failure
     210 *
     211 *  \param dp The caca display.
     212 *  \param driver A string describing the desired output driver or NULL to
     213 *                choose the best driver automatically.
     214 *  \return 0 in case of success, -1 if an error occurred.
     215 */
     216int caca_set_display_driver(caca_display_t *dp, char const *driver)
     217{
     218    caca_uninstall_driver(dp);
     219    if(caca_install_driver(dp, driver))
     220    {
     221        seterrno(ENODEV);
     222        return -1;
     223    }
     224
     225    return 0;
     226}
     227
     228/** \brief Detach a caca graphical context from a cucul backend context.
     229 *
     230 *  Detach a graphical context from its cucul backend and destroy it. The
     231 *  libcucul canvas continues to exist and other graphical contexts can be
     232 *  attached to it afterwards.
     233 *
     234 *  If the cucul canvas was automatically created by caca_create_display(),
     235 *  it is automatically destroyed and any handle to it becomes invalid.
     236 *
     237 *  This function never fails.
     238 *
     239 *  \param dp The libcaca graphical context.
     240 *  \return This function always returns 0.
     241 */
     242int caca_free_display(caca_display_t *dp)
     243{
     244    caca_uninstall_driver(dp);
     245    cucul_unmanage_canvas(dp->cv, (int (*)(void *))caca_can_resize, (void *)dp);
     246    if(dp->autorelease)
     247        cucul_free_canvas(dp->cv);
     248    free(dp);
     249
     250    return 0;
     251}
     252
     253/** \brief Get the canvas attached to a caca graphical context.
     254 *
     255 *  Return a handle on the \e cucul_canvas_t object that was either attached
     256 *  or created by caca_create_display().
     257 *
     258 *  This function never fails.
     259 *
     260 *  \param dp The libcaca graphical context.
     261 *  \return The libcucul canvas.
     262 */
     263cucul_canvas_t * caca_get_canvas(caca_display_t *dp)
     264{
     265    return dp->cv;
     266}
     267
     268/** \brief Return the \e libcaca version.
     269 *
     270 *  Return a read-only string with the \e libcaca version information.
     271 *
     272 *  This function never fails.
     273 *
     274 *  \return The \e libcaca version information.
     275 */
     276char const * caca_get_version(void)
     277{
     278    return VERSION;
     279}
     280
     281/*
     282 * XXX: The following functions are local.
     283 */
     284
     285static int caca_can_resize(caca_display_t *dp)
     286{
     287    return dp->resize.allow;
     288}
     289
     290static int caca_install_driver(caca_display_t *dp, char const *driver)
     291{
     292#if defined(USE_PLUGINS)
     293    dp->plugin = NULL;
     294#endif
     295
     296    if(caca_select_driver(dp, driver))
    143297    {
    144298#if defined(USE_PLUGINS)
     
    146300            dlclose(dp->plugin);
    147301#endif
    148         cucul_unmanage_canvas(cv, (int (*)(void *))caca_can_resize, (void *)dp);
    149         if(dp->autorelease)
    150             cucul_free_canvas(dp->cv);
    151         free(dp);
    152         seterrno(ENODEV);
    153         return NULL;
     302        return -1;
     303    }
     304
     305    if(dp->drv.init_graphics(dp))
     306    {
     307#if defined(USE_PLUGINS)
     308        if(dp->plugin)
     309            dlclose(dp->plugin);
     310#endif
     311        return -1;
    154312    }
    155313
     
    182340    dp->resize.allow = 0;
    183341
    184     return dp;
    185 }
    186 
    187 /** \brief Return the current output driver
    188  *
    189  *  Return the given display's current output driver.
    190  *
    191  *  This function never fails.
    192  *
    193  *  \param dp The caca display.
    194  *  \return A static string.
    195  */
    196 char const * caca_get_display_driver(caca_display_t *dp)
    197 {
    198     return dp->drv.driver;
    199 }
    200 
    201 /** \brief Detach a caca graphical context from a cucul backend context.
    202  *
    203  *  Detach a graphical context from its cucul backend and destroy it. The
    204  *  libcucul canvas continues to exist and other graphical contexts can be
    205  *  attached to it afterwards.
    206  *
    207  *  If the cucul canvas was automatically created by caca_create_display(),
    208  *  it is automatically destroyed and any handle to it becomes invalid.
    209  *
    210  *  This function never fails.
    211  *
    212  *  \param dp The libcaca graphical context.
    213  *  \return This function always returns 0.
    214  */
    215 int caca_free_display(caca_display_t *dp)
     342    return 0;
     343}
     344
     345static int caca_uninstall_driver(caca_display_t *dp)
    216346{
    217347    dp->drv.end_graphics(dp);
     
    220350        dlclose(dp->plugin);
    221351#endif
    222     cucul_unmanage_canvas(dp->cv, (int (*)(void *))caca_can_resize, (void *)dp);
    223     if(dp->autorelease)
    224         cucul_free_canvas(dp->cv);
    225     free(dp);
    226352
    227353    return 0;
    228 }
    229 
    230 /** \brief Get the canvas attached to a caca graphical context.
    231  *
    232  *  Return a handle on the \e cucul_canvas_t object that was either attached
    233  *  or created by caca_create_display().
    234  *
    235  *  This function never fails.
    236  *
    237  *  \param dp The libcaca graphical context.
    238  *  \return The libcucul canvas.
    239  */
    240 cucul_canvas_t * caca_get_canvas(caca_display_t *dp)
    241 {
    242     return dp->cv;
    243 }
    244 
    245 /** \brief Return the \e libcaca version.
    246  *
    247  *  Return a read-only string with the \e libcaca version information.
    248  *
    249  *  This function never fails.
    250  *
    251  *  \return The \e libcaca version information.
    252  */
    253 char const * caca_get_version(void)
    254 {
    255     return VERSION;
    256 }
    257 
    258 /** \brief Get available display drivers
    259  *
    260  *  Return a list of available display drivers. The list is a NULL-terminated
    261  *  array of strings, interleaving a string containing the internal value for
    262  *  the display driver, and a string containing the natural language
    263  *  description for that driver.
    264  *
    265  *  This function never fails.
    266  *
    267  *  \param dp Display object.
    268  *  \return An array of strings.
    269  */
    270 char const * const * caca_get_display_driver_list(void)
    271 {
    272     static char const * const list[] =
    273     {
    274 #if defined(USE_COCOA)
    275         "cocoa", "Mac OS X Cocoa",
    276 #endif
    277 #if defined(USE_WIN32)
    278         "win32", "Windows console",
    279 #endif
    280 #if defined(USE_CONIO)
    281         "conio", "MS-DOS conio",
    282 #endif
    283 #if defined(USE_X11)
    284         "x11", "X11 graphical window",
    285 #endif
    286 #if defined(USE_GL)
    287         "gl", "OpenGL window",
    288 #endif
    289 #if !defined(__KERNEL__)
    290         "raw", "raw libcaca output",
    291 #endif
    292 #if defined(USE_SLANG)
    293         "slang", "S-Lang console library",
    294 #endif
    295 #if defined(USE_NCURSES)
    296         "ncurses", "ncurses console library",
    297 #endif
    298 #if defined(USE_VGA)
    299         "vga", "direct VGA memory",
    300 #endif
    301         NULL, NULL
    302     };
    303 
    304     return list;
    305 }
    306 
    307 /*
    308  * XXX: The following functions are local.
    309  */
    310 
    311 static int caca_can_resize(caca_display_t *dp)
    312 {
    313     return dp->resize.allow;
    314354}
    315355
  • libcaca/trunk/caca/caca.h

    r2138 r2139  
    157157__extern caca_display_t * caca_create_display_with_driver(cucul_canvas_t *,
    158158                                                          char const *);
     159__extern char const * const * caca_get_display_driver_list(void);
    159160__extern char const * caca_get_display_driver(caca_display_t *);
     161__extern int caca_set_display_driver(caca_display_t *, char const *);
    160162__extern int caca_free_display(caca_display_t *);
    161163__extern cucul_canvas_t * caca_get_canvas(caca_display_t *);
    162164__extern int caca_refresh_display(caca_display_t *);
    163 __extern char const * const * caca_get_display_driver_list(void);
    164165__extern int caca_set_display_time(caca_display_t *, unsigned int);
    165166__extern unsigned int caca_get_display_time(caca_display_t const *);
  • libcaca/trunk/examples/driver.c

    r2138 r2139  
    1717
    1818#if !defined(__KERNEL__)
     19#   include <string.h>
    1920#   include <stdio.h>
    2021#endif
     
    2526int main(int argc, char *argv[])
    2627{
    27     char const * const * list;
     28    char const * const *list;
    2829    caca_display_t *dp;
    2930    cucul_canvas_t *cv;
    3031
    3132    list = caca_get_display_driver_list();
    32     if(argc <= 1)
    33     {
    34         printf("Available drivers:\n");
    3533
    36         while(*list)
    37         {
    38             printf("  %s (%s)\n", list[0], list[1]);
    39             list += 2;
    40         }
    41 
    42         return 0;
    43     }
    44 
    45     cv = cucul_create_canvas(0, 0);
    46     if(cv == NULL)
    47     {
    48         printf("cannot create canvas\n");
    49         return -1;
    50     }
    51     dp = caca_create_display_with_driver(cv, argv[1]);
     34    dp = caca_create_display(NULL);
    5235    if(dp == NULL)
    5336    {
     
    5639    }
    5740
    58     cucul_set_color_ansi(cv, CUCUL_WHITE, CUCUL_BLUE);
    59     cucul_draw_line(cv, 0, 0, 9999, 0, ' ');
    60     cucul_printf(cv, 1, 0, "Current driver: %s", argv[1]);
     41    cv = caca_get_canvas(dp);
     42    cucul_set_color_ansi(cv, CUCUL_WHITE, CUCUL_BLACK);
    6143
    62     caca_refresh_display(dp);
     44    while(1)
     45    {
     46        char const *driver;
     47        int i, cur = 0;
    6348
    64     caca_get_event(dp, CACA_EVENT_KEY_PRESS, NULL, -1);
     49        cucul_put_str(cv, 1, 0, "Available drivers:");
     50
     51        driver = caca_get_display_driver(dp);
     52
     53        for(i = 0; list[i]; i += 2)
     54        {
     55            int match = !strcmp(list[i], driver);
     56
     57            if(match)
     58                cur = i;
     59            cucul_draw_line(cv, 0, i + 2, 9999, i + 2, ' ');
     60            cucul_printf(cv, 2, i + 2, "%c %s (%s)",
     61                         match ? '*' : ' ', list[i], list[i + 1]);
     62        }
     63
     64        cucul_put_str(cv, 1, i + 2, "Switching driver in 5 seconds");
     65
     66        caca_refresh_display(dp);
     67
     68        if(caca_get_event(dp, CACA_EVENT_KEY_PRESS, NULL, 5000000))
     69            break;
     70
     71        do
     72        {
     73            cur += 2;
     74            if(list[cur] && !strcmp(list[cur], "raw"))
     75                cur += 2;
     76            if(!list[cur])
     77                cur = 0;
     78        }
     79        while(caca_set_display_driver(dp, list[cur]));
     80    }
    6581
    6682    caca_free_display(dp);
    67     cucul_free_canvas(cv);
    6883
    6984    return 0;
Note: See TracChangeset for help on using the changeset viewer.