diff --git a/configure.ac b/configure.ac index fdcde9f..5241203 100644 --- a/configure.ac +++ b/configure.ac @@ -37,13 +37,17 @@ if test "${enable_conio}" = "yes"; then AC_DEFINE(SCREENUPDATE_IN_PC_H, 1, Define if defines ScreenUpdate.)],[ AC_MSG_RESULT(no)]) - AC_DEFINE(USE_CONIO, 1, Define if the backend driver is conio.h) -elif test "${enable_slang}" = "yes"; then + AC_DEFINE(USE_CONIO, 1, Define to activate the conio.h backend driver) +fi + +if test "${enable_slang}" = "yes"; then AC_CHECK_HEADERS(slang.h,:,AC_MSG_ERROR([cannot find slang headers])) AC_CHECK_LIB(slang,SLkp_init,:,AC_MSG_ERROR([cannot find slang library])) - AC_DEFINE(USE_SLANG, 1, Define if the backend driver is slang) + AC_DEFINE(USE_SLANG, 1, Define to activate the slang backend driver) CACA_LIBS="${CACA_LIBS} -lslang" -elif test "${enable_x11}" = "yes"; then +fi + +if test "${enable_x11}" = "yes"; then AC_PATH_X AC_CHECK_LIB(X11, XOpenDisplay, [ac_cv_my_have_x11=yes @@ -54,16 +58,16 @@ elif test "${enable_x11}" = "yes"; then if test "${ac_cv_my_have_x11}" != "yes"; then AC_MSG_ERROR([cannot find X11 development files]) fi - AC_DEFINE(USE_X11, 1, Define if the backend driver is X11) + AC_DEFINE(USE_X11, 1, Define to activate the X11 backend driver) CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}" CACA_LIBS="${CACA_LIBS} ${X_LIBS}" -elif test "${enable_ncurses}" != "no"; then +fi + +if test "${enable_ncurses}" != "no"; then AC_CHECK_HEADERS(ncurses.h,:,AC_MSG_ERROR([cannot find ncurses headers])) AC_CHECK_LIB(ncurses,initscr,:,AC_MSG_ERROR([cannot find ncurses library])) - AC_DEFINE(USE_NCURSES, 1, Define if the backend driver is ncurses) + AC_DEFINE(USE_NCURSES, 1, Define to activate the ncurses backend driver) CACA_LIBS="${CACA_LIBS} -lncurses" -else - AC_MSG_ERROR([could not find any terminal graphics interface]) fi AC_SUBST(CACA_LIBS) diff --git a/src/bitmap.c b/src/bitmap.c index 1b09c4b..1fa6cd2 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -29,7 +29,7 @@ #include "config.h" -#ifdef HAVE_INTTYPES_H +#if defined(HAVE_INTTYPES_H) # include #else typedef unsigned char uint8_t; @@ -37,7 +37,7 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; #endif -#ifdef HAVE_ENDIAN_H +#if defined(HAVE_ENDIAN_H) # include #endif @@ -256,7 +256,7 @@ static void get_rgba_default(const struct caca_bitmap *bitmap, uint8_t *pixels, break; case 3: { -#ifdef HAVE_ENDIAN_H +#if defined(HAVE_ENDIAN_H) if(__BYTE_ORDER == __BIG_ENDIAN) #else /* This is compile-time optimised with at least -O1 or -Os */ diff --git a/src/caca.c b/src/caca.c index d52fed6..11ff86b 100644 --- a/src/caca.c +++ b/src/caca.c @@ -33,15 +33,16 @@ #if defined(USE_SLANG) # include -#elif defined(USE_NCURSES) +#endif +#if defined(USE_NCURSES) # include -#elif defined(USE_CONIO) +#endif +#if defined(USE_CONIO) # include # include -#elif defined(USE_X11) +#endif +#if defined(USE_X11) # include -#else -# error "no graphics library detected" #endif #include @@ -50,9 +51,12 @@ #include "caca.h" #include "caca_internals.h" +static void caca_init_driver(void); static void caca_init_features(void); static void caca_init_terminal(void); +enum caca_driver _caca_driver; + #if defined(USE_NCURSES) static mmask_t oldmask; #endif @@ -68,62 +72,81 @@ int caca_init(void) mmask_t newmask; #endif - caca_init_features(); - caca_init_terminal(); - -#if defined(USE_SLANG) - /* Initialize slang library */ - SLsig_block_signals(); - SLtt_get_terminfo(); + caca_init_driver(); - if(SLkp_init() == -1) - { - SLsig_unblock_signals(); + if(_caca_driver == CACA_DRIVER_NONE) return -1; - } - SLang_init_tty(-1, 0, 1); + caca_init_features(); + caca_init_terminal(); - if(SLsmg_init_smg() == -1) +#if defined(USE_SLANG) + if(_caca_driver == CACA_DRIVER_SLANG) { - SLsig_unblock_signals(); - return -1; - } + /* Initialise slang library */ + SLsig_block_signals(); + SLtt_get_terminfo(); - SLsig_unblock_signals(); - - SLsmg_cls(); - SLtt_set_cursor_visibility(0); - SLkp_define_keysym("\e[M", 1001); - SLtt_set_mouse_mode(1, 0); - SLsmg_refresh(); - - /* Disable scrolling so that hashmap scrolling optimization code - * does not cause ugly refreshes due to slow terminals */ - SLtt_Term_Cannot_Scroll = 1; + if(SLkp_init() == -1) + { + SLsig_unblock_signals(); + return -1; + } -#elif defined(USE_NCURSES) - initscr(); - keypad(stdscr, TRUE); - nonl(); - cbreak(); - noecho(); - nodelay(stdscr, TRUE); - curs_set(0); + SLang_init_tty(-1, 0, 1); - /* Activate mouse */ - newmask = ALL_MOUSE_EVENTS; - mousemask(newmask, &oldmask); + if(SLsmg_init_smg() == -1) + { + SLsig_unblock_signals(); + return -1; + } -#elif defined(USE_CONIO) - _wscroll = 0; - _setcursortype(_NOCURSOR); - clrscr(); + SLsig_unblock_signals(); -#elif defined(USE_X11) - /* Nothing to do */ + SLsmg_cls(); + SLtt_set_cursor_visibility(0); + SLkp_define_keysym("\e[M", 1001); + SLtt_set_mouse_mode(1, 0); + SLsmg_refresh(); + /* Disable scrolling so that hashmap scrolling optimization code + * does not cause ugly refreshes due to slow terminals */ + SLtt_Term_Cannot_Scroll = 1; + } + else +#endif +#if defined(USE_NCURSES) + if(_caca_driver == CACA_DRIVER_NCURSES) + { + initscr(); + keypad(stdscr, TRUE); + nonl(); + cbreak(); + noecho(); + nodelay(stdscr, TRUE); + curs_set(0); + + /* Activate mouse */ + newmask = ALL_MOUSE_EVENTS; + mousemask(newmask, &oldmask); + } + else +#endif +#if defined(USE_CONIO) + if(_caca_driver == CACA_DRIVER_CONIO) + { + _wscroll = 0; + _setcursortype(_NOCURSOR); + clrscr(); + } + else +#endif +#if defined(USE_X11) + { + /* Nothing to do */ + } #endif + if(_caca_init_graphics()) return -1; @@ -281,24 +304,96 @@ void caca_end(void) _caca_end_graphics(); #if defined(USE_SLANG) - SLtt_set_mouse_mode(0, 0); - SLtt_set_cursor_visibility(1); - SLang_reset_tty(); - SLsmg_reset_smg(); -#elif defined(USE_NCURSES) - mousemask(oldmask, NULL); - curs_set(1); - endwin(); -#elif defined(USE_CONIO) - _wscroll = 1; - textcolor((enum COLORS)WHITE); - textbackground((enum COLORS)BLACK); - gotoxy(_caca_width, _caca_height); - cputs("\r\n"); - _setcursortype(_NORMALCURSOR); -#elif defined(USE_X11) - /* Nothing to do */ + if(_caca_driver == CACA_DRIVER_SLANG) + { + SLtt_set_mouse_mode(0, 0); + SLtt_set_cursor_visibility(1); + SLang_reset_tty(); + SLsmg_reset_smg(); + } + else +#endif +#if defined(USE_NCURSES) + if(_caca_driver == CACA_DRIVER_NCURSES) + { + mousemask(oldmask, NULL); + curs_set(1); + endwin(); + } + else +#endif +#if defined(USE_CONIO) + if(_caca_driver == USE_CONIO) + { + _wscroll = 1; + textcolor((enum COLORS)WHITE); + textbackground((enum COLORS)BLACK); + gotoxy(_caca_width, _caca_height); + cputs("\r\n"); + _setcursortype(_NORMALCURSOR); + } + else +#endif +#if defined(USE_X11) + if(_caca_driver == USE_X11) + { + /* Nothing to do */ + } +#endif +} + +static void caca_init_driver(void) +{ +#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) + char *var = getenv("CACA_DRIVER"); + + /* If the environment variable was set, use it */ + if(var && *var) + { +#if defined(USE_CONIO) + if(!strcasecmp(var, "conio")) + _caca_driver = CACA_DRIVER_CONIO; + else +#endif +#if defined(USE_NCURSES) + if(!strcasecmp(var, "ncurses")) + _caca_driver = CACA_DRIVER_NCURSES; + else +#endif +#if defined(USE_SLANG) + if(!strcasecmp(var, "slang")) + _caca_driver = CACA_DRIVER_SLANG; + else +#endif +#if defined(USE_X11) + if(!strcasecmp(var, "x11")) + _caca_driver = CACA_DRIVER_X11; + else +#endif + _caca_driver = CACA_DRIVER_NONE; + + return; + } +#endif + +#if defined(USE_CONIO) + _caca_driver = CACA_DRIVER_CONIO; + return; +#endif +#if defined(USE_NCURSES) + _caca_driver = CACA_DRIVER_NCURSES; + return; +#endif +#if defined(USE_SLANG) + _caca_driver = CACA_DRIVER_SLANG; + return; #endif +#if defined(USE_X11) + _caca_driver = CACA_DRIVER_X11; + return; +#endif + _caca_driver = CACA_DRIVER_NONE; + return; } static void caca_init_features(void) @@ -351,6 +446,10 @@ static void caca_init_terminal(void) && (defined(USE_SLANG) || defined(USE_NCURSES)) char *term, *colorterm, *other; + if(_caca_driver != CACA_DRIVER_NCURSES && + _caca_driver != CACA_DRIVER_SLANG) + return; + term = getenv("TERM"); colorterm = getenv("COLORTERM"); @@ -360,11 +459,14 @@ static void caca_init_terminal(void) if(colorterm && !strcmp(colorterm, "gnome-terminal")) { #if defined(USE_NCURSES) - SCREEN *screen; - screen = newterm("xterm-16color", stdout, stdin); - if(screen == NULL) - return; - endwin(); + if(_caca_driver == USE_NCURSES) + { + SCREEN *screen; + screen = newterm("xterm-16color", stdout, stdin); + if(screen == NULL) + return; + endwin(); + } #endif (void)putenv("TERM=xterm-16color"); return; @@ -375,11 +477,14 @@ static void caca_init_terminal(void) if(other) { #if defined(USE_NCURSES) - SCREEN *screen; - screen = newterm("xterm-16color", stdout, stdin); - if(screen == NULL) - return; - endwin(); + if(_caca_driver == USE_NCURSES) + { + SCREEN *screen; + screen = newterm("xterm-16color", stdout, stdin); + if(screen == NULL) + return; + endwin(); + } #endif (void)putenv("TERM=xterm-16color"); return; diff --git a/src/caca.h b/src/caca.h index 16d2f4e..30504cc 100644 --- a/src/caca.h +++ b/src/caca.h @@ -55,6 +55,12 @@ * \e libcaca without having to modify the program which uses it. These * variables are: * + * \li \b CACA_DRIVER: set the backend video driver. In order of preference: + * - \c conio uses the DOS conio.h interface. + * - \c ncurses uses the ncurses library. + * - \c slang uses the S-Lang library. + * - \c x11 uses the native X11 driver. + * * \li \b CACA_BACKGROUND: set the background type. * - \c solid uses solid coloured backgrounds for all characters. This * feature does not work with all terminal emulators. This is the diff --git a/src/caca_internals.h b/src/caca_internals.h index 57491bd..b97c556 100644 --- a/src/caca_internals.h +++ b/src/caca_internals.h @@ -30,6 +30,27 @@ #ifndef __CACA_INTERNALS_H__ #define __CACA_INTERNALS_H__ +/* Graphics driver */ +enum caca_driver +{ +#if defined(USE_CONIO) + CACA_DRIVER_CONIO = 1, +#endif +#if defined(USE_NCURSES) + CACA_DRIVER_NCURSES = 2, +#endif +#if defined(USE_SLANG) + CACA_DRIVER_SLANG = 3, +#endif +#if defined(USE_X11) + CACA_DRIVER_X11 = 4, +#endif + CACA_DRIVER_NONE = 0 +}; + +extern enum caca_driver _caca_driver; + +/* Initialisation functions */ extern int _caca_init_graphics(void); extern int _caca_end_graphics(void); diff --git a/src/conic.c b/src/conic.c index d1bf0d8..b792b99 100644 --- a/src/conic.c +++ b/src/conic.c @@ -30,7 +30,7 @@ #include "config.h" -#ifdef HAVE_INTTYPES_H +#if defined(HAVE_INTTYPES_H) # include #else typedef unsigned char uint8_t; diff --git a/src/graphics.c b/src/graphics.c index aca787e..5f8f5ca 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -31,20 +31,21 @@ #if defined(USE_SLANG) # include -#elif defined(USE_NCURSES) +#endif +#if defined(USE_NCURSES) # include -#elif defined(USE_CONIO) +#endif +#if defined(USE_CONIO) # include # if defined(SCREENUPDATE_IN_PC_H) # include # endif -#elif defined(USE_X11) +#endif +#if defined(USE_X11) # include -#else -# error "no graphics library detected" #endif -#ifdef HAVE_INTTYPES_H +#if defined(HAVE_INTTYPES_H) # include #endif @@ -112,16 +113,32 @@ void caca_set_color(enum caca_color fgcolor, enum caca_color bgcolor) _caca_fgcolor = fgcolor; _caca_bgcolor = bgcolor; + switch(_caca_driver) + { #if defined(USE_SLANG) - SLsmg_set_color((bgcolor + 16 * fgcolor) /*% 128*/); -#elif defined(USE_NCURSES) - attrset(ncurses_attr[fgcolor + 16 * bgcolor]); -#elif defined(USE_CONIO) - textbackground(bgcolor); - textcolor(fgcolor); -#elif defined(USE_X11) - /* FIXME */ + case CACA_DRIVER_SLANG: + SLsmg_set_color((bgcolor + 16 * fgcolor) /*% 128*/); + break; +#endif +#if defined(USE_NCURSES) + case CACA_DRIVER_NCURSES: + attrset(ncurses_attr[fgcolor + 16 * bgcolor]); + break; +#endif +#if defined(USE_CONIO) + case CACA_DRIVER_CONIO: + textbackground(bgcolor); + textcolor(fgcolor); + break; +#endif +#if defined(USE_X11) + case CACA_DRIVER_X11: + /* FIXME */ + break; #endif + default: + break; + } } /** @@ -161,22 +178,38 @@ void caca_putchar(int x, int y, char c) y < 0 || y >= (int)_caca_height) return; + switch(_caca_driver) + { #if defined(USE_SLANG) - SLsmg_gotorc(y, x); - SLsmg_write_char(c); -#elif defined(USE_NCURSES) - move(y, x); - addch(c); -#elif defined(USE_CONIO) - data = conio_screen + 2 * (x + y * _caca_width); - data[0] = c; - data[1] = (_caca_bgcolor << 4) | _caca_fgcolor; -// gotoxy(x + 1, y + 1); -// putch(c); -#elif defined(USE_X11) - x11_screen[x + y * _caca_width] = - ((int)c << 8) | ((int)_caca_bgcolor << 4) | (int)_caca_fgcolor; + case CACA_DRIVER_SLANG: + SLsmg_gotorc(y, x); + SLsmg_write_char(c); + break; +#endif +#if defined(USE_NCURSES) + case CACA_DRIVER_NCURSES: + move(y, x); + addch(c); + break; +#endif +#if defined(USE_CONIO) + case CACA_DRIVER_CONIO: + data = conio_screen + 2 * (x + y * _caca_width); + data[0] = c; + data[1] = (_caca_bgcolor << 4) | _caca_fgcolor; +// gotoxy(x + 1, y + 1); +// putch(c); + break; +#endif +#if defined(USE_X11) + case CACA_DRIVER_X11: + x11_screen[x + y * _caca_width] = + ((int)c << 8) | ((int)_caca_bgcolor << 4) | (int)_caca_fgcolor; + break; #endif + default: + break; + } } /** @@ -190,9 +223,10 @@ void caca_putchar(int x, int y, char c) void caca_putstr(int x, int y, const char *s) { #if defined(USE_CONIO) - char *buf; -#elif defined(USE_X11) - int *buf; + char *charbuf; +#endif +#if defined(USE_X11) + int *intbuf; #endif unsigned int len; @@ -217,26 +251,43 @@ void caca_putstr(int x, int y, const char *s) s = _caca_scratch_line; } -#if defined(USE_SLANG) - SLsmg_gotorc(y, x); - SLsmg_write_string((char *)(intptr_t)s); -#elif defined(USE_NCURSES) - move(y, x); - addstr(s); -#elif defined(USE_CONIO) - buf = conio_screen + 2 * (x + y * _caca_width); - while(*s) + switch(_caca_driver) { - *buf++ = *s++; - *buf++ = (_caca_bgcolor << 4) | _caca_fgcolor; - } -// gotoxy(x + 1, y + 1); -// cputs(s); -#elif defined(USE_X11) - buf = x11_screen + x + y * _caca_width; - while(*s) - *buf++ = ((int)*s++ << 8) | ((int)_caca_bgcolor << 4) | (int)_caca_fgcolor; +#if defined(USE_SLANG) + case CACA_DRIVER_SLANG: + SLsmg_gotorc(y, x); + SLsmg_write_string((char *)(intptr_t)s); + break; #endif +#if defined(USE_NCURSES) + case CACA_DRIVER_NCURSES: + move(y, x); + addstr(s); + break; +#endif +#if defined(USE_CONIO) + case CACA_DRIVER_CONIO: + charbuf = conio_screen + 2 * (x + y * _caca_width); + while(*s) + { + *charbuf++ = *s++; + *charbuf++ = (_caca_bgcolor << 4) | _caca_fgcolor; + } +// gotoxy(x + 1, y + 1); +// cputs(s); + break; +#endif +#if defined(USE_X11) + case CACA_DRIVER_X11: + intbuf = x11_screen + x + y * _caca_width; + while(*s) + *intbuf++ = ((int)*s++ << 8) + | ((int)_caca_bgcolor << 4) | (int)_caca_fgcolor; + break; +#endif + default: + break; + } } /** @@ -298,231 +349,249 @@ void caca_clear(void) int _caca_init_graphics(void) { #if defined(USE_SLANG) - /* See SLang ref., 5.4.4. */ - static char *slang_colors[16] = + if(_caca_driver == CACA_DRIVER_SLANG) { - /* Standard colours */ - "black", - "blue", - "green", - "cyan", - "red", - "magenta", - "brown", - "lightgray", - /* Bright colours */ - "gray", - "brightblue", - "brightgreen", - "brightcyan", - "brightred", - "brightmagenta", - "yellow", - "white", - }; - - int fg, bg; - - for(fg = 0; fg < 16; fg++) - for(bg = 0; bg < 16; bg++) + /* See SLang ref., 5.4.4. */ + static char *slang_colors[16] = { - int i = bg + 16 * fg; - SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]); - } - - /* Disable alt charset support so that we get all 256 colour pairs */ - SLtt_Has_Alt_Charset = 0; + /* Standard colours */ + "black", + "blue", + "green", + "cyan", + "red", + "magenta", + "brown", + "lightgray", + /* Bright colours */ + "gray", + "brightblue", + "brightgreen", + "brightcyan", + "brightred", + "brightmagenta", + "yellow", + "white", + }; + + int fg, bg; + + for(fg = 0; fg < 16; fg++) + for(bg = 0; bg < 16; bg++) + { + int i = bg + 16 * fg; + SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]); + } - _caca_width = SLtt_Screen_Cols; - _caca_height = SLtt_Screen_Rows; + /* Disable alt charset support so that we get all 256 colour pairs */ + SLtt_Has_Alt_Charset = 0; -#elif defined(USE_NCURSES) - static int curses_colors[] = + _caca_width = SLtt_Screen_Cols; + _caca_height = SLtt_Screen_Rows; + } + else +#endif +#if defined(USE_NCURSES) + if(_caca_driver == CACA_DRIVER_NCURSES) { - /* Standard curses colours */ - COLOR_BLACK, - COLOR_BLUE, - COLOR_GREEN, - COLOR_CYAN, - COLOR_RED, - COLOR_MAGENTA, - COLOR_YELLOW, - COLOR_WHITE, - /* Extra values for xterm-16color */ - COLOR_BLACK + 8, - COLOR_BLUE + 8, - COLOR_GREEN + 8, - COLOR_CYAN + 8, - COLOR_RED + 8, - COLOR_MAGENTA + 8, - COLOR_YELLOW + 8, - COLOR_WHITE + 8 - }; - - int fg, bg, max; - - /* Activate colour */ - start_color(); - - /* If COLORS == 16, it means the terminal supports full bright colours - * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8), - * we can build 16*16 colour pairs. - * If COLORS == 8, it means the terminal does not know about bright - * colours and we need to get them through A_BOLD and A_BLINK (\e[1m - * and \e[5m). We can only build 8*8 colour pairs. */ - max = COLORS >= 16 ? 16 : 8; - - for(bg = 0; bg < max; bg++) - for(fg = 0; fg < max; fg++) + static int curses_colors[] = { - /* Use ((max + 7 - fg) % max) instead of fg so that colour 0 - * is light gray on black, since some terminals don't like - * this colour pair to be redefined. */ - int col = ((max + 7 - fg) % max) + max * bg; - init_pair(col, curses_colors[fg], curses_colors[bg]); - ncurses_attr[fg + 16 * bg] = COLOR_PAIR(col); - - if(max == 8) + /* Standard curses colours */ + COLOR_BLACK, + COLOR_BLUE, + COLOR_GREEN, + COLOR_CYAN, + COLOR_RED, + COLOR_MAGENTA, + COLOR_YELLOW, + COLOR_WHITE, + /* Extra values for xterm-16color */ + COLOR_BLACK + 8, + COLOR_BLUE + 8, + COLOR_GREEN + 8, + COLOR_CYAN + 8, + COLOR_RED + 8, + COLOR_MAGENTA + 8, + COLOR_YELLOW + 8, + COLOR_WHITE + 8 + }; + + int fg, bg, max; + + /* Activate colour */ + start_color(); + + /* If COLORS == 16, it means the terminal supports full bright colours + * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8), + * we can build 16*16 colour pairs. + * If COLORS == 8, it means the terminal does not know about bright + * colours and we need to get them through A_BOLD and A_BLINK (\e[1m + * and \e[5m). We can only build 8*8 colour pairs. */ + max = COLORS >= 16 ? 16 : 8; + + for(bg = 0; bg < max; bg++) + for(fg = 0; fg < max; fg++) { - /* Bright fg on simple bg */ - ncurses_attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); - /* Simple fg on bright bg */ - ncurses_attr[fg + 16 * (bg + 8)] = A_BLINK | COLOR_PAIR(col); - /* Bright fg on bright bg */ - ncurses_attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD + /* Use ((max + 7 - fg) % max) instead of fg so that colour 0 + * is light gray on black, since some terminals don't like + * this colour pair to be redefined. */ + int col = ((max + 7 - fg) % max) + max * bg; + init_pair(col, curses_colors[fg], curses_colors[bg]); + ncurses_attr[fg + 16 * bg] = COLOR_PAIR(col); + + if(max == 8) + { + /* Bright fg on simple bg */ + ncurses_attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); + /* Simple fg on bright bg */ + ncurses_attr[fg + 16 * (bg + 8)] = A_BLINK | COLOR_PAIR(col); + /* Bright fg on bright bg */ + ncurses_attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD + | COLOR_PAIR(col); + } } - } - - _caca_width = COLS; - _caca_height = LINES; -#elif defined(USE_CONIO) - gettextinfo(&conio_ti); - conio_screen = malloc(2 * conio_ti.screenwidth - * conio_ti.screenheight * sizeof(char)); - if(conio_screen == NULL) - return -1; + _caca_width = COLS; + _caca_height = LINES; + } + else +#endif +#if defined(USE_CONIO) + if(_caca_driver == CACA_DRIVER_CONIO) + { + gettextinfo(&conio_ti); + conio_screen = malloc(2 * conio_ti.screenwidth + * conio_ti.screenheight * sizeof(char)); + if(conio_screen == NULL) + return -1; # if defined(SCREENUPDATE_IN_PC_H) - ScreenRetrieve(conio_screen); + ScreenRetrieve(conio_screen); # else - /* FIXME */ + /* FIXME */ # endif - _caca_width = conio_ti.screenwidth; - _caca_height = conio_ti.screenheight; - -#elif defined(USE_X11) - static int x11_palette[] = - { - /* Standard curses colours */ - 0, 0, 0, - 0, 0, 32768, - 0, 32768, 0, - 0, 32768, 32768, - 32768, 0, 0, - 32768, 0, 32768, - 32768, 32768, 0, - 32768, 32768, 32768, - /* Extra values for xterm-16color */ - 16384, 16384, 16384, - 16384, 16384, 65535, - 16384, 65535, 16384, - 16384, 65535, 65535, - 65535, 16384, 16384, - 65535, 16384, 65535, - 65535, 65535, 16384, - 65535, 65535, 65535, - }; - - Colormap colormap; - const char *font_name = "8x13bold"; - int i; - - if(getenv("CACA_WIDTH")) - _caca_width = atoi(getenv("CACA_WIDTH")); - if(!_caca_width) - _caca_width = 80; - - if(getenv("CACA_HEIGHT")) - _caca_height = atoi(getenv("CACA_HEIGHT")); - if(!_caca_height) - _caca_height = 32; - - x11_screen = malloc(_caca_width * _caca_height * sizeof(int)); - if(x11_screen == NULL) - return -1; - - x11_dpy = XOpenDisplay(NULL); - if(x11_dpy == NULL) - { - free(x11_screen); - return -1; + _caca_width = conio_ti.screenwidth; + _caca_height = conio_ti.screenheight; } + else +#endif +#if defined(USE_X11) + if(_caca_driver == CACA_DRIVER_X11) + { + static int x11_palette[] = + { + /* Standard curses colours */ + 0, 0, 0, + 0, 0, 32768, + 0, 32768, 0, + 0, 32768, 32768, + 32768, 0, 0, + 32768, 0, 32768, + 32768, 32768, 0, + 32768, 32768, 32768, + /* Extra values for xterm-16color */ + 16384, 16384, 16384, + 16384, 16384, 65535, + 16384, 65535, 16384, + 16384, 65535, 65535, + 65535, 16384, 16384, + 65535, 16384, 65535, + 65535, 65535, 16384, + 65535, 65535, 65535, + }; + + Colormap colormap; + const char *font_name = "8x13bold"; + int i; + + if(getenv("CACA_WIDTH")) + _caca_width = atoi(getenv("CACA_WIDTH")); + if(!_caca_width) + _caca_width = 80; + + if(getenv("CACA_HEIGHT")) + _caca_height = atoi(getenv("CACA_HEIGHT")); + if(!_caca_height) + _caca_height = 32; + + x11_screen = malloc(_caca_width * _caca_height * sizeof(int)); + if(x11_screen == NULL) + return -1; + + x11_dpy = XOpenDisplay(NULL); + if(x11_dpy == NULL) + { + free(x11_screen); + return -1; + } - if(getenv("CACA_FONT")) - font_name = getenv("CACA_FONT"); + if(getenv("CACA_FONT")) + font_name = getenv("CACA_FONT"); - x11_font = XLoadFont(x11_dpy, font_name); - if(!x11_font) - { - XCloseDisplay(x11_dpy); - free(x11_screen); - return -1; - } + x11_font = XLoadFont(x11_dpy, font_name); + if(!x11_font) + { + XCloseDisplay(x11_dpy); + free(x11_screen); + return -1; + } - x11_font_struct = XQueryFont(x11_dpy, x11_font); - if(!x11_font_struct) - { - XUnloadFont(x11_dpy, x11_font); - XCloseDisplay(x11_dpy); - free(x11_screen); - return -1; - } + x11_font_struct = XQueryFont(x11_dpy, x11_font); + if(!x11_font_struct) + { + XUnloadFont(x11_dpy, x11_font); + XCloseDisplay(x11_dpy); + free(x11_screen); + return -1; + } - x11_font_width = x11_font_struct->max_bounds.width; - x11_font_height = x11_font_struct->max_bounds.ascent - + x11_font_struct->max_bounds.descent; - x11_font_offset = x11_font_struct->max_bounds.descent; + x11_font_width = x11_font_struct->max_bounds.width; + x11_font_height = x11_font_struct->max_bounds.ascent + + x11_font_struct->max_bounds.descent; + x11_font_offset = x11_font_struct->max_bounds.descent; - colormap = DefaultColormap(x11_dpy, DefaultScreen(x11_dpy)); - for(i = 0; i < 16; i++) - { - XColor color; - color.red = x11_palette[i * 3]; - color.green = x11_palette[i * 3 + 1]; - color.blue = x11_palette[i * 3 + 2]; - XAllocColor(x11_dpy, colormap, &color); - x11_colors[i] = color.pixel; - } + colormap = DefaultColormap(x11_dpy, DefaultScreen(x11_dpy)); + for(i = 0; i < 16; i++) + { + XColor color; + color.red = x11_palette[i * 3]; + color.green = x11_palette[i * 3 + 1]; + color.blue = x11_palette[i * 3 + 2]; + XAllocColor(x11_dpy, colormap, &color); + x11_colors[i] = color.pixel; + } - x11_window = XCreateSimpleWindow(x11_dpy, DefaultRootWindow(x11_dpy), - 0, 0, _caca_width * x11_font_width, - _caca_height * x11_font_height, 0, - x11_colors[0], x11_colors[0]); - XSelectInput(x11_dpy, x11_window, StructureNotifyMask); - XMapWindow(x11_dpy, x11_window); + x11_window = XCreateSimpleWindow(x11_dpy, DefaultRootWindow(x11_dpy), + 0, 0, _caca_width * x11_font_width, + _caca_height * x11_font_height, 0, + x11_colors[0], x11_colors[0]); + XSelectInput(x11_dpy, x11_window, StructureNotifyMask); + XMapWindow(x11_dpy, x11_window); - x11_gc = XCreateGC(x11_dpy, x11_window, 0, NULL); - XSetForeground(x11_dpy, x11_gc, x11_colors[15]); - XSetFont(x11_dpy, x11_gc, x11_font); + x11_gc = XCreateGC(x11_dpy, x11_window, 0, NULL); + XSetForeground(x11_dpy, x11_gc, x11_colors[15]); + XSetFont(x11_dpy, x11_gc, x11_font); - for(;;) - { - XEvent event; - XNextEvent(x11_dpy, &event); - if (event.type == MapNotify) - break; - } + for(;;) + { + XEvent event; + XNextEvent(x11_dpy, &event); + if (event.type == MapNotify) + break; + } - XSelectInput(x11_dpy, x11_window, KeyPressMask); + XSelectInput(x11_dpy, x11_window, KeyPressMask); - XSync(x11_dpy, False); + XSync(x11_dpy, False); - x11_pixmap = XCreatePixmap(x11_dpy, x11_window, - _caca_width * x11_font_width, - _caca_height * x11_font_height, - DefaultDepth(x11_dpy, DefaultScreen(x11_dpy))); + x11_pixmap = XCreatePixmap(x11_dpy, x11_window, + _caca_width * x11_font_width, + _caca_height * x11_font_height, + DefaultDepth(x11_dpy, + DefaultScreen(x11_dpy))); + } #endif + _caca_empty_line = malloc(_caca_width + 1); memset(_caca_empty_line, ' ', _caca_width); _caca_empty_line[_caca_width] = '\0'; @@ -539,19 +608,29 @@ int _caca_end_graphics(void) { #if defined(USE_SLANG) /* Nothing to do */ -#elif defined(USE_NCURSES) +#endif +#if defined(USE_NCURSES) /* Nothing to do */ -#elif defined(USE_CONIO) - free(conio_screen); -#elif defined(USE_X11) - XSync(x11_dpy, False); - XFreePixmap(x11_dpy, x11_pixmap); - XFreeFont(x11_dpy, x11_font_struct); - XFreeGC(x11_dpy, x11_gc); - XUnmapWindow(x11_dpy, x11_window); - XDestroyWindow(x11_dpy, x11_window); - XCloseDisplay(x11_dpy); - free(x11_screen); +#endif +#if defined(USE_CONIO) + if(_caca_driver == CACA_DRIVER_CONIO) + { + free(conio_screen); + } + else +#endif +#if defined(USE_X11) + if(_caca_driver == CACA_DRIVER_X11) + { + XSync(x11_dpy, False); + XFreePixmap(x11_dpy, x11_pixmap); + XFreeFont(x11_dpy, x11_font_struct); + XFreeGC(x11_dpy, x11_gc); + XUnmapWindow(x11_dpy, x11_window); + XDestroyWindow(x11_dpy, x11_window); + XCloseDisplay(x11_dpy); + free(x11_screen); + } #endif free(_caca_empty_line); @@ -611,35 +690,54 @@ void caca_refresh(void) int ticks = lastticks + _caca_getticks(); #if defined(USE_SLANG) - SLsmg_refresh(); -#elif defined(USE_NCURSES) - refresh(); -#elif defined(USE_CONIO) + if(_caca_driver == CACA_DRIVER_SLANG) + { + SLsmg_refresh(); + } + else +#endif +#if defined(USE_NCURSES) + if(_caca_driver == CACA_DRIVER_NCURSES) + { + refresh(); + } + else +#endif +#if defined(USE_CONIO) + if(_caca_driver == CACA_DRIVER_CONIO) + { # if defined(SCREENUPDATE_IN_PC_H) - ScreenUpdate(conio_screen); + ScreenUpdate(conio_screen); # else - /* FIXME */ + /* FIXME */ # endif -#elif defined(USE_X11) - unsigned int x, y; + } + else +#endif +#if defined(USE_X11) + if(_caca_driver == CACA_DRIVER_X11) + { + unsigned int x, y; - for(y = 0; y < _caca_height; y++) - for(x = 0; x < _caca_width; x++) - { - int item = x11_screen[x + y * _caca_width]; - char data = item >> 8; - XSetForeground(x11_dpy, x11_gc, x11_colors[(item >> 4) & 0xf]); - XFillRectangle(x11_dpy, x11_pixmap, x11_gc, - x * x11_font_width, y * x11_font_height, - x11_font_width, x11_font_height); - XSetForeground(x11_dpy, x11_gc, x11_colors[item & 0xf]); - XDrawString(x11_dpy, x11_pixmap, x11_gc, x * x11_font_width, - (y + 1) * x11_font_height - x11_font_offset, &data, 1); - } - XCopyArea(x11_dpy, x11_pixmap, x11_window, x11_gc, 0, 0, - _caca_width * x11_font_width, _caca_height * x11_font_height, - 0, 0); - XFlush(x11_dpy); + for(y = 0; y < _caca_height; y++) + for(x = 0; x < _caca_width; x++) + { + int item = x11_screen[x + y * _caca_width]; + char data = item >> 8; + XSetForeground(x11_dpy, x11_gc, x11_colors[(item >> 4) & 0xf]); + XFillRectangle(x11_dpy, x11_pixmap, x11_gc, + x * x11_font_width, y * x11_font_height, + x11_font_width, x11_font_height); + XSetForeground(x11_dpy, x11_gc, x11_colors[item & 0xf]); + XDrawString(x11_dpy, x11_pixmap, x11_gc, x * x11_font_width, + (y + 1) * x11_font_height - x11_font_offset, + &data, 1); + } + XCopyArea(x11_dpy, x11_pixmap, x11_window, x11_gc, 0, 0, + _caca_width * x11_font_width, _caca_height * x11_font_height, + 0, 0); + XFlush(x11_dpy); + } #endif /* Wait until _caca_delay + time of last call */ diff --git a/src/io.c b/src/io.c index 4b7b593..ae1c11e 100644 --- a/src/io.c +++ b/src/io.c @@ -31,15 +31,16 @@ #if defined(USE_SLANG) # include -#elif defined(USE_NCURSES) +#endif +#if defined(USE_NCURSES) # include -#elif defined(USE_CONIO) +#endif +#if defined(USE_CONIO) # include -#elif defined(USE_X11) +#endif +#if defined(USE_X11) # include # include -#else -# error "no graphics library detected" #endif #include "caca.h" @@ -75,44 +76,47 @@ unsigned int caca_get_event(void) return 0; #if defined(USE_NCURSES) - if(keybuf[0] == KEY_MOUSE) + if(_caca_driver == CACA_DRIVER_NCURSES) { - MEVENT mevent; - _pop_key(); - getmouse(&mevent); + if(keybuf[0] == KEY_MOUSE) + { + MEVENT mevent; + _pop_key(); + getmouse(&mevent); - event |= (1) << 16; - event |= (mevent.x) << 8; - event |= (mevent.y) << 0; + event |= (1) << 16; + event |= (mevent.x) << 8; + event |= (mevent.y) << 0; - return CACA_EVENT_MOUSE_CLICK | event; - } + return CACA_EVENT_MOUSE_CLICK | event; + } - switch(keybuf[0]) - { - case KEY_UP: event = CACA_EVENT_KEY_PRESS | CACA_KEY_UP; break; - case KEY_DOWN: event = CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN; break; - case KEY_LEFT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT; break; - case KEY_RIGHT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT; break; - - case KEY_F(1): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F1; break; - case KEY_F(2): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F2; break; - case KEY_F(3): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F3; break; - case KEY_F(4): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F4; break; - case KEY_F(5): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F5; break; - case KEY_F(6): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F6; break; - case KEY_F(7): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F7; break; - case KEY_F(8): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F8; break; - case KEY_F(9): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F9; break; - case KEY_F(10): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F10; break; - case KEY_F(11): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F11; break; - case KEY_F(12): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F12; break; - } + switch(keybuf[0]) + { + case KEY_UP: event = CACA_EVENT_KEY_PRESS | CACA_KEY_UP; break; + case KEY_DOWN: event = CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN; break; + case KEY_LEFT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT; break; + case KEY_RIGHT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT; break; - if(event) - { - _pop_key(); - return event; + case KEY_F(1): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F1; break; + case KEY_F(2): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F2; break; + case KEY_F(3): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F3; break; + case KEY_F(4): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F4; break; + case KEY_F(5): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F5; break; + case KEY_F(6): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F6; break; + case KEY_F(7): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F7; break; + case KEY_F(8): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F8; break; + case KEY_F(9): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F9; break; + case KEY_F(10): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F10; break; + case KEY_F(11): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F11; break; + case KEY_F(12): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F12; break; + } + + if(event) + { + _pop_key(); + return event; + } } #endif @@ -205,30 +209,49 @@ static unsigned int _pop_key(void) static unsigned int _read_key(void) { -#if defined(USE_SLANG) - return SLang_input_pending(0) ? SLang_getkey() : 0; -#elif defined(USE_NCURSES) - int key = getch(); - return (key == ERR) ? 0 : key; -#elif defined(USE_CONIO) - return _conio_kbhit() ? getch() : 0; -#elif defined(USE_X11) +#if defined(USE_NCURSES) + int intkey; +#endif +#if defined(USE_X11) XEvent event; char key; +#endif - while(XCheckWindowEvent(x11_dpy, x11_window, KeyPressMask, &event) - == True) + switch(_caca_driver) { - if(event.type == KeyPress) +#if defined(USE_SLANG) + case CACA_DRIVER_SLANG: + return SLang_input_pending(0) ? SLang_getkey() : 0; +#endif +#if defined(USE_NCURSES) + case CACA_DRIVER_NCURSES: + intkey = getch(); + return (intkey == ERR) ? 0 : intkey; +#endif +#if defined(USE_CONIO) + case CACA_DRIVER_CONIO: + return _conio_kbhit() ? getch() : 0; +#endif +#if defined(USE_X11) + case CACA_DRIVER_X11: + while(XCheckWindowEvent(x11_dpy, x11_window, KeyPressMask, &event) + == True) { - //KeySym keysym; - //keysym = XKeycodeToKeysym(_caca_dpy, event.xkey.keycode, 0); - if(XLookupString(&event.xkey, &key, 1, NULL, NULL)) - return key; + if(event.type == KeyPress) + { + //KeySym keysym; + //keysym = XKeycodeToKeysym(_caca_dpy, event.xkey.keycode, 0); + if(XLookupString(&event.xkey, &key, 1, NULL, NULL)) + return key; + } } + + return 0; +#endif + default: + break; } return 0; -#endif } diff --git a/src/line.c b/src/line.c index a86ff4b..3bbc1a2 100644 --- a/src/line.c +++ b/src/line.c @@ -30,7 +30,7 @@ #include "config.h" -#ifdef HAVE_INTTYPES_H +#if defined(HAVE_INTTYPES_H) # include #else typedef unsigned char uint8_t;