浏览代码

* src/graphics.c src/caca.c src/io.c:

+ Support for simultaneously compiled-in drivers.
    + Honour the CACA_DRIVER environment variable.
  * configure.ac:
    + Drivers are no longer mutually exclusive.
tags/v0.99.beta14
Sam Hocevar sam 21 年前
父节点
当前提交
699c2a46a3
共有 9 个文件被更改,包括 686 次插入429 次删除
  1. +13
    -9
      configure.ac
  2. +3
    -3
      src/bitmap.c
  3. +181
    -76
      src/caca.c
  4. +6
    -0
      src/caca.h
  5. +21
    -0
      src/caca_internals.h
  6. +1
    -1
      src/conic.c
  7. +383
    -285
      src/graphics.c
  8. +77
    -54
      src/io.c
  9. +1
    -1
      src/line.c

+ 13
- 9
configure.ac 查看文件

@@ -37,13 +37,17 @@ if test "${enable_conio}" = "yes"; then
AC_DEFINE(SCREENUPDATE_IN_PC_H, 1,
Define if <pc.h> 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)


+ 3
- 3
src/bitmap.c 查看文件

@@ -29,7 +29,7 @@

#include "config.h"

#ifdef HAVE_INTTYPES_H
#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#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 <endian.h>
#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 */


+ 181
- 76
src/caca.c 查看文件

@@ -33,15 +33,16 @@

#if defined(USE_SLANG)
# include <slang.h>
#elif defined(USE_NCURSES)
#endif
#if defined(USE_NCURSES)
# include <curses.h>
#elif defined(USE_CONIO)
#endif
#if defined(USE_CONIO)
# include <dos.h>
# include <conio.h>
#elif defined(USE_X11)
#endif
#if defined(USE_X11)
# include <X11/Xlib.h>
#else
# error "no graphics library detected"
#endif

#include <stdlib.h>
@@ -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;


+ 6
- 0
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


+ 21
- 0
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);



+ 1
- 1
src/conic.c 查看文件

@@ -30,7 +30,7 @@

#include "config.h"

#ifdef HAVE_INTTYPES_H
#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;


+ 383
- 285
src/graphics.c 查看文件

@@ -31,20 +31,21 @@

#if defined(USE_SLANG)
# include <slang.h>
#elif defined(USE_NCURSES)
#endif
#if defined(USE_NCURSES)
# include <curses.h>
#elif defined(USE_CONIO)
#endif
#if defined(USE_CONIO)
# include <conio.h>
# if defined(SCREENUPDATE_IN_PC_H)
# include <pc.h>
# endif
#elif defined(USE_X11)
#endif
#if defined(USE_X11)
# include <X11/Xlib.h>
#else
# error "no graphics library detected"
#endif

#ifdef HAVE_INTTYPES_H
#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#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 */


+ 77
- 54
src/io.c 查看文件

@@ -31,15 +31,16 @@

#if defined(USE_SLANG)
# include <slang.h>
#elif defined(USE_NCURSES)
#endif
#if defined(USE_NCURSES)
# include <curses.h>
#elif defined(USE_CONIO)
#endif
#if defined(USE_CONIO)
# include <conio.h>
#elif defined(USE_X11)
#endif
#if defined(USE_X11)
# include <X11/Xlib.h>
# include <X11/Xutil.h>
#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
}


+ 1
- 1
src/line.c 查看文件

@@ -30,7 +30,7 @@

#include "config.h"

#ifdef HAVE_INTTYPES_H
#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;


正在加载...
取消
保存