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

Last change on this file since 1837 was 1837, checked in by Sam Hocevar, 13 years ago
  • Implemented caca_set_cursor() on the X11, ncurses and S-Lang drivers.
  • Use caca_set_cursor() in test/input.c.
  • Property svn:keywords set to Id
File size: 20.0 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 1837 2007-10-19 22:22:13Z 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_SIGNAL_H
39#   include <signal.h>
40#endif
41#if defined HAVE_SYS_IOCTL_H
42#   include <sys/ioctl.h>
43#endif
44#if defined HAVE_LOCALE_H
45#   include <locale.h>
46#endif
47
48#ifndef TIOCGWINSZ
49#   include <termios.h>
50#endif
51
52#include "caca.h"
53#include "caca_internals.h"
54#include "cucul.h"
55#include "cucul_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_check_terminal(void);
199#endif
200static void ncurses_write_utf32(uint32_t);
201
202struct driver_private
203{
204    int attr[16*16];
205    mmask_t oldmask;
206};
207
208static int ncurses_init_graphics(caca_display_t *dp)
209{
210    static int curses_colors[] =
211    {
212        /* Standard curses colours */
213        COLOR_BLACK,
214        COLOR_BLUE,
215        COLOR_GREEN,
216        COLOR_CYAN,
217        COLOR_RED,
218        COLOR_MAGENTA,
219        COLOR_YELLOW,
220        COLOR_WHITE,
221        /* Extra values for xterm-16color */
222        COLOR_BLACK + 8,
223        COLOR_BLUE + 8,
224        COLOR_GREEN + 8,
225        COLOR_CYAN + 8,
226        COLOR_RED + 8,
227        COLOR_MAGENTA + 8,
228        COLOR_YELLOW + 8,
229        COLOR_WHITE + 8
230    };
231
232    mmask_t newmask;
233    int fg, bg, max;
234
235    dp->drv.p = malloc(sizeof(struct driver_private));
236
237#if defined HAVE_GETENV && defined HAVE_PUTENV
238    ncurses_check_terminal();
239#endif
240
241#if defined HAVE_SIGNAL
242    sigwinch_d = dp;
243    signal(SIGWINCH, sigwinch_handler);
244#endif
245
246#if defined HAVE_LOCALE_H
247    setlocale(LC_ALL, "");
248#endif
249
250    _caca_set_term_title("caca for ncurses");
251
252    initscr();
253    keypad(stdscr, TRUE);
254    nonl();
255    raw();
256    noecho();
257    nodelay(stdscr, TRUE);
258    curs_set(0);
259
260    /* Activate mouse */
261    newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS;
262    mousemask(newmask, &dp->drv.p->oldmask);
263    mouseinterval(-1); /* No click emulation */
264
265    /* Set the escape delay to a ridiculously low value */
266    ESCDELAY = 10;
267
268    /* Activate colour */
269    start_color();
270
271    /* If COLORS == 16, it means the terminal supports full bright colours
272     * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8),
273     * we can build 16*16 colour pairs.
274     * If COLORS == 8, it means the terminal does not know about bright
275     * colours and we need to get them through A_BOLD and A_BLINK (\e[1m
276     * and \e[5m). We can only build 8*8 colour pairs. */
277    max = COLORS >= 16 ? 16 : 8;
278
279    for(bg = 0; bg < max; bg++)
280        for(fg = 0; fg < max; fg++)
281        {
282            /* Use ((max + 7 - fg) % max) instead of fg so that colour 0
283             * is light gray on black. Some terminals don't like this
284             * colour pair to be redefined. */
285            int col = ((max + 7 - fg) % max) + max * bg;
286            init_pair(col, curses_colors[fg], curses_colors[bg]);
287            dp->drv.p->attr[fg + 16 * bg] = COLOR_PAIR(col);
288
289            if(max == 8)
290            {
291                /* Bright fg on simple bg */
292                dp->drv.p->attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
293                /* Simple fg on bright bg */
294                dp->drv.p->attr[fg + 16 * (bg + 8)] = A_BLINK
295                                                    | COLOR_PAIR(col);
296                /* Bright fg on bright bg */
297                dp->drv.p->attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD
298                                                        | COLOR_PAIR(col);
299            }
300        }
301
302    _cucul_set_canvas_size(dp->cv, COLS, LINES);
303
304    return 0;
305}
306
307static int ncurses_end_graphics(caca_display_t *dp)
308{
309    _caca_set_term_title("");
310    mousemask(dp->drv.p->oldmask, NULL);
311    curs_set(1);
312    noraw();
313    endwin();
314
315    free(dp->drv.p);
316
317    return 0;
318}
319
320static int ncurses_set_display_title(caca_display_t *dp, char const *title)
321{
322    _caca_set_term_title(title);
323
324    return 0;
325}
326
327static unsigned int ncurses_get_display_width(caca_display_t *dp)
328{
329    /* Fallback to a 6x10 font */
330    return dp->cv->width * 6;
331}
332
333static unsigned int ncurses_get_display_height(caca_display_t *dp)
334{
335    /* Fallback to a 6x10 font */
336    return dp->cv->height * 10;
337}
338
339static void ncurses_display(caca_display_t *dp)
340{
341    int x, y;
342    uint32_t *attrs = dp->cv->attrs;
343    uint32_t *chars = dp->cv->chars;
344    for(y = 0; y < (int)dp->cv->height; y++)
345    {
346        move(y, 0);
347        for(x = dp->cv->width; x--; )
348        {
349            attrset(dp->drv.p->attr[cucul_attr_to_ansi(*attrs++)]);
350            ncurses_write_utf32(*chars++);
351        }
352    }
353   
354    x = cucul_get_cursor_x(dp->cv);
355    y = cucul_get_cursor_y(dp->cv);
356    move(y, x);
357
358    refresh();
359}
360
361static void ncurses_handle_resize(caca_display_t *dp)
362{
363    struct winsize size;
364
365#if defined HAVE_SYS_IOCTL_H
366    if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0)
367    {
368        dp->resize.w = size.ws_col;
369        dp->resize.h = size.ws_row;
370#if defined HAVE_RESIZE_TERM
371        resize_term(dp->resize.h, dp->resize.w);
372#else
373        resizeterm(dp->resize.h, dp->resize.w);
374#endif
375        wrefresh(curscr);
376        return;
377    }
378#endif
379
380    /* Fallback */
381    dp->resize.w = dp->cv->width;
382    dp->resize.h = dp->cv->height;
383}
384
385static int ncurses_get_event(caca_display_t *dp, caca_event_t *ev)
386{
387    int intkey;
388
389    intkey = getch();
390    if(intkey == ERR)
391    {
392        ev->type = CACA_EVENT_NONE;
393        return 0;
394    }
395
396    if(intkey < 0x7f)
397    {
398        ev->type = CACA_EVENT_KEY_PRESS;
399        ev->data.key.ch = intkey;
400        ev->data.key.utf32 = intkey;
401        ev->data.key.utf8[0] = intkey;
402        ev->data.key.utf8[1] = '\0';
403        return 1;
404    }
405
406    /* If the key was UTF-8, parse the whole sequence */
407    if(intkey >= 0x80 && intkey < 0x100)
408    {
409        int keys[7]; /* Necessary for ungetch(); */
410        char utf8[7];
411        uint32_t utf32;
412        unsigned int i, bytes = 0;
413
414        keys[0] = intkey;
415        utf8[0] = intkey;
416
417        for(i = 1; i < 6; i++)
418        {
419            keys[i] = getch();
420            utf8[i] = (unsigned char)keys[i];
421        }
422
423        utf8[i] = '\0';
424        utf32 = cucul_utf8_to_utf32(utf8, &bytes);
425
426        while(i > bytes)
427            ungetch(keys[--i]);
428
429        if(bytes)
430        {
431            ev->type = CACA_EVENT_KEY_PRESS;
432            ev->data.key.ch = 0;
433            ev->data.key.utf32 = utf32;
434            strcpy(ev->data.key.utf8, utf8);
435            return 1;
436        }
437    }
438
439    if(intkey == KEY_MOUSE)
440    {
441        MEVENT mevent;
442        getmouse(&mevent);
443
444        switch(mevent.bstate)
445        {
446#define PRESS(x) ev->data.mouse.button = x; \
447                 ev->type = CACA_EVENT_MOUSE_PRESS; _push_event(dp, ev)
448#define RELEASE(x) ev->data.mouse.button = x; \
449                   ev->type = CACA_EVENT_MOUSE_RELEASE; _push_event(dp, ev)
450#define CLICK(x) PRESS(x); RELEASE(x)
451            case BUTTON1_PRESSED: PRESS(1); break;
452            case BUTTON1_RELEASED: RELEASE(1); break;
453            case BUTTON1_CLICKED: CLICK(1); break;
454            case BUTTON1_DOUBLE_CLICKED: CLICK(1); CLICK(1); break;
455            case BUTTON1_TRIPLE_CLICKED: CLICK(1); CLICK(1); CLICK(1); break;
456            case BUTTON1_RESERVED_EVENT: break;
457
458            case BUTTON2_PRESSED: PRESS(2); break;
459            case BUTTON2_RELEASED: RELEASE(2); break;
460            case BUTTON2_CLICKED: CLICK(2); break;
461            case BUTTON2_DOUBLE_CLICKED: CLICK(2); CLICK(2); break;
462            case BUTTON2_TRIPLE_CLICKED: CLICK(2); CLICK(2); CLICK(2); break;
463            case BUTTON2_RESERVED_EVENT: break;
464
465            case BUTTON3_PRESSED: PRESS(3); break;
466            case BUTTON3_RELEASED: RELEASE(3); break;
467            case BUTTON3_CLICKED: CLICK(3); break;
468            case BUTTON3_DOUBLE_CLICKED: CLICK(3); CLICK(3); break;
469            case BUTTON3_TRIPLE_CLICKED: CLICK(3); CLICK(3); CLICK(3); break;
470            case BUTTON3_RESERVED_EVENT: break;
471
472            case BUTTON4_PRESSED: PRESS(4); break;
473            case BUTTON4_RELEASED: RELEASE(4); break;
474            case BUTTON4_CLICKED: CLICK(4); break;
475            case BUTTON4_DOUBLE_CLICKED: CLICK(4); CLICK(4); break;
476            case BUTTON4_TRIPLE_CLICKED: CLICK(4); CLICK(4); CLICK(4); break;
477            case BUTTON4_RESERVED_EVENT: break;
478
479            default:
480                break;
481#undef PRESS
482#undef RELEASE
483#undef CLICK
484        }
485
486        if(dp->mouse.x == (unsigned int)mevent.x &&
487           dp->mouse.y == (unsigned int)mevent.y)
488            return _pop_event(dp, ev);
489
490        dp->mouse.x = mevent.x;
491        dp->mouse.y = mevent.y;
492
493        ev->type = CACA_EVENT_MOUSE_MOTION;
494        ev->data.mouse.x = dp->mouse.x;
495        ev->data.mouse.y = dp->mouse.y;
496        return 1;
497    }
498
499    switch(intkey)
500    {
501        case KEY_UP: ev->data.key.ch = CACA_KEY_UP; break;
502        case KEY_DOWN: ev->data.key.ch = CACA_KEY_DOWN; break;
503        case KEY_LEFT: ev->data.key.ch = CACA_KEY_LEFT; break;
504        case KEY_RIGHT: ev->data.key.ch = CACA_KEY_RIGHT; break;
505
506        case KEY_IC: ev->data.key.ch = CACA_KEY_INSERT; break;
507        case KEY_DC: ev->data.key.ch = CACA_KEY_DELETE; break;
508        case 0x7f:
509        case KEY_BACKSPACE: ev->data.key.ch = CACA_KEY_BACKSPACE; break;
510        case KEY_HOME: ev->data.key.ch = CACA_KEY_HOME; break;
511        case KEY_END: ev->data.key.ch = CACA_KEY_END; break;
512        case KEY_PPAGE: ev->data.key.ch = CACA_KEY_PAGEUP; break;
513        case KEY_NPAGE: ev->data.key.ch = CACA_KEY_PAGEDOWN; break;
514
515        case KEY_F(1): ev->data.key.ch = CACA_KEY_F1; break;
516        case KEY_F(2): ev->data.key.ch = CACA_KEY_F2; break;
517        case KEY_F(3): ev->data.key.ch = CACA_KEY_F3; break;
518        case KEY_F(4): ev->data.key.ch = CACA_KEY_F4; break;
519        case KEY_F(5): ev->data.key.ch = CACA_KEY_F5; break;
520        case KEY_F(6): ev->data.key.ch = CACA_KEY_F6; break;
521        case KEY_F(7): ev->data.key.ch = CACA_KEY_F7; break;
522        case KEY_F(8): ev->data.key.ch = CACA_KEY_F8; break;
523        case KEY_F(9): ev->data.key.ch = CACA_KEY_F9; break;
524        case KEY_F(10): ev->data.key.ch = CACA_KEY_F10; break;
525        case KEY_F(11): ev->data.key.ch = CACA_KEY_F11; break;
526        case KEY_F(12): ev->data.key.ch = CACA_KEY_F12; break;
527
528        default:
529            /* Unknown key */
530            ev->type = CACA_EVENT_NONE; return 0;
531    }
532
533    ev->type = CACA_EVENT_KEY_PRESS;
534    ev->data.key.utf32 = 0;
535    ev->data.key.utf8[0] = '\0';
536    return 1;
537}
538
539static void ncurses_set_cursor(caca_display_t *dp, int flags)
540{
541    curs_set(flags ? 2 : 0);
542}
543
544/*
545 * XXX: following functions are local
546 */
547
548#if defined HAVE_SIGNAL
549static RETSIGTYPE sigwinch_handler(int sig)
550{
551    sigwinch_d->resize.resized = 1;
552
553    signal(SIGWINCH, sigwinch_handler);
554}
555#endif
556
557#if defined HAVE_GETENV && defined HAVE_PUTENV
558static void ncurses_check_terminal(void)
559{
560    char *term, *colorterm;
561
562    term = getenv("TERM");
563    colorterm = getenv("COLORTERM");
564
565    if(!term || strcmp(term, "xterm"))
566        return;
567
568    /* If we are using gnome-terminal, it's really a 16 colour terminal.
569     * Ditto if we are using xfce4-terminal, or Konsole. */
570    if((colorterm && (!strcmp(colorterm, "gnome-terminal")
571                       || !strcmp(colorterm, "Terminal")))
572         || getenv("KONSOLE_DCOP_SESSION"))
573    {
574        SCREEN *screen;
575        screen = newterm("xterm-16color", stdout, stdin);
576        if(screen == NULL)
577            return;
578        endwin();
579        (void)putenv("TERM=xterm-16color");
580        return;
581    }
582}
583#endif
584
585static void ncurses_write_utf32(uint32_t ch)
586{
587#if defined HAVE_NCURSESW_NCURSES_H
588    char buf[10];
589    int bytes;
590#endif
591
592    if(ch == CUCUL_MAGIC_FULLWIDTH)
593        return;
594
595#if defined HAVE_NCURSESW_NCURSES_H
596    bytes = cucul_utf32_to_utf8(buf, ch);
597    buf[bytes] = '\0';
598    addstr(buf);
599#else
600    if(ch < 0x80)
601    {
602        addch(ch);
603    }
604    else
605    {
606        chtype cch;
607        chtype cch2;
608
609        cch = '?';
610        cch2 = ' ';
611        if ((ch > 0x0000ff00) && (ch < 0x0000ff5f))
612        {
613            cch = ch - 0x0000ff00 + ' ';
614        }
615        switch (ch)
616        {
617        case 0x000000a0: /* <nbsp> */
618        case 0x00003000: /*   */
619            cch = ' ';
620            break;
621        case 0x000000a3: /* £ */
622            cch = ACS_STERLING;
623            break;
624        case 0x000000b0: /* ° */
625            cch = ACS_DEGREE;
626            break;
627        case 0x000000b1: /* ± */
628            cch = ACS_PLMINUS;
629            break;
630        case 0x000000b7: /* · */
631        case 0x00002219: /* ∙ */
632        case 0x000030fb: /* ・ */
633            cch = ACS_BULLET;
634            break;
635        case 0x000003c0: /* π */
636            cch = ACS_PI;
637            break;
638        case 0x00002018: /* ‘ */
639        case 0x00002019: /* ’ */
640            cch = '\'';
641            break;
642        case 0x0000201c: /* “ */
643        case 0x0000201d: /* ” */
644            cch = '"';
645            break;
646        case 0x00002190: /* ← */
647            cch = ACS_LARROW;
648            break;
649        case 0x00002191: /* ↑ */
650            cch = ACS_UARROW;
651            break;
652        case 0x00002192: /* → */
653            cch = ACS_RARROW;
654            break;
655        case 0x00002193: /* ↓ */
656            cch = ACS_DARROW;
657            break;
658        case 0x00002260: /* ≠ */
659            cch = ACS_NEQUAL;
660            break;
661        case 0x00002261: /* ≡ */
662            cch = '=';
663            break;
664        case 0x00002264: /* ≤ */
665            cch = ACS_LEQUAL;
666            break;
667        case 0x00002265: /* ≥ */
668            cch = ACS_GEQUAL;
669            break;
670        case 0x000023ba: /* ⎺ */
671            cch = ACS_S1;
672            cch2 = cch;
673            break;
674        case 0x000023bb: /* ⎻ */
675            cch = ACS_S3;
676            cch2 = cch;
677            break;
678        case 0x000023bc: /* ⎼ */
679            cch = ACS_S7;
680            cch2 = cch;
681            break;
682        case 0x000023bd: /* ⎽ */
683            cch = ACS_S9;
684            cch2 = cch;
685            break;
686        case 0x00002500: /* ─ */
687        case 0x00002550: /* ═ */
688            cch = ACS_HLINE;
689            cch2 = cch;
690            break;
691        case 0x00002502: /* │ */
692        case 0x00002551: /* ║ */
693            cch = ACS_VLINE;
694            break;
695        case 0x0000250c: /* ┌ */
696        case 0x00002552: /* ╒ */
697        case 0x00002553: /* ╓ */
698        case 0x00002554: /* ╔ */
699            cch = ACS_ULCORNER;
700            cch2 = ACS_HLINE;
701            break;
702        case 0x00002510: /* ┐ */
703        case 0x00002555: /* ╕ */
704        case 0x00002556: /* ╖ */
705        case 0x00002557: /* ╗ */
706            cch = ACS_URCORNER;
707            break;
708        case 0x00002514: /* └ */
709        case 0x00002558: /* ╘ */
710        case 0x00002559: /* ╙ */
711        case 0x0000255a: /* ╚ */
712            cch = ACS_LLCORNER;
713            cch2 = ACS_HLINE;
714            break;
715        case 0x00002518: /* ┘ */
716        case 0x0000255b: /* ╛ */
717        case 0x0000255c: /* ╜ */
718        case 0x0000255d: /* ╝ */
719            cch = ACS_LRCORNER;
720            break;
721        case 0x0000251c: /* ├ */
722        case 0x0000255e: /* ╞ */
723        case 0x0000255f: /* ╟ */
724        case 0x00002560: /* ╠ */
725            cch = ACS_LTEE;
726            cch2 = ACS_HLINE;
727            break;
728        case 0x00002524: /* ┤ */
729        case 0x00002561: /* ╡ */
730        case 0x00002562: /* ╢ */
731        case 0x00002563: /* ╣ */
732            cch = ACS_RTEE;
733            break;
734        case 0x0000252c: /* ┬ */
735        case 0x00002564: /* ╤ */
736        case 0x00002565: /* ╥ */
737        case 0x00002566: /* ╦ */
738            cch = ACS_TTEE;
739            cch2 = ACS_HLINE;
740            break;
741        case 0x00002534: /* ┴ */
742        case 0x00002567: /* ╧ */
743        case 0x00002568: /* ╨ */
744        case 0x00002569: /* ╩ */
745            cch = ACS_BTEE;
746            cch2 = ACS_HLINE;
747            break;
748        case 0x0000253c: /* ┼ */
749        case 0x0000256a: /* ╪ */
750        case 0x0000256b: /* ╫ */
751        case 0x0000256c: /* ╬ */
752            cch = ACS_PLUS;
753            cch2 = ACS_HLINE;
754            break;
755        case 0x00002591: /* ░ */
756            cch = ACS_BOARD;
757            cch2 = cch;
758            break;
759        case 0x00002592: /* ▒ */
760        case 0x00002593: /* ▓ */
761            cch = ACS_CKBOARD;
762            cch2 = cch;
763            break;
764        case 0x00002580: /* ▀ */
765        case 0x00002584: /* ▄ */
766        case 0x00002588: /* █ */
767        case 0x0000258c: /* ▌ */
768        case 0x00002590: /* ▐ */
769        case 0x000025a0: /* ■ */
770        case 0x000025ac: /* ▬ */
771        case 0x000025ae: /* ▮ */
772            cch = ACS_BLOCK;
773            cch2 = cch;
774            break;
775        case 0x000025c6: /* ◆ */
776        case 0x00002666: /* ♦ */
777            cch = ACS_DIAMOND;
778            break;
779        case 0x00002022: /* • */
780        case 0x000025cb: /* ○ */
781        case 0x000025cf: /* ● */
782        case 0x00002603: /* ☃ */
783        case 0x0000263c: /* ☼ */
784            cch = ACS_LANTERN;
785            break;
786        case 0x0000301c: /* 〜 */
787            cch = '~';
788            break;
789        }
790        addch(cch);
791        if(cucul_utf32_is_fullwidth(ch))
792        {
793            addch(cch2);
794        }
795    }
796#endif
797}
798
799/*
800 * Driver initialisation
801 */
802
803int ncurses_install(caca_display_t *dp)
804{
805    dp->drv.driver = CACA_DRIVER_NCURSES;
806
807    dp->drv.init_graphics = ncurses_init_graphics;
808    dp->drv.end_graphics = ncurses_end_graphics;
809    dp->drv.set_display_title = ncurses_set_display_title;
810    dp->drv.get_display_width = ncurses_get_display_width;
811    dp->drv.get_display_height = ncurses_get_display_height;
812    dp->drv.display = ncurses_display;
813    dp->drv.handle_resize = ncurses_handle_resize;
814    dp->drv.get_event = ncurses_get_event;
815    dp->drv.set_mouse = NULL;
816    dp->drv.set_cursor = ncurses_set_cursor;
817
818    return 0;
819}
820
821#endif /* USE_NCURSES */
822
Note: See TracBrowser for help on using the repository browser.