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

Last change on this file since 2055 was 2055, checked in by Sam Hocevar, 13 years ago
  • Add cucul_manage_canvas() and cucul_unmanage_canvas(). Display drivers no longer need to access the cv->refcount private member and cucul_set_canvas_size() is no longer needed.
  • Property svn:keywords set to Id
File size: 20.1 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 2055 2007-11-25 14:11:58Z 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#include "common.h"
22
23#if defined USE_NCURSES
24
25#if defined HAVE_NCURSESW_NCURSES_H
26#   include <ncursesw/ncurses.h>
27#elif defined HAVE_NCURSES_NCURSES_H
28#   include <ncurses/ncurses.h>
29#elif defined HAVE_NCURSES_H
30#   include <ncurses.h>
31#else
32#   include <curses.h>
33#endif
34
35#include <stdlib.h>
36#include <string.h>
37
38#if defined HAVE_UNISTD_H
39#   include <unistd.h>
40#endif
41#if defined HAVE_SIGNAL_H
42#   include <signal.h>
43#endif
44#if defined HAVE_SYS_IOCTL_H
45#   include <sys/ioctl.h>
46#endif
47#if defined HAVE_LOCALE_H
48#   include <locale.h>
49#endif
50#if defined HAVE_TERMIOS_H
51#   include <termios.h>
52#endif
53
54#include "caca.h"
55#include "caca_internals.h"
56#include "cucul.h"
57#include "cucul_internals.h"
58
59/*
60 * Emulation for missing ACS_* in older curses
61 */
62
63#ifndef ACS_BLOCK
64#define ACS_BLOCK '#'
65#endif
66
67#ifndef ACS_BOARD
68#define ACS_BOARD '#'
69#endif
70
71#ifndef ACS_BTEE
72#define ACS_BTEE '+'
73#endif
74
75#ifndef ACS_BULLET
76#define ACS_BULLET '.'
77#endif
78
79#ifndef ACS_CKBOARD
80#define ACS_CKBOARD ':'
81#endif
82
83#ifndef ACS_DARROW
84#define ACS_DARROW 'v'
85#endif
86
87#ifndef ACS_DEGREE
88#define ACS_DEGREE '\''
89#endif
90
91#ifndef ACS_DIAMOND
92#define ACS_DIAMOND '+'
93#endif
94
95#ifndef ACS_GEQUAL
96#define ACS_GEQUAL '>'
97#endif
98
99#ifndef ACS_HLINE
100#define ACS_HLINE '-'
101#endif
102
103#ifndef ACS_LANTERN
104#define ACS_LANTERN '#'
105#endif
106
107#ifndef ACS_LARROW
108#define ACS_LARROW '<'
109#endif
110
111#ifndef ACS_LEQUAL
112#define ACS_LEQUAL '<'
113#endif
114
115#ifndef ACS_LLCORNER
116#define ACS_LLCORNER '+'
117#endif
118
119#ifndef ACS_LRCORNER
120#define ACS_LRCORNER '+'
121#endif
122
123#ifndef ACS_LTEE
124#define ACS_LTEE '+'
125#endif
126
127#ifndef ACS_NEQUAL
128#define ACS_NEQUAL '!'
129#endif
130
131#ifndef ACS_PI
132#define ACS_PI '*'
133#endif
134
135#ifndef ACS_STERLING
136#define ACS_STERLING 'f'
137#endif
138
139#ifndef ACS_PLMINUS
140#define ACS_PLMINUS '#'
141#endif
142
143#ifndef ACS_PLUS
144#define ACS_PLUS '+'
145#endif
146
147#ifndef ACS_RARROW
148#define ACS_RARROW '>'
149#endif
150
151#ifndef ACS_RTEE
152#define ACS_RTEE '+'
153#endif
154
155#ifndef ACS_S1
156#define ACS_S1 '-'
157#endif
158
159#ifndef ACS_S3
160#define ACS_S3 '-'
161#endif
162
163#ifndef ACS_S7
164#define ACS_S7 '-'
165#endif
166
167#ifndef ACS_S9
168#define ACS_S9 '-'
169#endif
170
171#ifndef ACS_TTEE
172#define ACS_TTEE '+'
173#endif
174
175#ifndef ACS_UARROW
176#define ACS_UARROW '^'
177#endif
178
179#ifndef ACS_ULCORNER
180#define ACS_ULCORNER '+'
181#endif
182
183#ifndef ACS_URCORNER
184#define ACS_URCORNER '+'
185#endif
186
187#ifndef ACS_VLINE
188#define ACS_VLINE '|'
189#endif
190
191/*
192 * Local functions
193 */
194
195#if defined HAVE_SIGNAL
196static RETSIGTYPE sigwinch_handler(int);
197static caca_display_t *sigwinch_d; /* FIXME: we ought to get rid of this */
198#endif
199#if defined HAVE_GETENV && defined HAVE_PUTENV
200static void ncurses_check_terminal(void);
201#endif
202static void ncurses_write_utf32(uint32_t);
203
204struct driver_private
205{
206    int attr[16*16];
207    mmask_t oldmask;
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_check_terminal();
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    free(dp->drv.p);
320
321    return 0;
322}
323
324static int ncurses_set_display_title(caca_display_t *dp, char const *title)
325{
326    _caca_set_term_title(title);
327
328    return 0;
329}
330
331static unsigned int ncurses_get_display_width(caca_display_t const *dp)
332{
333    /* Fallback to a 6x10 font */
334    return dp->cv->width * 6;
335}
336
337static unsigned int ncurses_get_display_height(caca_display_t const *dp)
338{
339    /* Fallback to a 6x10 font */
340    return dp->cv->height * 10;
341}
342
343static void ncurses_display(caca_display_t *dp)
344{
345    int x, y;
346    uint32_t *attrs = dp->cv->attrs;
347    uint32_t *chars = dp->cv->chars;
348    for(y = 0; y < (int)dp->cv->height; y++)
349    {
350        move(y, 0);
351        for(x = dp->cv->width; x--; )
352        {
353            attrset(dp->drv.p->attr[cucul_attr_to_ansi(*attrs++)]);
354            ncurses_write_utf32(*chars++);
355        }
356    }
357   
358    x = cucul_get_cursor_x(dp->cv);
359    y = cucul_get_cursor_y(dp->cv);
360    move(y, x);
361
362    refresh();
363}
364
365static void ncurses_handle_resize(caca_display_t *dp)
366{
367    struct winsize size;
368
369#if defined HAVE_SYS_IOCTL_H
370    if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0)
371    {
372        dp->resize.w = size.ws_col;
373        dp->resize.h = size.ws_row;
374#if defined HAVE_RESIZE_TERM
375        resize_term(dp->resize.h, dp->resize.w);
376#else
377        resizeterm(dp->resize.h, dp->resize.w);
378#endif
379        wrefresh(curscr);
380        return;
381    }
382#endif
383
384    /* Fallback */
385    dp->resize.w = dp->cv->width;
386    dp->resize.h = dp->cv->height;
387}
388
389static int ncurses_get_event(caca_display_t *dp, caca_privevent_t *ev)
390{
391    int intkey;
392
393    intkey = getch();
394    if(intkey == ERR)
395    {
396        ev->type = CACA_EVENT_NONE;
397        return 0;
398    }
399
400    if(intkey < 0x7f)
401    {
402        ev->type = CACA_EVENT_KEY_PRESS;
403        ev->data.key.ch = intkey;
404        ev->data.key.utf32 = intkey;
405        ev->data.key.utf8[0] = intkey;
406        ev->data.key.utf8[1] = '\0';
407        return 1;
408    }
409
410    /* If the key was UTF-8, parse the whole sequence */
411    if(intkey >= 0x80 && intkey < 0x100)
412    {
413        int keys[7]; /* Necessary for ungetch(); */
414        char utf8[7];
415        uint32_t utf32;
416        unsigned int i, bytes = 0;
417
418        keys[0] = intkey;
419        utf8[0] = intkey;
420
421        for(i = 1; i < 6; i++)
422        {
423            keys[i] = getch();
424            utf8[i] = (unsigned char)keys[i];
425        }
426
427        utf8[i] = '\0';
428        utf32 = cucul_utf8_to_utf32(utf8, &bytes);
429
430        while(i > bytes)
431            ungetch(keys[--i]);
432
433        if(bytes)
434        {
435            ev->type = CACA_EVENT_KEY_PRESS;
436            ev->data.key.ch = 0;
437            ev->data.key.utf32 = utf32;
438            strcpy(ev->data.key.utf8, utf8);
439            return 1;
440        }
441    }
442
443    if(intkey == KEY_MOUSE)
444    {
445        MEVENT mevent;
446        getmouse(&mevent);
447
448        switch(mevent.bstate)
449        {
450#define PRESS(x) ev->data.mouse.button = x; \
451                 ev->type = CACA_EVENT_MOUSE_PRESS; _push_event(dp, ev)
452#define RELEASE(x) ev->data.mouse.button = x; \
453                   ev->type = CACA_EVENT_MOUSE_RELEASE; _push_event(dp, ev)
454#define CLICK(x) PRESS(x); RELEASE(x)
455            case BUTTON1_PRESSED: PRESS(1); break;
456            case BUTTON1_RELEASED: RELEASE(1); break;
457            case BUTTON1_CLICKED: CLICK(1); break;
458            case BUTTON1_DOUBLE_CLICKED: CLICK(1); CLICK(1); break;
459            case BUTTON1_TRIPLE_CLICKED: CLICK(1); CLICK(1); CLICK(1); break;
460            case BUTTON1_RESERVED_EVENT: break;
461
462            case BUTTON2_PRESSED: PRESS(2); break;
463            case BUTTON2_RELEASED: RELEASE(2); break;
464            case BUTTON2_CLICKED: CLICK(2); break;
465            case BUTTON2_DOUBLE_CLICKED: CLICK(2); CLICK(2); break;
466            case BUTTON2_TRIPLE_CLICKED: CLICK(2); CLICK(2); CLICK(2); break;
467            case BUTTON2_RESERVED_EVENT: break;
468
469            case BUTTON3_PRESSED: PRESS(3); break;
470            case BUTTON3_RELEASED: RELEASE(3); break;
471            case BUTTON3_CLICKED: CLICK(3); break;
472            case BUTTON3_DOUBLE_CLICKED: CLICK(3); CLICK(3); break;
473            case BUTTON3_TRIPLE_CLICKED: CLICK(3); CLICK(3); CLICK(3); break;
474            case BUTTON3_RESERVED_EVENT: break;
475
476            case BUTTON4_PRESSED: PRESS(4); break;
477            case BUTTON4_RELEASED: RELEASE(4); break;
478            case BUTTON4_CLICKED: CLICK(4); break;
479            case BUTTON4_DOUBLE_CLICKED: CLICK(4); CLICK(4); break;
480            case BUTTON4_TRIPLE_CLICKED: CLICK(4); CLICK(4); CLICK(4); break;
481            case BUTTON4_RESERVED_EVENT: break;
482
483            default:
484                break;
485#undef PRESS
486#undef RELEASE
487#undef CLICK
488        }
489
490        if(dp->mouse.x == (unsigned int)mevent.x &&
491           dp->mouse.y == (unsigned int)mevent.y)
492            return _pop_event(dp, ev);
493
494        dp->mouse.x = mevent.x;
495        dp->mouse.y = mevent.y;
496
497        ev->type = CACA_EVENT_MOUSE_MOTION;
498        ev->data.mouse.x = dp->mouse.x;
499        ev->data.mouse.y = dp->mouse.y;
500        return 1;
501    }
502
503    switch(intkey)
504    {
505        case KEY_UP: ev->data.key.ch = CACA_KEY_UP; break;
506        case KEY_DOWN: ev->data.key.ch = CACA_KEY_DOWN; break;
507        case KEY_LEFT: ev->data.key.ch = CACA_KEY_LEFT; break;
508        case KEY_RIGHT: ev->data.key.ch = CACA_KEY_RIGHT; break;
509
510        case KEY_IC: ev->data.key.ch = CACA_KEY_INSERT; break;
511        case KEY_DC: ev->data.key.ch = CACA_KEY_DELETE; break;
512        case 0x7f:
513        case KEY_BACKSPACE: ev->data.key.ch = CACA_KEY_BACKSPACE; break;
514        case KEY_HOME: ev->data.key.ch = CACA_KEY_HOME; break;
515        case KEY_END: ev->data.key.ch = CACA_KEY_END; break;
516        case KEY_PPAGE: ev->data.key.ch = CACA_KEY_PAGEUP; break;
517        case KEY_NPAGE: ev->data.key.ch = CACA_KEY_PAGEDOWN; break;
518
519        case KEY_F(1): ev->data.key.ch = CACA_KEY_F1; break;
520        case KEY_F(2): ev->data.key.ch = CACA_KEY_F2; break;
521        case KEY_F(3): ev->data.key.ch = CACA_KEY_F3; break;
522        case KEY_F(4): ev->data.key.ch = CACA_KEY_F4; break;
523        case KEY_F(5): ev->data.key.ch = CACA_KEY_F5; break;
524        case KEY_F(6): ev->data.key.ch = CACA_KEY_F6; break;
525        case KEY_F(7): ev->data.key.ch = CACA_KEY_F7; break;
526        case KEY_F(8): ev->data.key.ch = CACA_KEY_F8; break;
527        case KEY_F(9): ev->data.key.ch = CACA_KEY_F9; break;
528        case KEY_F(10): ev->data.key.ch = CACA_KEY_F10; break;
529        case KEY_F(11): ev->data.key.ch = CACA_KEY_F11; break;
530        case KEY_F(12): ev->data.key.ch = CACA_KEY_F12; break;
531
532        default:
533            /* Unknown key */
534            ev->type = CACA_EVENT_NONE; return 0;
535    }
536
537    ev->type = CACA_EVENT_KEY_PRESS;
538    ev->data.key.utf32 = 0;
539    ev->data.key.utf8[0] = '\0';
540    return 1;
541}
542
543static void ncurses_set_cursor(caca_display_t *dp, int flags)
544{
545    curs_set(flags ? 2 : 0);
546}
547
548/*
549 * XXX: following functions are local
550 */
551
552#if defined HAVE_SIGNAL
553static RETSIGTYPE sigwinch_handler(int sig)
554{
555    sigwinch_d->resize.resized = 1;
556
557    signal(SIGWINCH, sigwinch_handler);
558}
559#endif
560
561#if defined HAVE_GETENV && defined HAVE_PUTENV
562static void ncurses_check_terminal(void)
563{
564    char *term, *colorterm;
565
566    term = getenv("TERM");
567    colorterm = getenv("COLORTERM");
568
569    if(!term || strcmp(term, "xterm"))
570        return;
571
572    /* If we are using gnome-terminal, it's really a 16 colour terminal.
573     * Ditto if we are using xfce4-terminal, or Konsole. */
574    if((colorterm && (!strcmp(colorterm, "gnome-terminal")
575                       || !strcmp(colorterm, "Terminal")))
576         || getenv("KONSOLE_DCOP_SESSION"))
577    {
578        SCREEN *screen;
579        screen = newterm("xterm-16color", stdout, stdin);
580        if(screen == NULL)
581            return;
582        endwin();
583        (void)putenv("TERM=xterm-16color");
584        return;
585    }
586}
587#endif
588
589static void ncurses_write_utf32(uint32_t ch)
590{
591#if defined HAVE_NCURSESW_NCURSES_H
592    char buf[10];
593    int bytes;
594#endif
595
596    if(ch == CUCUL_MAGIC_FULLWIDTH)
597        return;
598
599#if defined HAVE_NCURSESW_NCURSES_H
600    bytes = cucul_utf32_to_utf8(buf, ch);
601    buf[bytes] = '\0';
602    addstr(buf);
603#else
604    if(ch < 0x80)
605    {
606        addch(ch);
607    }
608    else
609    {
610        chtype cch;
611        chtype cch2;
612
613        cch = '?';
614        cch2 = ' ';
615        if ((ch > 0x0000ff00) && (ch < 0x0000ff5f))
616        {
617            cch = ch - 0x0000ff00 + ' ';
618        }
619        switch (ch)
620        {
621        case 0x000000a0: /* <nbsp> */
622        case 0x00003000: /*   */
623            cch = ' ';
624            break;
625        case 0x000000a3: /* £ */
626            cch = ACS_STERLING;
627            break;
628        case 0x000000b0: /* ° */
629            cch = ACS_DEGREE;
630            break;
631        case 0x000000b1: /* ± */
632            cch = ACS_PLMINUS;
633            break;
634        case 0x000000b7: /* · */
635        case 0x00002219: /* ∙ */
636        case 0x000030fb: /* ・ */
637            cch = ACS_BULLET;
638            break;
639        case 0x000003c0: /* π */
640            cch = ACS_PI;
641            break;
642        case 0x00002018: /* ‘ */
643        case 0x00002019: /* ’ */
644            cch = '\'';
645            break;
646        case 0x0000201c: /* “ */
647        case 0x0000201d: /* ” */
648            cch = '"';
649            break;
650        case 0x00002190: /* ← */
651            cch = ACS_LARROW;
652            break;
653        case 0x00002191: /* ↑ */
654            cch = ACS_UARROW;
655            break;
656        case 0x00002192: /* → */
657            cch = ACS_RARROW;
658            break;
659        case 0x00002193: /* ↓ */
660            cch = ACS_DARROW;
661            break;
662        case 0x00002260: /* ≠ */
663            cch = ACS_NEQUAL;
664            break;
665        case 0x00002261: /* ≡ */
666            cch = '=';
667            break;
668        case 0x00002264: /* ≤ */
669            cch = ACS_LEQUAL;
670            break;
671        case 0x00002265: /* ≥ */
672            cch = ACS_GEQUAL;
673            break;
674        case 0x000023ba: /* ⎺ */
675            cch = ACS_S1;
676            cch2 = cch;
677            break;
678        case 0x000023bb: /* ⎻ */
679            cch = ACS_S3;
680            cch2 = cch;
681            break;
682        case 0x000023bc: /* ⎼ */
683            cch = ACS_S7;
684            cch2 = cch;
685            break;
686        case 0x000023bd: /* ⎽ */
687            cch = ACS_S9;
688            cch2 = cch;
689            break;
690        case 0x00002500: /* ─ */
691        case 0x00002550: /* ═ */
692            cch = ACS_HLINE;
693            cch2 = cch;
694            break;
695        case 0x00002502: /* │ */
696        case 0x00002551: /* ║ */
697            cch = ACS_VLINE;
698            break;
699        case 0x0000250c: /* ┌ */
700        case 0x00002552: /* ╒ */
701        case 0x00002553: /* ╓ */
702        case 0x00002554: /* ╔ */
703            cch = ACS_ULCORNER;
704            cch2 = ACS_HLINE;
705            break;
706        case 0x00002510: /* ┐ */
707        case 0x00002555: /* ╕ */
708        case 0x00002556: /* ╖ */
709        case 0x00002557: /* ╗ */
710            cch = ACS_URCORNER;
711            break;
712        case 0x00002514: /* └ */
713        case 0x00002558: /* ╘ */
714        case 0x00002559: /* ╙ */
715        case 0x0000255a: /* ╚ */
716            cch = ACS_LLCORNER;
717            cch2 = ACS_HLINE;
718            break;
719        case 0x00002518: /* ┘ */
720        case 0x0000255b: /* ╛ */
721        case 0x0000255c: /* ╜ */
722        case 0x0000255d: /* ╝ */
723            cch = ACS_LRCORNER;
724            break;
725        case 0x0000251c: /* ├ */
726        case 0x0000255e: /* ╞ */
727        case 0x0000255f: /* ╟ */
728        case 0x00002560: /* ╠ */
729            cch = ACS_LTEE;
730            cch2 = ACS_HLINE;
731            break;
732        case 0x00002524: /* ┤ */
733        case 0x00002561: /* ╡ */
734        case 0x00002562: /* ╢ */
735        case 0x00002563: /* ╣ */
736            cch = ACS_RTEE;
737            break;
738        case 0x0000252c: /* ┬ */
739        case 0x00002564: /* ╤ */
740        case 0x00002565: /* ╥ */
741        case 0x00002566: /* ╦ */
742            cch = ACS_TTEE;
743            cch2 = ACS_HLINE;
744            break;
745        case 0x00002534: /* ┴ */
746        case 0x00002567: /* ╧ */
747        case 0x00002568: /* ╨ */
748        case 0x00002569: /* ╩ */
749            cch = ACS_BTEE;
750            cch2 = ACS_HLINE;
751            break;
752        case 0x0000253c: /* ┼ */
753        case 0x0000256a: /* ╪ */
754        case 0x0000256b: /* ╫ */
755        case 0x0000256c: /* ╬ */
756            cch = ACS_PLUS;
757            cch2 = ACS_HLINE;
758            break;
759        case 0x00002591: /* ░ */
760            cch = ACS_BOARD;
761            cch2 = cch;
762            break;
763        case 0x00002592: /* ▒ */
764        case 0x00002593: /* ▓ */
765            cch = ACS_CKBOARD;
766            cch2 = cch;
767            break;
768        case 0x00002580: /* ▀ */
769        case 0x00002584: /* ▄ */
770        case 0x00002588: /* █ */
771        case 0x0000258c: /* ▌ */
772        case 0x00002590: /* ▐ */
773        case 0x000025a0: /* ■ */
774        case 0x000025ac: /* ▬ */
775        case 0x000025ae: /* ▮ */
776            cch = ACS_BLOCK;
777            cch2 = cch;
778            break;
779        case 0x000025c6: /* ◆ */
780        case 0x00002666: /* ♦ */
781            cch = ACS_DIAMOND;
782            break;
783        case 0x00002022: /* • */
784        case 0x000025cb: /* ○ */
785        case 0x000025cf: /* ● */
786        case 0x00002603: /* ☃ */
787        case 0x0000263c: /* ☼ */
788            cch = ACS_LANTERN;
789            break;
790        case 0x0000301c: /* 〜 */
791            cch = '~';
792            break;
793        }
794        addch(cch);
795        if(cucul_utf32_is_fullwidth(ch))
796        {
797            addch(cch2);
798        }
799    }
800#endif
801}
802
803/*
804 * Driver initialisation
805 */
806
807int ncurses_install(caca_display_t *dp)
808{
809    dp->drv.driver = CACA_DRIVER_NCURSES;
810
811    dp->drv.init_graphics = ncurses_init_graphics;
812    dp->drv.end_graphics = ncurses_end_graphics;
813    dp->drv.set_display_title = ncurses_set_display_title;
814    dp->drv.get_display_width = ncurses_get_display_width;
815    dp->drv.get_display_height = ncurses_get_display_height;
816    dp->drv.display = ncurses_display;
817    dp->drv.handle_resize = ncurses_handle_resize;
818    dp->drv.get_event = ncurses_get_event;
819    dp->drv.set_mouse = NULL;
820    dp->drv.set_cursor = ncurses_set_cursor;
821
822    return 0;
823}
824
825#endif /* USE_NCURSES */
826
Note: See TracBrowser for help on using the repository browser.