Ignore:
Timestamp:
Mar 7, 2006, 12:01:59 AM (14 years ago)
Author:
Sam Hocevar
Message:
  • Split caca/graphics.c into driver-specific files. Resize is currently broken, and event handling is not yet in the driver-specific files, but I will of course fix that later.
File:
1 edited

Legend:

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

    r536 r539  
    2020#include "config.h"
    2121
    22 #if defined(USE_SLANG)
    23 #   if defined(HAVE_SLANG_SLANG_H)
    24 #       include <slang/slang.h>
    25 #   else
    26 #       include <slang.h>
    27 #   endif
    28 #endif
    29 #if defined(USE_NCURSES)
    30 #   if defined(HAVE_NCURSES_H)
    31 #       include <ncurses.h>
    32 #   else
    33 #       include <curses.h>
    34 #   endif
    35 #endif
    36 #if defined(USE_CONIO)
    37 #   include <conio.h>
    38 #   if defined(SCREENUPDATE_IN_PC_H)
    39 #       include <pc.h>
    40 #   endif
    41 #endif
    42 #if defined(USE_X11)
    43 #   include <X11/Xlib.h>
    44 #   if defined(HAVE_X11_XKBLIB_H)
    45 #       include <X11/XKBlib.h>
    46 #   endif
    47 #endif
    48 #if defined(USE_WIN32)
    49 #   include <windows.h>
    50 #endif
    51 #if defined(USE_GL)
    52 #   include <GL/gl.h>
    53 #   include <GL/glut.h>
    54 #   include <GL/freeglut_ext.h>
    55 #endif
    5622#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
    5723#   include <inttypes.h>
     
    6935#include <stdarg.h>
    7036
    71 #if defined(HAVE_SIGNAL_H)
    72 #   include <signal.h>
    73 #endif
    74 #if defined(HAVE_SYS_IOCTL_H)
    75 #   include <sys/ioctl.h>
    76 #endif
    77 
    7837#include "caca.h"
    7938#include "caca_internals.h"
     
    8241
    8342/*
    84  * Global variables
    85  */
    86 
    87 #if defined(USE_SLANG)
    88 /* Tables generated by test/optipal.c */
    89 static int const slang_palette[2*16*16] =
    90 {
    91      1,  0,   2,  0,   3,  0,   4,  0,   5,  0,   6,  0,   7,  0,   8,  0,
    92      9,  0,  10,  0,  11,  0,  12,  0,  13,  0,  14,  0,  15,  0,   0,  8,
    93      8,  7,   7,  8,  15,  7,   7, 15,  15,  9,   9, 15,   1,  9,   9,  1,
    94      7,  9,   9,  7,   8,  1,   1,  8,   0,  1,  15, 10,  10, 15,   2, 10,
    95     10,  2,   7, 10,  10,  7,   8,  2,   2,  8,   0,  2,  15, 11,  11, 15,
    96      3, 11,  11,  3,   7, 11,  11,  7,   8,  3,   3,  8,   0,  3,  15, 12,
    97     12, 15,   4, 12,  12,  4,   7, 12,  12,  7,   8,  4,   4,  8,   0,  4,
    98     15, 13,  13, 15,   5, 13,  13,  5,   7, 13,  13,  7,   8,  5,   5,  8,
    99      0,  5,  15, 14,  14, 15,   6, 14,  14,  6,   7, 14,  14,  7,   8,  6,
    100      6,  8,   0,  6,   4,  6,   6,  4,  12, 14,  14, 12,   6,  2,   2,  6,
    101     14, 10,  10, 14,   2,  3,   3,  2,  10, 11,  11, 10,   3,  1,   1,  3,
    102     11,  9,   9, 11,   1,  5,   5,  1,   9, 13,  13,  9,   5,  4,   4,  5,
    103     13, 12,  12, 13,   4, 14,   6, 12,  12,  6,  14,  4,   6, 10,   2, 14,
    104     14,  2,  10,  6,   2, 11,   3, 10,  10,  3,  11,  2,   3,  9,   1, 11,
    105     11,  1,   9,  3,   1, 13,   5,  9,   9,  5,  13,  1,   5, 12,   4, 13,
    106     13,  4,  12,  5,   0,  7,   0, 15,  15,  8,   8, 15,  15,  1,   7,  1,
    107      1,  6,   2,  5,   3,  4,   4,  3,   5,  2,   6,  1,   0,  0,   1,  1,
    108      9,  6,  10,  5,  11,  4,  12,  3,  13,  2,  14,  1,   2,  2,   3,  3,
    109      4,  4,   5,  5,   6,  6,   7,  7,  14,  9,   1, 15,   8,  9,   8,  8,
    110      9,  9,   1,  7,   0,  9,   9,  8,   6,  9,  13, 10,   2, 15,   8, 10,
    111      7,  2,  15,  2,   2,  7,   0, 10,  10,  8,   5, 10,  12, 11,   3, 15,
    112      8, 11,   7,  3,  15,  3,   3,  7,   0, 11,  11,  8,   4, 11,  11, 12,
    113      4, 15,   8, 12,   7,  4,  15,  4,   4,  7,   0, 12,  12,  8,   3, 12,
    114     10, 13,   5, 15,   8, 13,   7,  5,  15,  5,   5,  7,   0, 13,  13,  8,
    115      2, 13,   9, 14,   6, 15,   8, 14,   7,  6,  15,  6,   6,  7,   0, 14,
    116     14,  8,   1, 14,   5,  6,   2,  4,  13, 14,  10, 12,   4,  2,   3,  6,
    117     12, 10,  11, 14,   6,  3,   1,  2,  14, 11,   9, 10,   2,  1,   5,  3,
    118     10,  9,  13, 11,   3,  5,   4,  1,  11, 13,  12,  9,   1,  4,   6,  5,
    119      9, 12,  14, 13,   5, 14,   2, 12,  13,  6,  10,  4,   4, 10,   3, 14,
    120     12,  2,  11,  6,   6, 11,   1, 10,  14,  3,   9,  2,   2,  9,   5, 11,
    121     10,  1,  13,  3,   3, 13,   4,  9,  11,  5,  12,  1,   1, 12,   6, 13,
    122      9,  4,  14,  5,  10, 10,  11, 11,  12, 12,  13, 13,  14, 14,  15, 15,
    123 };
    124 
    125 static int const slang_assoc[16*16] =
    126 {
    127     134, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    128     28, 135, 214, 86, 219, 91, 133, 127, 26, 23, 240, 112, 245, 117, 141, 126,
    129     37, 211, 142, 83, 206, 132, 78, 160, 35, 237, 32, 109, 232, 140, 104, 161,
    130     46, 87, 82, 143, 131, 215, 210, 169, 44, 113, 108, 41, 139, 241, 236, 170,
    131     55, 222, 203, 130, 144, 94, 75, 178, 53, 248, 229, 138, 50, 120, 101, 179,
    132     64, 90, 129, 218, 95, 145, 223, 187, 62, 116, 137, 244, 121, 59, 249, 188,
    133     73, 128, 79, 207, 74, 202, 146, 196, 71, 136, 105, 233, 100, 228, 68, 197,
    134     122, 153, 162, 171, 180, 189, 198, 147, 16, 25, 34, 43, 52, 61, 70, 18,
    135     15, 27, 36, 45, 54, 63, 72, 17, 151, 155, 164, 173, 182, 191, 200, 124,
    136     154, 22, 238, 110, 243, 115, 156, 24, 150, 152, 216, 88, 221, 93, 148, 20,
    137     163, 235, 31, 107, 230, 165, 102, 33, 159, 213, 250, 85, 208, 157, 80, 29,
    138     172, 111, 106, 40, 174, 239, 234, 42, 168, 89, 84, 251, 166, 217, 212, 38,
    139     181, 246, 227, 183, 49, 118, 99, 51, 177, 224, 205, 175, 252, 96, 77, 47,
    140     190, 114, 192, 242, 119, 58, 247, 60, 186, 92, 184, 220, 97, 253, 225, 56,
    141     199, 201, 103, 231, 98, 226, 67, 69, 195, 193, 81, 209, 76, 204, 254, 65,
    142     123, 149, 158, 167, 176, 185, 194, 19, 125, 21, 30, 39, 48, 57, 66, 255,
    143 };
    144 #endif
    145 
    146 #if defined(USE_WIN32)
    147 static int const win32_fg_palette[] =
    148 {
    149     0,
    150     FOREGROUND_BLUE,
    151     FOREGROUND_GREEN,
    152     FOREGROUND_GREEN | FOREGROUND_BLUE,
    153     FOREGROUND_RED,
    154     FOREGROUND_RED | FOREGROUND_BLUE,
    155     FOREGROUND_RED | FOREGROUND_GREEN,
    156     FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
    157     FOREGROUND_INTENSITY,
    158     FOREGROUND_INTENSITY | FOREGROUND_BLUE,
    159     FOREGROUND_INTENSITY | FOREGROUND_GREEN,
    160     FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
    161     FOREGROUND_INTENSITY | FOREGROUND_RED,
    162     FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
    163     FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
    164     FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
    165 };
    166 
    167 static int const win32_bg_palette[] =
    168 {
    169     0,
    170     BACKGROUND_BLUE,
    171     BACKGROUND_GREEN,
    172     BACKGROUND_GREEN | BACKGROUND_BLUE,
    173     BACKGROUND_RED,
    174     BACKGROUND_RED | BACKGROUND_BLUE,
    175     BACKGROUND_RED | BACKGROUND_GREEN,
    176     BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
    177     BACKGROUND_INTENSITY,
    178     BACKGROUND_INTENSITY | BACKGROUND_BLUE,
    179     BACKGROUND_INTENSITY | BACKGROUND_GREEN,
    180     BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE,
    181     BACKGROUND_INTENSITY | BACKGROUND_RED,
    182     BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE,
    183     BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN,
    184     BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
    185 };
    186 #endif
    187 
    188 #if defined(USE_GL)
    189 /* Ok, I just suck. */
    190 static GLbyte const gl_bgpal[][4] =
    191 {
    192     { 0x00, 0x00, 0x00, 0x7f },
    193     { 0x00, 0x00, 0x3f, 0x7f },
    194     { 0x00, 0x3f, 0x00, 0x7f },
    195     { 0x00, 0x3f, 0x3f, 0x7f },
    196     { 0x3f, 0x00, 0x00, 0x7f },
    197     { 0x3f, 0x00, 0x3f, 0x7f },
    198     { 0x3f, 0x3f, 0x00, 0x7f },
    199     { 0x3f, 0x3f, 0x3f, 0x7f },
    200     // + intensity
    201     { 0x00, 0x00, 0x00, 0x7f },
    202     { 0x00, 0x00, 0x7f, 0x7f },
    203     { 0x00, 0x7f, 0x00, 0x7f },
    204     { 0x00, 0x7f, 0x7f, 0x7f },
    205     { 0x7f, 0x00, 0x00, 0x7f },
    206     { 0x7f, 0x00, 0x7f, 0x7f },
    207     { 0x7f, 0x7f, 0x00, 0x7f },
    208     { 0x7f, 0x7f, 0x7f, 0x7f }
    209 };
    210 
    211 static caca_t *gl_kk; /* FIXME: we ought to get rid of this */
    212 #endif
    213 
    214 /*
    21543 * Local functions
    21644 */
    21745static void caca_handle_resize(caca_t *kk);
    218 
    219 #if defined(USE_SLANG)
    220 static void slang_init_palette(void);
    221 #endif
    222 
    223 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG))
    224 static RETSIGTYPE sigwinch_handler(int);
    225 static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */
    226 #endif
    227 
    228 #if defined(USE_X11)
    229 static int x11_error_handler(Display *, XErrorEvent *);
    230 #endif
    231 
    232 #if defined(USE_GL)
    233 static void gl_handle_keyboard(unsigned char, int, int);
    234 static void gl_handle_special_key(int, int, int);
    235 static void gl_handle_reshape(int, int);
    236 static void gl_handle_mouse(int, int, int, int);
    237 static void gl_handle_mouse_motion(int, int);
    238 #endif
    23946
    24047#if !defined(_DOXYGEN_SKIP_ME)
    24148int _caca_init_graphics(caca_t *kk)
    24249{
    243 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG))
    244     sigwinch_kk = kk;
    245     signal(SIGWINCH, sigwinch_handler);
    246 #endif
    247 
    248 #if defined(USE_SLANG)
    249     if(kk->driver == CACA_DRIVER_SLANG)
    250     {
    251         slang_init_palette();
    252 
    253         /* Disable alt charset support so that we get a chance to have all
    254          * 256 colour pairs */
    255         SLtt_Has_Alt_Charset = 0;
    256 
    257         cucul_set_size(kk->qq, SLtt_Screen_Cols, SLtt_Screen_Rows);
    258     }
    259     else
    260 #endif
    261 #if defined(USE_NCURSES)
    262     if(kk->driver == CACA_DRIVER_NCURSES)
    263     {
    264         static int curses_colors[] =
    265         {
    266             /* Standard curses colours */
    267             COLOR_BLACK,
    268             COLOR_BLUE,
    269             COLOR_GREEN,
    270             COLOR_CYAN,
    271             COLOR_RED,
    272             COLOR_MAGENTA,
    273             COLOR_YELLOW,
    274             COLOR_WHITE,
    275             /* Extra values for xterm-16color */
    276             COLOR_BLACK + 8,
    277             COLOR_BLUE + 8,
    278             COLOR_GREEN + 8,
    279             COLOR_CYAN + 8,
    280             COLOR_RED + 8,
    281             COLOR_MAGENTA + 8,
    282             COLOR_YELLOW + 8,
    283             COLOR_WHITE + 8
    284         };
    285 
    286         int fg, bg, max;
    287 
    288         /* Activate colour */
    289         start_color();
    290 
    291         /* If COLORS == 16, it means the terminal supports full bright colours
    292          * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8),
    293          * we can build 16*16 colour pairs.
    294          * If COLORS == 8, it means the terminal does not know about bright
    295          * colours and we need to get them through A_BOLD and A_BLINK (\e[1m
    296          * and \e[5m). We can only build 8*8 colour pairs. */
    297         max = COLORS >= 16 ? 16 : 8;
    298 
    299         for(bg = 0; bg < max; bg++)
    300             for(fg = 0; fg < max; fg++)
    301             {
    302                 /* Use ((max + 7 - fg) % max) instead of fg so that colour 0
    303                  * is light gray on black. Some terminals don't like this
    304                  * colour pair to be redefined. */
    305                 int col = ((max + 7 - fg) % max) + max * bg;
    306                 init_pair(col, curses_colors[fg], curses_colors[bg]);
    307                 kk->ncurses.attr[fg + 16 * bg] = COLOR_PAIR(col);
    308 
    309                 if(max == 8)
    310                 {
    311                     /* Bright fg on simple bg */
    312                     kk->ncurses.attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
    313                     /* Simple fg on bright bg */
    314                     kk->ncurses.attr[fg + 16 * (bg + 8)] = A_BLINK
    315                                                         | COLOR_PAIR(col);
    316                     /* Bright fg on bright bg */
    317                     kk->ncurses.attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD
    318                                                             | COLOR_PAIR(col);
    319                 }
    320             }
    321 
    322         cucul_set_size(kk->qq, COLS, LINES);
    323     }
    324     else
    325 #endif
    326 #if defined(USE_CONIO)
    327     if(kk->driver == CACA_DRIVER_CONIO)
    328     {
    329         gettextinfo(&kk->conio.ti);
    330         kk->conio.screen = malloc(2 * kk->conio.ti.screenwidth
    331                                 * kk->conio.ti.screenheight * sizeof(char));
    332         if(kk->conio.screen == NULL)
    333             return -1;
    334 #   if defined(SCREENUPDATE_IN_PC_H)
    335         ScreenRetrieve(kk->conio.screen);
    336 #   else
    337         /* FIXME */
    338 #   endif
    339         cucul_set_size(kk->qq, kk->conio.ti.screenwidth,
    340                                kk->conio.ti.screenheight);
    341     }
    342     else
    343 #endif
    344 #if defined(USE_X11)
    345     if(kk->driver == CACA_DRIVER_X11)
    346     {
    347         static int const x11_palette[] =
    348         {
    349             /* Standard curses colours */
    350             0x0,    0x0,    0x0,
    351             0x0,    0x0,    0x8000,
    352             0x0,    0x8000, 0x0,
    353             0x0,    0x8000, 0x8000,
    354             0x8000, 0x0,    0x0,
    355             0x8000, 0x0,    0x8000,
    356             0x8000, 0x8000, 0x0,
    357             0x8000, 0x8000, 0x8000,
    358             /* Extra values for xterm-16color */
    359             0x4000, 0x4000, 0x4000,
    360             0x4000, 0x4000, 0xffff,
    361             0x4000, 0xffff, 0x4000,
    362             0x4000, 0xffff, 0xffff,
    363             0xffff, 0x4000, 0x4000,
    364             0xffff, 0x4000, 0xffff,
    365             0xffff, 0xffff, 0x4000,
    366             0xffff, 0xffff, 0xffff,
    367         };
    368 
    369         Colormap colormap;
    370         XSetWindowAttributes x11_winattr;
    371         int (*old_error_handler)(Display *, XErrorEvent *);
    372         char const *fonts[] = { NULL, "8x13bold", "fixed" }, **parser;
    373         char const *geometry;
    374         unsigned int width = 0, height = 0;
    375         int i;
    376 
    377         geometry = getenv("CACA_GEOMETRY");
    378         if(geometry && *(geometry))
    379             sscanf(geometry, "%ux%u", &width, &height);
    380 
    381         if(width && height)
    382             cucul_set_size(kk->qq, width, height);
    383 
    384         kk->x11.dpy = XOpenDisplay(NULL);
    385         if(kk->x11.dpy == NULL)
    386             return -1;
    387 
    388         fonts[0] = getenv("CACA_FONT");
    389         if(fonts[0] && *fonts[0])
    390             parser = fonts;
    391         else
    392             parser = fonts + 1;
    393 
    394         /* Ignore font errors */
    395         old_error_handler = XSetErrorHandler(x11_error_handler);
    396 
    397         /* Parse our font list */
    398         for( ; ; parser++)
    399         {
    400             if(!*parser)
    401             {
    402                 XSetErrorHandler(old_error_handler);
    403                 XCloseDisplay(kk->x11.dpy);
    404                 return -1;
    405             }
    406 
    407             kk->x11.font = XLoadFont(kk->x11.dpy, *parser);
    408             if(!kk->x11.font)
    409                 continue;
    410 
    411             kk->x11.font_struct = XQueryFont(kk->x11.dpy, kk->x11.font);
    412             if(!kk->x11.font_struct)
    413             {
    414                 XUnloadFont(kk->x11.dpy, kk->x11.font);
    415                 continue;
    416             }
    417 
    418             break;
    419         }
    420 
    421         /* Reset the default X11 error handler */
    422         XSetErrorHandler(old_error_handler);
    423 
    424         kk->x11.font_width = kk->x11.font_struct->max_bounds.width;
    425         kk->x11.font_height = kk->x11.font_struct->max_bounds.ascent
    426                              + kk->x11.font_struct->max_bounds.descent;
    427         kk->x11.font_offset = kk->x11.font_struct->max_bounds.descent;
    428 
    429         colormap = DefaultColormap(kk->x11.dpy, DefaultScreen(kk->x11.dpy));
    430         for(i = 0; i < 16; i++)
    431         {
    432             XColor color;
    433             color.red = x11_palette[i * 3];
    434             color.green = x11_palette[i * 3 + 1];
    435             color.blue = x11_palette[i * 3 + 2];
    436             XAllocColor(kk->x11.dpy, colormap, &color);
    437             kk->x11.colors[i] = color.pixel;
    438         }
    439 
    440         x11_winattr.backing_store = Always;
    441         x11_winattr.background_pixel = kk->x11.colors[0];
    442         x11_winattr.event_mask = ExposureMask | StructureNotifyMask;
    443 
    444         kk->x11.window =
    445             XCreateWindow(kk->x11.dpy, DefaultRootWindow(kk->x11.dpy), 0, 0,
    446                           kk->qq->width * kk->x11.font_width,
    447                           kk->qq->height * kk->x11.font_height,
    448                           0, 0, InputOutput, 0,
    449                           CWBackingStore | CWBackPixel | CWEventMask,
    450                           &x11_winattr);
    451 
    452         XStoreName(kk->x11.dpy, kk->x11.window, "caca for X");
    453 
    454         XSelectInput(kk->x11.dpy, kk->x11.window, StructureNotifyMask);
    455         XMapWindow(kk->x11.dpy, kk->x11.window);
    456 
    457         kk->x11.gc = XCreateGC(kk->x11.dpy, kk->x11.window, 0, NULL);
    458         XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[15]);
    459         XSetFont(kk->x11.dpy, kk->x11.gc, kk->x11.font);
    460 
    461         for(;;)
    462         {
    463             XEvent event;
    464             XNextEvent(kk->x11.dpy, &event);
    465             if (event.type == MapNotify)
    466                 break;
    467         }
    468 
    469 #if defined(HAVE_X11_XKBLIB_H)
    470         /* Disable autorepeat */
    471         XkbSetDetectableAutoRepeat(kk->x11.dpy, True, &kk->x11.autorepeat);
    472         if(!kk->x11.autorepeat)
    473             XAutoRepeatOff(kk->x11.dpy);
    474 #endif
    475 
    476         XSelectInput(kk->x11.dpy, kk->x11.window, kk->x11.event_mask);
    477 
    478         XSync(kk->x11.dpy, False);
    479 
    480         kk->x11.pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window,
    481                                        kk->qq->width * kk->x11.font_width,
    482                                        kk->qq->height * kk->x11.font_height,
    483                                        DefaultDepth(kk->x11.dpy,
    484                                                 DefaultScreen(kk->x11.dpy)));
    485 
    486         kk->x11.new_width = kk->x11.new_height = 0;
    487     }
    488     else
    489 #endif
    490 #if defined(USE_WIN32)
    491     if(kk->driver == CACA_DRIVER_WIN32)
    492     {
    493         CONSOLE_CURSOR_INFO cci;
    494         CONSOLE_SCREEN_BUFFER_INFO csbi;
    495         COORD size;
    496 
    497         kk->win32.front =
    498             CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
    499                                       0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    500         if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE)
    501             return -1;
    502 
    503         kk->win32.back =
    504             CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
    505                                       0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    506         if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE)
    507             return -1;
    508 
    509         if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi))
    510             return -1;
    511 
    512         /* Sample code to get the biggest possible window */
    513         //size = GetLargestConsoleWindowSize(kk->win32.hout);
    514         cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1,
    515                                csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
    516         size.X = kk->qq->width;
    517         size.Y = kk->qq->height;
    518         SetConsoleScreenBufferSize(kk->win32.front, size);
    519         SetConsoleScreenBufferSize(kk->win32.back, size);
    520 
    521         SetConsoleMode(kk->win32.front, 0);
    522         SetConsoleMode(kk->win32.back, 0);
    523 
    524         GetConsoleCursorInfo(kk->win32.front, &cci);
    525         cci.dwSize = 0;
    526         cci.bVisible = FALSE;
    527         SetConsoleCursorInfo(kk->win32.front, &cci);
    528         SetConsoleCursorInfo(kk->win32.back, &cci);
    529 
    530         SetConsoleActiveScreenBuffer(kk->win32.front);
    531 
    532         kk->win32.buffer = malloc(kk->qq->width * kk->qq->height
    533                                    * sizeof(CHAR_INFO));
    534         if(kk->win32.buffer == NULL)
    535             return -1;
    536     }
    537     else
    538 #endif
    539 #if defined(USE_GL)
    540     if(kk->driver == CACA_DRIVER_GL)
    541     {
    542         char *empty_texture;
    543         char const *geometry;
    544         char *argv[2] = { "", NULL };
    545         unsigned int width = 0, height = 0;
    546         int argc = 1;
    547         int i;
    548 
    549         gl_kk = kk;
    550 
    551         geometry = getenv("CACA_GEOMETRY");
    552         if(geometry && *(geometry))
    553             sscanf(geometry, "%ux%u", &width, &height);
    554 
    555         if(width && height)
    556             cucul_set_size(kk->qq, width, height);
    557 
    558         kk->gl.font_width = 9;
    559         kk->gl.font_height = 15;
    560 
    561         kk->gl.width = kk->qq->width * kk->gl.font_width;
    562         kk->gl.height = kk->qq->height * kk->gl.font_height;
    563 
    564         kk->gl.resized = 0;
    565         kk->gl.bit = 0;
    566 
    567         kk->gl.mouse_changed = kk->gl.mouse_clicked = 0;
    568         kk->gl.mouse_button = kk->gl.mouse_state = 0;
    569 
    570         kk->gl.key = 0;
    571         kk->gl.special_key = 0;
    572 
    573         kk->gl.sw = 9.0f / 16.0f;
    574         kk->gl.sh = 15.0f / 16.0f;
    575 
    576         glutInit(&argc, argv);
    577 
    578         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    579         glutInitWindowSize(kk->gl.width, kk->gl.height);
    580         kk->gl.window = glutCreateWindow("caca for GL");
    581 
    582         gluOrtho2D(0, kk->gl.width, kk->gl.height, 0);
    583 
    584         glDisable(GL_CULL_FACE);
    585         glDisable(GL_DEPTH_TEST);
    586 
    587         glutKeyboardFunc(gl_handle_keyboard);
    588         glutSpecialFunc(gl_handle_special_key);
    589         glutReshapeFunc(gl_handle_reshape);
    590 
    591         glutMouseFunc(gl_handle_mouse);
    592         glutMotionFunc(gl_handle_mouse_motion);
    593         glutPassiveMotionFunc(gl_handle_mouse_motion);
    594 
    595         glLoadIdentity();
    596 
    597         glMatrixMode(GL_PROJECTION);
    598         glPushMatrix();
    599         glLoadIdentity();
    600         gluOrtho2D(0, kk->gl.width, kk->gl.height, 0);
    601 
    602         glMatrixMode(GL_MODELVIEW);
    603 
    604         glClear(GL_COLOR_BUFFER_BIT);
    605 
    606         empty_texture = malloc(16 * 16 * 4);
    607         if(empty_texture == NULL)
    608             return -1;
    609 
    610         memset(empty_texture, 0xff, 16 * 16 * 4);
    611         glEnable(GL_TEXTURE_2D);
    612 
    613         for(i = 0; i < 94; i++)
    614         {
    615             glGenTextures(1, (GLuint*)&kk->gl.id[i]);
    616             glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]);
    617             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    618             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    619             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
    620                          16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, empty_texture);
    621         }
    622 
    623         for(i = 0; i < 94; i++)
    624         {
    625             glDisable(GL_TEXTURE_2D);
    626             glClear(GL_COLOR_BUFFER_BIT);
    627 
    628             glColor3f(1, 1, 1);
    629             glRasterPos2f(0, 15);
    630             glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i + 32);
    631 
    632             glEnable(GL_TEXTURE_2D);
    633             glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]);
    634             glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
    635                              0, kk->gl.height - 16, 16, 16, 0);
    636 
    637             glutMainLoopEvent();
    638             glutPostRedisplay();
    639         }
    640     }
    641     else
    642 #endif
    643     {
    644         /* Dummy */
    645     }
     50    int ret = kk->driver.init_graphics(kk);
     51
     52    if(!ret)
     53        return ret;
    64654
    64755    kk->delay = 0;
     
    65361int _caca_end_graphics(caca_t *kk)
    65462{
    655 #if defined(USE_SLANG)
    656     /* Nothing to do */
    657 #endif
    658 #if defined(USE_NCURSES)
    659     /* Nothing to do */
    660 #endif
    661 #if defined(USE_CONIO)
    662     if(kk->driver == CACA_DRIVER_CONIO)
    663     {
    664         free(kk->conio.screen);
    665     }
    666     else
    667 #endif
    668 #if defined(USE_X11)
    669     if(kk->driver == CACA_DRIVER_X11)
    670     {
    671         XSync(kk->x11.dpy, False);
    672 #if defined(HAVE_X11_XKBLIB_H)
    673         if(!kk->x11.autorepeat)
    674             XAutoRepeatOn(kk->x11.dpy);
    675 #endif
    676         XFreePixmap(kk->x11.dpy, kk->x11.pixmap);
    677         XFreeFont(kk->x11.dpy, kk->x11.font_struct);
    678         XFreeGC(kk->x11.dpy, kk->x11.gc);
    679         XUnmapWindow(kk->x11.dpy, kk->x11.window);
    680         XDestroyWindow(kk->x11.dpy, kk->x11.window);
    681         XCloseDisplay(kk->x11.dpy);
    682     }
    683     else
    684 #endif
    685 #if defined(USE_WIN32)
    686     if(kk->driver == CACA_DRIVER_WIN32)
    687     {
    688         SetConsoleActiveScreenBuffer(kk->win32.hout);
    689         CloseHandle(kk->win32.back);
    690         CloseHandle(kk->win32.front);
    691     }
    692     else
    693 #endif
    694 #if defined(USE_GL)
    695     if(kk->driver == CACA_DRIVER_GL)
    696     {
    697         glutDestroyWindow(kk->gl.window);
    698     }
    699     else
    700 #endif
    701     {
    702         /* Dummy */
    703     }
    704 
    705     return 0;
     63    return kk->driver.end_graphics(kk);
    70664}
    70765#endif /* _DOXYGEN_SKIP_ME */
     
    71775int caca_set_window_title(caca_t *kk, char const *title)
    71876{
    719 #if defined(USE_X11)
    720     if(kk->driver == CACA_DRIVER_X11)
    721     {
    722         XStoreName(kk->x11.dpy, kk->x11.window, title);
    723     }
    724     else
    725 #endif
    726 #if defined(USE_WIN32)
    727     if(kk->driver == CACA_DRIVER_WIN32)
    728     {
    729         SetConsoleTitle(title);
    730     }
    731     else
    732 #endif
    733 #if defined(USE_GL)
    734     if(kk->driver == CACA_DRIVER_GL)
    735     {
    736         glutSetWindowTitle(title);
    737     }
    738     else
    739 #endif
    740     {
    741         /* Not supported */
    742         return -1;
    743     }
    744 
    745     return 0;
     77    return kk->driver.set_window_title(kk, title);
    74678}
    74779
     
    75789unsigned int caca_get_window_width(caca_t *kk)
    75890{
    759 #if defined(USE_X11)
    760     if(kk->driver == CACA_DRIVER_X11)
    761     {
    762         return kk->qq->width * kk->x11.font_width;
    763     }
    764     else
    765 #endif
    766 #if defined(USE_WIN32)
    767     if(kk->driver == CACA_DRIVER_WIN32)
    768     {
    769         /* FIXME */
    770     }
    771     else
    772 #endif
    773 #if defined(USE_GL)
    774     if(kk->driver == CACA_DRIVER_GL)
    775     {
    776         return kk->gl.width;
    777     }
    778     else
    779 #endif
    780     {
    781         /* Dummy */
    782     }
    783 
    784     /* Fallback to a 6x10 font */
    785     return kk->qq->width * 6;
     91    return kk->driver.get_window_width(kk);
    78692}
    78793
     
    797103unsigned int caca_get_window_height(caca_t *kk)
    798104{
    799 #if defined(USE_X11)
    800     if(kk->driver == CACA_DRIVER_X11)
    801     {
    802         return kk->qq->height * kk->x11.font_height;
    803     }
    804     else
    805 #endif
    806 #if defined(USE_WIN32)
    807     if(kk->driver == CACA_DRIVER_WIN32)
    808     {
    809         /* FIXME */
    810     }
    811     else
    812 #endif
    813 #if defined(USE_GL)
    814     if(kk->driver == CACA_DRIVER_GL)
    815     {
    816         return kk->gl.height;
    817     }
    818     else
    819 #endif
    820     {
    821         /* Dummy */
    822     }
    823 
    824     /* Fallback to a 6x10 font */
    825     return kk->qq->height * 10;
     105    return kk->driver.get_window_height(kk);
    826106}
    827107
     
    876156    int ticks = kk->lastticks + _caca_getticks(&kk->timer);
    877157
    878 #if defined(USE_SLANG)
    879     if(kk->driver == CACA_DRIVER_SLANG)
    880     {
    881         int x, y;
    882         uint8_t *attr = kk->qq->attr;
    883         uint32_t *chars = kk->qq->chars;
    884         for(y = 0; y < (int)kk->qq->height; y++)
    885         {
    886             SLsmg_gotorc(y, 0);
    887             for(x = kk->qq->width; x--; )
    888             {
    889 #if defined(OPTIMISE_SLANG_PALETTE)
    890                 /* If foreground == background, just don't use this colour
    891                  * pair, and print a space instead of the real character. */
    892                 uint8_t fgcolor = *attr & 0xf;
    893                 uint8_t bgcolor = *attr >> 4;
    894                 if(fgcolor != bgcolor)
    895                 {
    896                     SLsmg_set_color(slang_assoc[*attr++]);
    897                     SLsmg_write_char(*chars++ & 0x7f);
    898                 }
    899                 else
    900                 {
    901                     if(fgcolor == CUCUL_COLOR_BLACK)
    902                         fgcolor = CUCUL_COLOR_WHITE;
    903                     else if(fgcolor == CUCUL_COLOR_WHITE
    904                              || fgcolor <= CUCUL_COLOR_LIGHTGRAY)
    905                         fgcolor = CUCUL_COLOR_BLACK;
    906                     else
    907                         fgcolor = CUCUL_COLOR_WHITE;
    908                     SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
    909                     SLsmg_write_char(' ');
    910                     chars++;
    911                     attr++;
    912                 }
    913 #else
    914                 SLsmg_set_color(*attr++);
    915                 SLsmg_write_char(*chars++ & 0x7f);
    916 #endif
    917             }
    918         }
    919         SLsmg_refresh();
    920     }
    921     else
    922 #endif
    923 #if defined(USE_NCURSES)
    924     if(kk->driver == CACA_DRIVER_NCURSES)
    925     {
    926         int x, y;
    927         uint8_t *attr = kk->qq->attr;
    928         uint32_t *chars = kk->qq->chars;
    929         for(y = 0; y < (int)kk->qq->height; y++)
    930         {
    931             move(y, 0);
    932             for(x = kk->qq->width; x--; )
    933             {
    934                 attrset(kk->ncurses.attr[*attr++]);
    935                 addch(*chars++ & 0x7f);
    936             }
    937         }
    938         refresh();
    939     }
    940     else
    941 #endif
    942 #if defined(USE_CONIO)
    943     if(kk->driver == CACA_DRIVER_CONIO)
    944     {
    945         int n;
    946         char *screen = kk->conio.screen;
    947         uint8_t *attr = kk->qq->attr;
    948         uint32_t *chars = kk->qq->chars;
    949         for(n = kk->qq->height * kk->qq->width; n--; )
    950         {
    951             *screen++ = *chars++ & 0x7f;
    952             *screen++ = *attr++;
    953         }
    954 #   if defined(SCREENUPDATE_IN_PC_H)
    955         ScreenUpdate(kk->conio.screen);
    956 #   else
    957         /* FIXME */
    958 #   endif
    959     }
    960     else
    961 #endif
    962 #if defined(USE_X11)
    963     if(kk->driver == CACA_DRIVER_X11)
    964     {
    965         unsigned int x, y, len;
    966 
    967         /* First draw the background colours. Splitting the process in two
    968          * loops like this is actually slightly faster. */
    969         for(y = 0; y < kk->qq->height; y++)
    970         {
    971             for(x = 0; x < kk->qq->width; x += len)
    972             {
    973                 uint8_t *attr = kk->qq->attr + x + y * kk->qq->width;
    974 
    975                 len = 1;
    976                 while(x + len < kk->qq->width
    977                        && (attr[len] >> 4) == (attr[0] >> 4))
    978                     len++;
    979 
    980                 XSetForeground(kk->x11.dpy, kk->x11.gc,
    981                                kk->x11.colors[attr[0] >> 4]);
    982                 XFillRectangle(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc,
    983                                x * kk->x11.font_width, y * kk->x11.font_height,
    984                                len * kk->x11.font_width, kk->x11.font_height);
    985             }
    986         }
    987 
    988         /* Then print the foreground characters */
    989         for(y = 0; y < kk->qq->height; y++)
    990         {
    991             for(x = 0; x < kk->qq->width; x += len)
    992             {
    993                 char buffer[BUFSIZ]; /* FIXME: use a smaller buffer */
    994                 uint32_t *chars = kk->qq->chars + x + y * kk->qq->width;
    995                 uint8_t *attr = kk->qq->attr + x + y * kk->qq->width;
    996 
    997                 len = 1;
    998 
    999                 /* Skip spaces */
    1000                 if(chars[0] == ' ')
    1001                     continue;
    1002 
    1003                 buffer[0] = chars[0] & 0x7f;
    1004 
    1005                 while(x + len < kk->qq->width
    1006                        && (attr[len] & 0xf) == (attr[0] & 0xf))
    1007                 {
    1008                     buffer[len] = chars[len] & 0x7f;
    1009                     len++;
    1010                 }
    1011 
    1012                 XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[attr[0] & 0xf]);
    1013                 XDrawString(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc,
    1014                             x * kk->x11.font_width,
    1015                             (y + 1) * kk->x11.font_height - kk->x11.font_offset,
    1016                             buffer, len);
    1017             }
    1018         }
    1019 
    1020         XCopyArea(kk->x11.dpy, kk->x11.pixmap, kk->x11.window, kk->x11.gc, 0, 0,
    1021                   kk->qq->width * kk->x11.font_width, kk->qq->height * kk->x11.font_height,
    1022                   0, 0);
    1023         XFlush(kk->x11.dpy);
    1024     }
    1025     else
    1026 #endif
    1027 #if defined(USE_WIN32)
    1028     if(kk->driver == CACA_DRIVER_WIN32)
    1029     {
    1030         COORD size, pos;
    1031         SMALL_RECT rect;
    1032         unsigned int i;
    1033 
    1034         /* Render everything to our back buffer */
    1035         for(i = 0; i < kk->qq->width * kk->qq->height; i++)
    1036         {
    1037             kk->win32.buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f;
    1038             kk->win32.buffer[i].Attributes =
    1039                     win32_fg_palette[kk->qq->attr[i] & 0xf]
    1040                      | win32_bg_palette[kk->qq->attr[i] >> 4];
    1041         }
    1042 
    1043         /* Blit the back buffer to the front buffer */
    1044         size.X = kk->qq->width;
    1045         size.Y = kk->qq->height;
    1046         pos.X = pos.Y = 0;
    1047         rect.Left = rect.Top = 0;
    1048         rect.Right = kk->qq->width - 1;
    1049         rect.Bottom = kk->qq->height - 1;
    1050         WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect);
    1051     }
    1052     else
    1053 #endif
    1054 #if defined(USE_GL)
    1055     if(kk->driver == CACA_DRIVER_GL)
    1056     {
    1057         unsigned int x, y, line;
    1058 
    1059         glClear(GL_COLOR_BUFFER_BIT);
    1060 
    1061         line = 0;
    1062         for(y = 0; y < kk->gl.height; y += kk->gl.font_height)
    1063         {
    1064             uint8_t *attr = kk->qq->attr + line * kk->qq->width;
    1065 
    1066             for(x = 0; x < kk->gl.width; x += kk->gl.font_width)
    1067             {
    1068                 glDisable(GL_TEXTURE_2D);
    1069                 glColor4bv(gl_bgpal[attr[0] >> 4]);
    1070                 glBegin(GL_QUADS);
    1071                     glVertex2f(x, y);
    1072                     glVertex2f(x + kk->gl.font_width, y);
    1073                     glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height);
    1074                     glVertex2f(x, y + kk->gl.font_height);
    1075                 glEnd();
    1076 
    1077                 attr++;
    1078             }
    1079 
    1080             line++;
    1081         }
    1082 
    1083         /* 2nd pass, avoids changing render state too much */
    1084         glEnable(GL_BLEND);
    1085         glEnable(GL_TEXTURE_2D);
    1086         glBlendFunc(GL_ONE, GL_ONE);
    1087 
    1088         line = 0;
    1089         for(y = 0; y < kk->gl.height; y += kk->gl.font_height)
    1090         {
    1091             uint8_t *attr = kk->qq->attr + line * kk->qq->width;
    1092             uint32_t *chars = kk->qq->chars + line * kk->qq->width;
    1093 
    1094             for(x = 0; x < kk->gl.width; x += kk->gl.font_width)
    1095             {
    1096                 if(*chars != (uint32_t)' ')
    1097                 {
    1098                     char ch = *chars & 0x7f;
    1099 
    1100                     /* FIXME: check ch bounds */
    1101                     glBindTexture(GL_TEXTURE_2D, kk->gl.id[ch - 32]);
    1102                     glColor4bv(gl_bgpal[attr[0] & 0xf]);
    1103                     glBegin(GL_QUADS);
    1104                         glTexCoord2f(0, kk->gl.sh);
    1105                         glVertex2f(x, y);
    1106                         glTexCoord2f(kk->gl.sw, kk->gl.sh);
    1107                         glVertex2f(x + kk->gl.font_width, y);
    1108                         glTexCoord2f(kk->gl.sw, 0);
    1109                         glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height);
    1110                         glTexCoord2f(0, 0);
    1111                         glVertex2f(x, y + kk->gl.font_height);
    1112                     glEnd();
    1113                 }
    1114 
    1115                 attr++;
    1116                 chars++;
    1117             }
    1118             line++;
    1119         }
    1120         glDisable(GL_BLEND);
    1121         glDisable(GL_TEXTURE_2D);
    1122 
    1123         glutMainLoopEvent();
    1124         glutSwapBuffers();
    1125         glutPostRedisplay();
    1126     }
    1127     else
    1128 #endif
    1129     {
    1130         /* Dummy */
    1131     }
     158    kk->driver.display(kk);
    1132159
    1133160    /* FIXME handle this somewhere else */
     
    1168195    new_height = kk->qq->height;
    1169196
    1170 #if defined(USE_SLANG)
    1171     if(kk->driver == CACA_DRIVER_SLANG)
    1172     {
    1173         SLtt_get_screen_size();
    1174         new_width = SLtt_Screen_Cols;
    1175         new_height = SLtt_Screen_Rows;
    1176 
    1177         if(new_width != kk->qq->width || new_height != kk->qq->height)
    1178             SLsmg_reinit_smg();
    1179     }
    1180     else
    1181 #endif
    1182 #if defined(USE_NCURSES)
    1183     if(kk->driver == CACA_DRIVER_NCURSES)
    1184     {
    1185         struct winsize size;
    1186 
    1187         if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0)
    1188         {
    1189             new_width = size.ws_col;
    1190             new_height = size.ws_row;
    1191 #if defined(HAVE_RESIZE_TERM)
    1192             resize_term(new_height, new_width);
    1193 #else
    1194             resizeterm(new_height, new_width);
    1195 #endif
    1196             wrefresh(curscr);
    1197         }
    1198     }
    1199     else
    1200 #endif
    1201 #if defined(USE_CONIO)
    1202     if(kk->driver == CACA_DRIVER_CONIO)
    1203     {
    1204         /* Nothing to do here. */
    1205     }
    1206     else
    1207 #endif
    1208 #if defined(USE_X11)
    1209     if(kk->driver == CACA_DRIVER_X11)
    1210     {
    1211         Pixmap new_pixmap;
    1212 
    1213         new_width = kk->x11.new_width;
    1214         new_height = kk->x11.new_height;
    1215 
    1216         new_pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window,
    1217                                    kk->qq->width * kk->x11.font_width,
    1218                                    kk->qq->height * kk->x11.font_height,
    1219                                    DefaultDepth(kk->x11.dpy,
    1220                                                 DefaultScreen(kk->x11.dpy)));
    1221         XCopyArea(kk->x11.dpy, kk->x11.pixmap, new_pixmap, kk->x11.gc, 0, 0,
    1222                   kk->qq->width * kk->x11.font_width,
    1223                   kk->qq->height * kk->x11.font_height, 0, 0);
    1224         XFreePixmap(kk->x11.dpy, kk->x11.pixmap);
    1225         kk->x11.pixmap = new_pixmap;
    1226     }
    1227     else
    1228 #endif
    1229 #if defined(USE_WIN32)
    1230     if(kk->driver == CACA_DRIVER_WIN32)
    1231     {
    1232         /* Nothing to do here. */
    1233     }
    1234     else
    1235 #endif
    1236 #if defined(USE_GL)
    1237     if(kk->driver == CACA_DRIVER_GL)
    1238     {
    1239         kk->gl.width = kk->gl.new_width;
    1240         kk->gl.height = kk->gl.new_height;
    1241 
    1242         new_width = kk->gl.width / kk->gl.font_width;
    1243         new_height = (kk->gl.height / kk->gl.font_height) + 1;
    1244 
    1245         glMatrixMode(GL_PROJECTION);
    1246         glPushMatrix();
    1247         glLoadIdentity();
    1248 
    1249         glViewport(0, 0, kk->gl.width, kk->gl.height);
    1250         gluOrtho2D(0, kk->gl.width, kk->gl.height, 0);
    1251         glMatrixMode(GL_MODELVIEW);
    1252     }
    1253     else
    1254 #endif
    1255     {
    1256         /* Dummy */
    1257     }
     197    kk->driver.handle_resize(kk);
    1258198
    1259199    /* Tell libcucul we changed size */
     
    1262202}
    1263203
    1264 #if defined(USE_SLANG)
    1265 static void slang_init_palette(void)
    1266 {
    1267     /* See SLang ref., 5.4.4. */
    1268     static char *slang_colors[16] =
    1269     {
    1270         /* Standard colours */
    1271         "black",
    1272         "blue",
    1273         "green",
    1274         "cyan",
    1275         "red",
    1276         "magenta",
    1277         "brown",
    1278         "lightgray",
    1279         /* Bright colours */
    1280         "gray",
    1281         "brightblue",
    1282         "brightgreen",
    1283         "brightcyan",
    1284         "brightred",
    1285         "brightmagenta",
    1286         "yellow",
    1287         "white",
    1288     };
    1289 
    1290 #if defined(OPTIMISE_SLANG_PALETTE)
    1291     int i;
    1292 
    1293     for(i = 0; i < 16 * 16; i++)
    1294         SLtt_set_color(i, NULL, slang_colors[slang_palette[i * 2]],
    1295                                 slang_colors[slang_palette[i * 2 + 1]]);
    1296 #else
    1297     int fg, bg;
    1298 
    1299     for(bg = 0; bg < 16; bg++)
    1300         for(fg = 0; fg < 16; fg++)
    1301         {
    1302             int i = fg + 16 * bg;
    1303             SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]);
    1304         }
    1305 #endif
    1306 }
    1307 #endif /* USE_SLANG */
    1308 
    1309 #if defined(USE_X11)
    1310 static int x11_error_handler(Display *dpy, XErrorEvent *event)
    1311 {
    1312     /* Ignore the error */
    1313     return 0;
    1314 }
    1315 #endif
    1316 
    1317 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG))
    1318 static RETSIGTYPE sigwinch_handler(int sig)
    1319 {
    1320     sigwinch_kk->resize_event = 1;
    1321 
    1322     signal(SIGWINCH, sigwinch_handler);;
    1323 }
    1324 #endif
    1325 
    1326 #if defined(USE_GL)
    1327 static void gl_handle_keyboard(unsigned char key, int x, int y)
    1328 {
    1329     caca_t *kk = gl_kk;
    1330 
    1331     kk->gl.key = key;
    1332 }
    1333 
    1334 static void gl_handle_special_key(int key, int x, int y)
    1335 {
    1336     caca_t *kk = gl_kk;
    1337 
    1338     kk->gl.special_key = key;
    1339 }
    1340 
    1341 static void gl_handle_reshape(int w, int h)
    1342 {
    1343     caca_t *kk = gl_kk;
    1344 
    1345     if(kk->gl.bit) /* Do not handle reshaping at the first time */
    1346     {
    1347         kk->gl.new_width = w;
    1348         kk->gl.new_height = h;
    1349 
    1350         kk->gl.resized = 1;
    1351     }
    1352     else
    1353         kk->gl.bit = 1;
    1354 }
    1355 
    1356 static void gl_handle_mouse(int button, int state, int x, int y)
    1357 {
    1358     caca_t *kk = gl_kk;
    1359 
    1360     kk->gl.mouse_clicked = 1;
    1361     kk->gl.mouse_button = button;
    1362     kk->gl.mouse_state = state;
    1363     kk->gl.mouse_x = x / kk->gl.font_width;
    1364     kk->gl.mouse_y = y / kk->gl.font_height;
    1365     kk->gl.mouse_changed = 1;
    1366 }
    1367 
    1368 static void gl_handle_mouse_motion(int x, int y)
    1369 {
    1370     caca_t *kk = gl_kk;
    1371 
    1372     kk->gl.mouse_x = x / kk->gl.font_width;
    1373     kk->gl.mouse_y = y / kk->gl.font_height;
    1374     kk->gl.mouse_changed = 1;
    1375 }
    1376 #endif
    1377 
Note: See TracChangeset for help on using the changeset viewer.