source: libcaca/trunk/caca/driver_ncurses.c @ 2299

Last change on this file since 2299 was 2299, checked in by Sam Hocevar, 12 years ago
  • Remove #include <stdint.h> etc. from "common.h". Instead, make sure that <cucul.h> will provide the C99 types, even if libcaca has been installed.
  • Rename what's left of "common.h" to "stubs.h".
  • Remove all references to erroneous <inttypes.h> from source files.
  • Property svn:keywords set to Id
File size: 20.9 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                2007 Ben Wiley Sittler <bsittler@gmail.com>
5 *                All Rights Reserved
6 *
7 *  $Id: driver_ncurses.c 2299 2008-04-19 12:42:50Z sam $
8 *
9 *  This library is free software. It comes without any warranty, to
10 *  the extent permitted by applicable law. You can redistribute it
11 *  and/or modify it under the terms of the Do What The Fuck You Want
12 *  To Public License, Version 2, as published by Sam Hocevar. See
13 *  http://sam.zoy.org/wtfpl/COPYING for more details.
14 */
15
16/*
17 *  This file contains the libcaca Ncurses input and output driver
18 */
19
20#include "config.h"
21
22#if defined USE_NCURSES
23
24#if defined HAVE_NCURSESW_NCURSES_H
25#   include <ncursesw/ncurses.h>
26#elif defined HAVE_NCURSES_NCURSES_H
27#   include <ncurses/ncurses.h>
28#elif defined HAVE_NCURSES_H
29#   include <ncurses.h>
30#else
31#   include <curses.h>
32#endif
33
34#include <stdlib.h>
35#include <string.h>
36
37#if defined HAVE_UNISTD_H
38#   include <unistd.h>
39#endif
40#if defined HAVE_SIGNAL_H
41#   include <signal.h>
42#endif
43#if defined HAVE_SYS_IOCTL_H
44#   include <sys/ioctl.h>
45#endif
46#if defined HAVE_LOCALE_H
47#   include <locale.h>
48#endif
49#if defined HAVE_TERMIOS_H
50#   include <termios.h>
51#endif
52
53#include "cucul.h"
54#include "caca.h"
55#include "caca_internals.h"
56
57/*
58 * Emulation for missing ACS_* in older curses
59 */
60
61#ifndef ACS_BLOCK
62#define ACS_BLOCK '#'
63#endif
64
65#ifndef ACS_BOARD
66#define ACS_BOARD '#'
67#endif
68
69#ifndef ACS_BTEE
70#define ACS_BTEE '+'
71#endif
72
73#ifndef ACS_BULLET
74#define ACS_BULLET '.'
75#endif
76
77#ifndef ACS_CKBOARD
78#define ACS_CKBOARD ':'
79#endif
80
81#ifndef ACS_DARROW
82#define ACS_DARROW 'v'
83#endif
84
85#ifndef ACS_DEGREE
86#define ACS_DEGREE '\''
87#endif
88
89#ifndef ACS_DIAMOND
90#define ACS_DIAMOND '+'
91#endif
92
93#ifndef ACS_GEQUAL
94#define ACS_GEQUAL '>'
95#endif
96
97#ifndef ACS_HLINE
98#define ACS_HLINE '-'
99#endif
100
101#ifndef ACS_LANTERN
102#define ACS_LANTERN '#'
103#endif
104
105#ifndef ACS_LARROW
106#define ACS_LARROW '<'
107#endif
108
109#ifndef ACS_LEQUAL
110#define ACS_LEQUAL '<'
111#endif
112
113#ifndef ACS_LLCORNER
114#define ACS_LLCORNER '+'
115#endif
116
117#ifndef ACS_LRCORNER
118#define ACS_LRCORNER '+'
119#endif
120
121#ifndef ACS_LTEE
122#define ACS_LTEE '+'
123#endif
124
125#ifndef ACS_NEQUAL
126#define ACS_NEQUAL '!'
127#endif
128
129#ifndef ACS_PI
130#define ACS_PI '*'
131#endif
132
133#ifndef ACS_STERLING
134#define ACS_STERLING 'f'
135#endif
136
137#ifndef ACS_PLMINUS
138#define ACS_PLMINUS '#'
139#endif
140
141#ifndef ACS_PLUS
142#define ACS_PLUS '+'
143#endif
144
145#ifndef ACS_RARROW
146#define ACS_RARROW '>'
147#endif
148
149#ifndef ACS_RTEE
150#define ACS_RTEE '+'
151#endif
152
153#ifndef ACS_S1
154#define ACS_S1 '-'
155#endif
156
157#ifndef ACS_S3
158#define ACS_S3 '-'
159#endif
160
161#ifndef ACS_S7
162#define ACS_S7 '-'
163#endif
164
165#ifndef ACS_S9
166#define ACS_S9 '-'
167#endif
168
169#ifndef ACS_TTEE
170#define ACS_TTEE '+'
171#endif
172
173#ifndef ACS_UARROW
174#define ACS_UARROW '^'
175#endif
176
177#ifndef ACS_ULCORNER
178#define ACS_ULCORNER '+'
179#endif
180
181#ifndef ACS_URCORNER
182#define ACS_URCORNER '+'
183#endif
184
185#ifndef ACS_VLINE
186#define ACS_VLINE '|'
187#endif
188
189/*
190 * Local functions
191 */
192
193#if defined HAVE_SIGNAL
194static RETSIGTYPE sigwinch_handler(int);
195static caca_display_t *sigwinch_d; /* FIXME: we ought to get rid of this */
196#endif
197#if defined HAVE_GETENV && defined HAVE_PUTENV
198static void ncurses_install_terminal(caca_display_t *);
199static void ncurses_uninstall_terminal(caca_display_t *);
200#endif
201static void ncurses_write_utf32(uint32_t);
202
203struct driver_private
204{
205    int attr[16*16];
206    mmask_t oldmask;
207    char *term;
208};
209
210static int ncurses_init_graphics(caca_display_t *dp)
211{
212    static int curses_colors[] =
213    {
214        /* Standard curses colours */
215        COLOR_BLACK,
216        COLOR_BLUE,
217        COLOR_GREEN,
218        COLOR_CYAN,
219        COLOR_RED,
220        COLOR_MAGENTA,
221        COLOR_YELLOW,
222        COLOR_WHITE,
223        /* Extra values for xterm-16color */
224        COLOR_BLACK + 8,
225        COLOR_BLUE + 8,
226        COLOR_GREEN + 8,
227        COLOR_CYAN + 8,
228        COLOR_RED + 8,
229        COLOR_MAGENTA + 8,
230        COLOR_YELLOW + 8,
231        COLOR_WHITE + 8
232    };
233
234    mmask_t newmask;
235    int fg, bg, max;
236
237    dp->drv.p = malloc(sizeof(struct driver_private));
238
239#if defined HAVE_GETENV && defined HAVE_PUTENV
240    ncurses_install_terminal(dp);
241#endif
242
243#if defined HAVE_SIGNAL
244    sigwinch_d = dp;
245    signal(SIGWINCH, sigwinch_handler);
246#endif
247
248#if defined HAVE_LOCALE_H
249    setlocale(LC_ALL, "");
250#endif
251
252    _caca_set_term_title("caca for ncurses");
253
254    initscr();
255    keypad(stdscr, TRUE);
256    nonl();
257    raw();
258    noecho();
259    nodelay(stdscr, TRUE);
260    curs_set(0);
261
262    /* Activate mouse */
263    newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS;
264    mousemask(newmask, &dp->drv.p->oldmask);
265    mouseinterval(-1); /* No click emulation */
266
267    /* Set the escape delay to a ridiculously low value */
268    ESCDELAY = 10;
269
270    /* Activate colour */
271    start_color();
272
273    /* If COLORS == 16, it means the terminal supports full bright colours
274     * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8),
275     * we can build 16*16 colour pairs.
276     * If COLORS == 8, it means the terminal does not know about bright
277     * colours and we need to get them through A_BOLD and A_BLINK (\e[1m
278     * and \e[5m). We can only build 8*8 colour pairs. */
279    max = COLORS >= 16 ? 16 : 8;
280
281    for(bg = 0; bg < max; bg++)
282        for(fg = 0; fg < max; fg++)
283        {
284            /* Use ((max + 7 - fg) % max) instead of fg so that colour 0
285             * is light gray on black. Some terminals don't like this
286             * colour pair to be redefined. */
287            int col = ((max + 7 - fg) % max) + max * bg;
288            init_pair(col, curses_colors[fg], curses_colors[bg]);
289            dp->drv.p->attr[fg + 16 * bg] = COLOR_PAIR(col);
290
291            if(max == 8)
292            {
293                /* Bright fg on simple bg */
294                dp->drv.p->attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
295                /* Simple fg on bright bg */
296                dp->drv.p->attr[fg + 16 * (bg + 8)] = A_BLINK
297                                                    | COLOR_PAIR(col);
298                /* Bright fg on bright bg */
299                dp->drv.p->attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD
300                                                        | COLOR_PAIR(col);
301            }
302        }
303
304    dp->resize.allow = 1;
305    cucul_set_canvas_size(dp->cv, COLS, LINES);
306    dp->resize.allow = 0;
307
308    return 0;
309}
310
311static int ncurses_end_graphics(caca_display_t *dp)
312{
313    _caca_set_term_title("");
314    mousemask(dp->drv.p->oldmask, NULL);
315    curs_set(1);
316    noraw();
317    endwin();
318
319#if defined HAVE_GETENV && defined HAVE_PUTENV
320    ncurses_uninstall_terminal(dp);
321#endif
322
323    free(dp->drv.p);
324
325    return 0;
326}
327
328static int ncurses_set_display_title(caca_display_t *dp, char const *title)
329{
330    _caca_set_term_title(title);
331
332    return 0;
333}
334
335static unsigned int ncurses_get_display_width(caca_display_t const *dp)
336{
337    /* Fallback to a 6x10 font */
338    return cucul_get_canvas_width(dp->cv) * 6;
339}
340
341static unsigned int ncurses_get_display_height(caca_display_t const *dp)
342{
343    /* Fallback to a 6x10 font */
344    return cucul_get_canvas_height(dp->cv) * 10;
345}
346
347static void ncurses_display(caca_display_t *dp)
348{
349    uint32_t const *cvchars = (uint32_t const *)cucul_get_canvas_chars(dp->cv);
350    uint32_t const *cvattrs = (uint32_t const *)cucul_get_canvas_attrs(dp->cv);
351    unsigned int width = cucul_get_canvas_width(dp->cv);
352    unsigned int height = cucul_get_canvas_height(dp->cv);
353    int x, y;
354
355    for(y = 0; y < (int)height; y++)
356    {
357        move(y, 0);
358        for(x = width; x--; )
359        {
360            attrset(dp->drv.p->attr[cucul_attr_to_ansi(*cvattrs++)]);
361            ncurses_write_utf32(*cvchars++);
362        }
363    }
364   
365    x = cucul_get_cursor_x(dp->cv);
366    y = cucul_get_cursor_y(dp->cv);
367    move(y, x);
368
369    refresh();
370}
371
372static void ncurses_handle_resize(caca_display_t *dp)
373{
374    struct winsize size;
375
376#if defined HAVE_SYS_IOCTL_H
377    if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0)
378    {
379        dp->resize.w = size.ws_col;
380        dp->resize.h = size.ws_row;
381#if defined HAVE_RESIZE_TERM
382        resize_term(dp->resize.h, dp->resize.w);
383#else
384        resizeterm(dp->resize.h, dp->resize.w);
385#endif
386        wrefresh(curscr);
387        return;
388    }
389#endif
390
391    /* Fallback */
392    dp->resize.w = cucul_get_canvas_width(dp->cv);
393    dp->resize.h = cucul_get_canvas_height(dp->cv);
394}
395
396static int ncurses_get_event(caca_display_t *dp, caca_privevent_t *ev)
397{
398    int intkey;
399
400    intkey = getch();
401    if(intkey == ERR)
402    {
403        ev->type = CACA_EVENT_NONE;
404        return 0;
405    }
406
407    if(intkey < 0x7f)
408    {
409        ev->type = CACA_EVENT_KEY_PRESS;
410        ev->data.key.ch = intkey;
411        ev->data.key.utf32 = intkey;
412        ev->data.key.utf8[0] = intkey;
413        ev->data.key.utf8[1] = '\0';
414        return 1;
415    }
416
417    /* If the key was UTF-8, parse the whole sequence */
418    if(intkey >= 0x80 && intkey < 0x100)
419    {
420        int keys[7]; /* Necessary for ungetch(); */
421        char utf8[7];
422        uint32_t utf32;
423        unsigned int i, bytes = 0;
424
425        keys[0] = intkey;
426        utf8[0] = intkey;
427
428        for(i = 1; i < 6; i++)
429        {
430            keys[i] = getch();
431            utf8[i] = (unsigned char)keys[i];
432        }
433
434        utf8[i] = '\0';
435        utf32 = cucul_utf8_to_utf32(utf8, &bytes);
436
437        while(i > bytes)
438            ungetch(keys[--i]);
439
440        if(bytes)
441        {
442            ev->type = CACA_EVENT_KEY_PRESS;
443            ev->data.key.ch = 0;
444            ev->data.key.utf32 = utf32;
445            strcpy(ev->data.key.utf8, utf8);
446            return 1;
447        }
448    }
449
450    if(intkey == KEY_MOUSE)
451    {
452        MEVENT mevent;
453        getmouse(&mevent);
454
455        switch(mevent.bstate)
456        {
457#define PRESS(x) ev->data.mouse.button = x; \
458                 ev->type = CACA_EVENT_MOUSE_PRESS; _push_event(dp, ev)
459#define RELEASE(x) ev->data.mouse.button = x; \
460                   ev->type = CACA_EVENT_MOUSE_RELEASE; _push_event(dp, ev)
461#define CLICK(x) PRESS(x); RELEASE(x)
462            case BUTTON1_PRESSED: PRESS(1); break;
463            case BUTTON1_RELEASED: RELEASE(1); break;
464            case BUTTON1_CLICKED: CLICK(1); break;
465            case BUTTON1_DOUBLE_CLICKED: CLICK(1); CLICK(1); break;
466            case BUTTON1_TRIPLE_CLICKED: CLICK(1); CLICK(1); CLICK(1); break;
467            case BUTTON1_RESERVED_EVENT: break;
468
469            case BUTTON2_PRESSED: PRESS(2); break;
470            case BUTTON2_RELEASED: RELEASE(2); break;
471            case BUTTON2_CLICKED: CLICK(2); break;
472            case BUTTON2_DOUBLE_CLICKED: CLICK(2); CLICK(2); break;
473            case BUTTON2_TRIPLE_CLICKED: CLICK(2); CLICK(2); CLICK(2); break;
474            case BUTTON2_RESERVED_EVENT: break;
475
476            case BUTTON3_PRESSED: PRESS(3); break;
477            case BUTTON3_RELEASED: RELEASE(3); break;
478            case BUTTON3_CLICKED: CLICK(3); break;
479            case BUTTON3_DOUBLE_CLICKED: CLICK(3); CLICK(3); break;
480            case BUTTON3_TRIPLE_CLICKED: CLICK(3); CLICK(3); CLICK(3); break;
481            case BUTTON3_RESERVED_EVENT: break;
482
483            case BUTTON4_PRESSED: PRESS(4); break;
484            case BUTTON4_RELEASED: RELEASE(4); break;
485            case BUTTON4_CLICKED: CLICK(4); break;
486            case BUTTON4_DOUBLE_CLICKED: CLICK(4); CLICK(4); break;
487            case BUTTON4_TRIPLE_CLICKED: CLICK(4); CLICK(4); CLICK(4); break;
488            case BUTTON4_RESERVED_EVENT: break;
489
490            default:
491                break;
492#undef PRESS
493#undef RELEASE
494#undef CLICK
495        }
496
497        if(dp->mouse.x == (unsigned int)mevent.x &&
498           dp->mouse.y == (unsigned int)mevent.y)
499            return _pop_event(dp, ev);
500
501        dp->mouse.x = mevent.x;
502        dp->mouse.y = mevent.y;
503
504        ev->type = CACA_EVENT_MOUSE_MOTION;
505        ev->data.mouse.x = dp->mouse.x;
506        ev->data.mouse.y = dp->mouse.y;
507        return 1;
508    }
509
510    switch(intkey)
511    {
512        case KEY_UP: ev->data.key.ch = CACA_KEY_UP; break;
513        case KEY_DOWN: ev->data.key.ch = CACA_KEY_DOWN; break;
514        case KEY_LEFT: ev->data.key.ch = CACA_KEY_LEFT; break;
515        case KEY_RIGHT: ev->data.key.ch = CACA_KEY_RIGHT; break;
516
517        case KEY_IC: ev->data.key.ch = CACA_KEY_INSERT; break;
518        case KEY_DC: ev->data.key.ch = CACA_KEY_DELETE; break;
519        case 0x7f:
520        case KEY_BACKSPACE: ev->data.key.ch = CACA_KEY_BACKSPACE; break;
521        case KEY_HOME: ev->data.key.ch = CACA_KEY_HOME; break;
522        case KEY_END: ev->data.key.ch = CACA_KEY_END; break;
523        case KEY_PPAGE: ev->data.key.ch = CACA_KEY_PAGEUP; break;
524        case KEY_NPAGE: ev->data.key.ch = CACA_KEY_PAGEDOWN; break;
525
526        case KEY_F(1): ev->data.key.ch = CACA_KEY_F1; break;
527        case KEY_F(2): ev->data.key.ch = CACA_KEY_F2; break;
528        case KEY_F(3): ev->data.key.ch = CACA_KEY_F3; break;
529        case KEY_F(4): ev->data.key.ch = CACA_KEY_F4; break;
530        case KEY_F(5): ev->data.key.ch = CACA_KEY_F5; break;
531        case KEY_F(6): ev->data.key.ch = CACA_KEY_F6; break;
532        case KEY_F(7): ev->data.key.ch = CACA_KEY_F7; break;
533        case KEY_F(8): ev->data.key.ch = CACA_KEY_F8; break;
534        case KEY_F(9): ev->data.key.ch = CACA_KEY_F9; break;
535        case KEY_F(10): ev->data.key.ch = CACA_KEY_F10; break;
536        case KEY_F(11): ev->data.key.ch = CACA_KEY_F11; break;
537        case KEY_F(12): ev->data.key.ch = CACA_KEY_F12; break;
538
539        default:
540            /* Unknown key */
541            ev->type = CACA_EVENT_NONE; return 0;
542    }
543
544    ev->type = CACA_EVENT_KEY_PRESS;
545    ev->data.key.utf32 = 0;
546    ev->data.key.utf8[0] = '\0';
547    return 1;
548}
549
550static void ncurses_set_cursor(caca_display_t *dp, int flags)
551{
552    curs_set(flags ? 2 : 0);
553}
554
555/*
556 * XXX: following functions are local
557 */
558
559#if defined HAVE_SIGNAL
560static RETSIGTYPE sigwinch_handler(int sig)
561{
562    sigwinch_d->resize.resized = 1;
563
564    signal(SIGWINCH, sigwinch_handler);
565}
566#endif
567
568#if defined HAVE_GETENV && defined HAVE_PUTENV
569static void ncurses_install_terminal(caca_display_t *dp)
570{
571    char *term, *colorterm;
572
573    dp->drv.p->term = NULL;
574
575    term = getenv("TERM");
576    colorterm = getenv("COLORTERM");
577
578    if(!term || strcmp(term, "xterm"))
579        return;
580
581    /* If we are using gnome-terminal, it's really a 16 colour terminal.
582     * Ditto if we are using xfce4-terminal, or Konsole. */
583    if((colorterm && (!strcmp(colorterm, "gnome-terminal")
584                       || !strcmp(colorterm, "Terminal")))
585         || getenv("KONSOLE_DCOP_SESSION"))
586    {
587        SCREEN *screen;
588        screen = newterm("xterm-16color", stdout, stdin);
589        if(screen == NULL)
590            return;
591        endwin();
592        (void)putenv("TERM=xterm-16color");
593        dp->drv.p->term = strdup(term);
594        return;
595    }
596}
597
598static void ncurses_uninstall_terminal(caca_display_t *dp)
599{
600    /* Needs to be persistent because we use putenv() */
601    static char termenv[1024];
602
603    if(!dp->drv.p->term)
604        return;
605
606    snprintf(termenv, 1023, "TERM=%s", dp->drv.p->term);
607    free(dp->drv.p->term);
608    (void)putenv(termenv);
609}
610#endif
611
612static void ncurses_write_utf32(uint32_t ch)
613{
614#if defined HAVE_NCURSESW_NCURSES_H
615    char buf[10];
616    int bytes;
617#endif
618
619    if(ch == CUCUL_MAGIC_FULLWIDTH)
620        return;
621
622#if defined HAVE_NCURSESW_NCURSES_H
623    bytes = cucul_utf32_to_utf8(buf, ch);
624    buf[bytes] = '\0';
625    addstr(buf);
626#else
627    if(ch < 0x80)
628    {
629        addch(ch);
630    }
631    else
632    {
633        chtype cch;
634        chtype cch2;
635
636        cch = '?';
637        cch2 = ' ';
638        if ((ch > 0x0000ff00) && (ch < 0x0000ff5f))
639        {
640            cch = ch - 0x0000ff00 + ' ';
641        }
642        switch (ch)
643        {
644        case 0x000000a0: /* <nbsp> */
645        case 0x00003000: /*   */
646            cch = ' ';
647            break;
648        case 0x000000a3: /* £ */
649            cch = ACS_STERLING;
650            break;
651        case 0x000000b0: /* ° */
652            cch = ACS_DEGREE;
653            break;
654        case 0x000000b1: /* ± */
655            cch = ACS_PLMINUS;
656            break;
657        case 0x000000b7: /* · */
658        case 0x00002219: /* ∙ */
659        case 0x000030fb: /* ・ */
660            cch = ACS_BULLET;
661            break;
662        case 0x000003c0: /* π */
663            cch = ACS_PI;
664            break;
665        case 0x00002018: /* ‘ */
666        case 0x00002019: /* ’ */
667            cch = '\'';
668            break;
669        case 0x0000201c: /* “ */
670        case 0x0000201d: /* ” */
671            cch = '"';
672            break;
673        case 0x00002190: /* ← */
674            cch = ACS_LARROW;
675            break;
676        case 0x00002191: /* ↑ */
677            cch = ACS_UARROW;
678            break;
679        case 0x00002192: /* → */
680            cch = ACS_RARROW;
681            break;
682        case 0x00002193: /* ↓ */
683            cch = ACS_DARROW;
684            break;
685        case 0x00002260: /* ≠ */
686            cch = ACS_NEQUAL;
687            break;
688        case 0x00002261: /* ≡ */
689            cch = '=';
690            break;
691        case 0x00002264: /* ≤ */
692            cch = ACS_LEQUAL;
693            break;
694        case 0x00002265: /* ≥ */
695            cch = ACS_GEQUAL;
696            break;
697        case 0x000023ba: /* ⎺ */
698            cch = ACS_S1;
699            cch2 = cch;
700            break;
701        case 0x000023bb: /* ⎻ */
702            cch = ACS_S3;
703            cch2 = cch;
704            break;
705        case 0x000023bc: /* ⎼ */
706            cch = ACS_S7;
707            cch2 = cch;
708            break;
709        case 0x000023bd: /* ⎽ */
710            cch = ACS_S9;
711            cch2 = cch;
712            break;
713        case 0x00002500: /* ─ */
714        case 0x00002550: /* ═ */
715            cch = ACS_HLINE;
716            cch2 = cch;
717            break;
718        case 0x00002502: /* │ */
719        case 0x00002551: /* ║ */
720            cch = ACS_VLINE;
721            break;
722        case 0x0000250c: /* ┌ */
723        case 0x00002552: /* ╒ */
724        case 0x00002553: /* ╓ */
725        case 0x00002554: /* ╔ */
726            cch = ACS_ULCORNER;
727            cch2 = ACS_HLINE;
728            break;
729        case 0x00002510: /* ┐ */
730        case 0x00002555: /* ╕ */
731        case 0x00002556: /* ╖ */
732        case 0x00002557: /* ╗ */
733            cch = ACS_URCORNER;
734            break;
735        case 0x00002514: /* └ */
736        case 0x00002558: /* ╘ */
737        case 0x00002559: /* ╙ */
738        case 0x0000255a: /* ╚ */
739            cch = ACS_LLCORNER;
740            cch2 = ACS_HLINE;
741            break;
742        case 0x00002518: /* ┘ */
743        case 0x0000255b: /* ╛ */
744        case 0x0000255c: /* ╜ */
745        case 0x0000255d: /* ╝ */
746            cch = ACS_LRCORNER;
747            break;
748        case 0x0000251c: /* ├ */
749        case 0x0000255e: /* ╞ */
750        case 0x0000255f: /* ╟ */
751        case 0x00002560: /* ╠ */
752            cch = ACS_LTEE;
753            cch2 = ACS_HLINE;
754            break;
755        case 0x00002524: /* ┤ */
756        case 0x00002561: /* ╡ */
757        case 0x00002562: /* ╢ */
758        case 0x00002563: /* ╣ */
759            cch = ACS_RTEE;
760            break;
761        case 0x0000252c: /* ┬ */
762        case 0x00002564: /* ╤ */
763        case 0x00002565: /* ╥ */
764        case 0x00002566: /* ╦ */
765            cch = ACS_TTEE;
766            cch2 = ACS_HLINE;
767            break;
768        case 0x00002534: /* ┴ */
769        case 0x00002567: /* ╧ */
770        case 0x00002568: /* ╨ */
771        case 0x00002569: /* ╩ */
772            cch = ACS_BTEE;
773            cch2 = ACS_HLINE;
774            break;
775        case 0x0000253c: /* ┼ */
776        case 0x0000256a: /* ╪ */
777        case 0x0000256b: /* ╫ */
778        case 0x0000256c: /* ╬ */
779            cch = ACS_PLUS;
780            cch2 = ACS_HLINE;
781            break;
782        case 0x00002591: /* ░ */
783            cch = ACS_BOARD;
784            cch2 = cch;
785            break;
786        case 0x00002592: /* ▒ */
787        case 0x00002593: /* ▓ */
788            cch = ACS_CKBOARD;
789            cch2 = cch;
790            break;
791        case 0x00002580: /* ▀ */
792        case 0x00002584: /* ▄ */
793        case 0x00002588: /* █ */
794        case 0x0000258c: /* ▌ */
795        case 0x00002590: /* ▐ */
796        case 0x000025a0: /* ■ */
797        case 0x000025ac: /* ▬ */
798        case 0x000025ae: /* ▮ */
799            cch = ACS_BLOCK;
800            cch2 = cch;
801            break;
802        case 0x000025c6: /* ◆ */
803        case 0x00002666: /* ♦ */
804            cch = ACS_DIAMOND;
805            break;
806        case 0x00002022: /* • */
807        case 0x000025cb: /* ○ */
808        case 0x000025cf: /* ● */
809        case 0x00002603: /* ☃ */
810        case 0x0000263c: /* ☼ */
811            cch = ACS_LANTERN;
812            break;
813        case 0x0000301c: /* 〜 */
814            cch = '~';
815            break;
816        }
817        addch(cch);
818        if(cucul_utf32_is_fullwidth(ch))
819        {
820            addch(cch2);
821        }
822    }
823#endif
824}
825
826/*
827 * Driver initialisation
828 */
829
830int ncurses_install(caca_display_t *dp)
831{
832    dp->drv.id = CACA_DRIVER_NCURSES;
833    dp->drv.driver = "ncurses";
834
835    dp->drv.init_graphics = ncurses_init_graphics;
836    dp->drv.end_graphics = ncurses_end_graphics;
837    dp->drv.set_display_title = ncurses_set_display_title;
838    dp->drv.get_display_width = ncurses_get_display_width;
839    dp->drv.get_display_height = ncurses_get_display_height;
840    dp->drv.display = ncurses_display;
841    dp->drv.handle_resize = ncurses_handle_resize;
842    dp->drv.get_event = ncurses_get_event;
843    dp->drv.set_mouse = NULL;
844    dp->drv.set_cursor = ncurses_set_cursor;
845
846    return 0;
847}
848
849#endif /* USE_NCURSES */
850
Note: See TracBrowser for help on using the repository browser.