+ Renamed sdl_get_key() into sdl_get_event(). + Handle mouse clicks. * src/caca.c: + Activate the terminal's mouse handling if supported.tags/v0.99.beta14
@@ -78,12 +78,14 @@ gdk_init (&argc, &argv); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/pikachu.jpeg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/gradient.png", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/beastie.png", NULL); | |||
pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/stitch.jpg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/stitch.jpg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/caca.jpg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/dranac.jpeg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/artwork/aboire.png", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/web/sam.zoy.org/artwork/goret.png", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/lilkim02.jpg", NULL); | |||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/etw.bmp", NULL); | |||
pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/lena_std.png", NULL); | |||
if(!pixbuf) return -2; | |||
pixels = gdk_pixbuf_get_pixels(pixbuf); | |||
bufx = gdk_pixbuf_get_width(pixbuf); | |||
@@ -99,18 +101,18 @@ fprintf(stderr, "w %i, h %i, stride %i\n", bufx, bufy, bufpitch); | |||
/* Go ! */ | |||
while(!quit) | |||
{ | |||
char key = caca_get_key(); | |||
int event = caca_get_event(); | |||
if(key && demo) | |||
if(event && demo) | |||
{ | |||
display_menu(); | |||
caca_refresh(); | |||
demo = NULL; | |||
} | |||
else if(key) | |||
else if(event & CACA_EVENT_KEY_PRESS) | |||
{ | |||
handle_key: | |||
switch(key) | |||
switch(event & 0xff) | |||
{ | |||
case 'q': | |||
case 'Q': | |||
@@ -170,9 +172,12 @@ fprintf(stderr, "w %i, h %i, stride %i\n", bufx, bufy, bufpitch); | |||
if(demo) | |||
caca_clear(); | |||
key = caca_get_key(); | |||
if(key) | |||
handle_event: | |||
event = caca_get_event(); | |||
if(event & CACA_EVENT_KEY_PRESS) | |||
goto handle_key; | |||
else if(event) | |||
goto handle_event; | |||
caca_refresh(); | |||
} | |||
@@ -56,22 +56,27 @@ int main(int argc, char **argv) | |||
{ | |||
int xa, ya, xb, yb; | |||
char buf[BUFSIZ]; | |||
int event; | |||
switch(caca_get_key()) | |||
while((event = caca_get_event())) | |||
{ | |||
case 0: | |||
break; | |||
case 'q': | |||
quit = 1; | |||
break; | |||
case '-': | |||
if(frame > 0) | |||
frame--; | |||
break; | |||
case '+': | |||
if(frame < caca_get_sprite_frames(sprite) - 1) | |||
frame++; | |||
break; | |||
if(event & CACA_EVENT_KEY_PRESS) | |||
switch(event & 0xff) | |||
{ | |||
case 0: | |||
break; | |||
case 'q': | |||
quit = 1; | |||
break; | |||
case '-': | |||
if(frame > 0) | |||
frame--; | |||
break; | |||
case '+': | |||
if(frame < caca_get_sprite_frames(sprite) - 1) | |||
frame++; | |||
break; | |||
} | |||
} | |||
caca_clear(); | |||
@@ -101,8 +101,8 @@ void caca_blit(int x1, int y1, int x2, int y2, void *pixels, int w, int h) | |||
int tmp = y2; y2 = y1; y1 = tmp; | |||
} | |||
//pitch = (3 * w + 3) / 4 * 4; | |||
pitch = 4 * w; | |||
pitch = (3 * w + 3) / 4 * 4; | |||
//pitch = 4 * w; | |||
for(y = y1 > 0 ? y1 : 0; y <= y2 && y <= (int)caca_get_height(); y++) | |||
{ | |||
@@ -114,12 +114,12 @@ void caca_blit(int x1, int y1, int x2, int y2, void *pixels, int w, int h) | |||
{ | |||
int fromx = w * (x - x1) / (x2 - x1 + 1); | |||
int fromy = h * (y - y1) / (y2 - y1 + 1); | |||
//int r = ((unsigned char *)pixels)[3 * fromx + pitch * fromy]; | |||
//int g = ((unsigned char *)pixels)[3 * fromx + 1 + pitch * fromy]; | |||
//int b = ((unsigned char *)pixels)[3 * fromx + 2 + pitch * fromy]; | |||
int b = ((unsigned char *)pixels)[4 * fromx + pitch * fromy]; | |||
int g = ((unsigned char *)pixels)[4 * fromx + 1 + pitch * fromy]; | |||
int r = ((unsigned char *)pixels)[4 * fromx + 2 + pitch * fromy]; | |||
int r = ((unsigned char *)pixels)[3 * fromx + pitch * fromy]; | |||
int g = ((unsigned char *)pixels)[3 * fromx + 1 + pitch * fromy]; | |||
int b = ((unsigned char *)pixels)[3 * fromx + 2 + pitch * fromy]; | |||
//int b = ((unsigned char *)pixels)[4 * fromx + pitch * fromy]; | |||
//int g = ((unsigned char *)pixels)[4 * fromx + 1 + pitch * fromy]; | |||
//int r = ((unsigned char *)pixels)[4 * fromx + 2 + pitch * fromy]; | |||
int hue, sat, val; | |||
int min = r, max = r, delta; | |||
@@ -142,7 +142,7 @@ void caca_blit(int x1, int y1, int x2, int y2, void *pixels, int w, int h) | |||
else | |||
hue = 1280 + 256 * (r - g) / delta; | |||
hue = (hue + 128 + 8 * _get_dither()) / 256; | |||
hue = (hue + 128 + 16 * _get_dither()) / 256; | |||
if(val > (_get_dither() + 40) * 4) | |||
caca_set_color(light_colors[hue]); | |||
@@ -97,6 +97,8 @@ int caca_init(void) | |||
SLang_init_tty(-1, 0, 1); | |||
SLkp_define_keysym("\e[M", 1001); | |||
if(SLsmg_init_smg() == -1) | |||
{ | |||
SLsig_unblock_signals(); | |||
@@ -107,6 +109,7 @@ int caca_init(void) | |||
SLsmg_cls(); | |||
SLtt_set_cursor_visibility(0); | |||
SLtt_set_mouse_mode (1, 0); | |||
SLsmg_refresh(); | |||
for(i = 0; i < 16; i++) | |||
@@ -291,6 +294,7 @@ void caca_refresh(void) | |||
void caca_end(void) | |||
{ | |||
#if defined(USE_SLANG) | |||
SLtt_set_mouse_mode(0, 0); | |||
SLtt_set_cursor_visibility(1); | |||
SLang_reset_tty(); | |||
SLsmg_reset_smg(); | |||
@@ -62,6 +62,17 @@ enum caca_dithering | |||
CACA_DITHER_RANDOM | |||
}; | |||
/* | |||
* Events | |||
*/ | |||
enum caca_event | |||
{ | |||
CACA_EVENT_NONE = 0x00000000, | |||
CACA_EVENT_KEY_PRESS = 0x01000000, | |||
CACA_EVENT_KEY_RELEASE = 0x02000000, | |||
CACA_EVENT_MOUSE_CLICK = 0x04000000 | |||
}; | |||
/* | |||
* Keys | |||
*/ | |||
@@ -107,7 +118,7 @@ const char *caca_get_color_name(unsigned int); | |||
void caca_refresh(void); | |||
void caca_end(void); | |||
int caca_get_key(void); | |||
int caca_get_event(void); | |||
void caca_set_color(enum caca_color); | |||
enum caca_color caca_get_color(void); | |||
@@ -36,111 +36,135 @@ | |||
#include "caca.h" | |||
#include "caca_internals.h" | |||
static unsigned char back[5] = {0, 0, 0, 0, 0}; | |||
static void _push_key(unsigned char key) | |||
{ | |||
back[4] = back[3]; | |||
back[3] = back[2]; | |||
back[2] = back[1]; | |||
back[1] = back[0]; | |||
back[0] = key; | |||
} | |||
static unsigned char _pop_key(void) | |||
{ | |||
unsigned char key = back[0]; | |||
back[0] = back[1]; | |||
back[1] = back[2]; | |||
back[2] = back[3]; | |||
back[3] = back[4]; | |||
return key; | |||
} | |||
static void _push_key(unsigned char); | |||
static unsigned char _pop_key(void); | |||
static unsigned char _read_key(void); | |||
static unsigned char _read_key(void) | |||
{ | |||
#if defined(USE_SLANG) | |||
return SLang_input_pending(0) ? SLang_getkey() : 0; | |||
#elif defined(USE_NCURSES) | |||
unsigned char key = getch(); | |||
return (key == ERR) ? 0 : key; | |||
#elif defined(USE_CONIO) | |||
return _conio_kbhit() ? getch() : 0; | |||
#endif | |||
} | |||
static unsigned char back[5] = {0, 0, 0, 0, 0}; | |||
int caca_get_key(void) | |||
int caca_get_event(void) | |||
{ | |||
unsigned char key[5]; | |||
unsigned char key[6]; | |||
/* If there were legacy keys, pop them */ | |||
key[0] = _pop_key(); | |||
if(key[0]) | |||
return key[0]; | |||
return CACA_EVENT_KEY_PRESS | key[0]; | |||
key[0] = _read_key(); | |||
if(!key[0]) | |||
return 0; | |||
if(key[0] != 0x1b) | |||
return key[0]; | |||
return CACA_EVENT_KEY_PRESS | key[0]; | |||
/* | |||
* Handle escape sequences | |||
*/ | |||
key[1] = _read_key(); | |||
if(!key[1]) | |||
return key[0]; | |||
return CACA_EVENT_KEY_PRESS | key[0]; | |||
key[2] = _read_key(); | |||
if(!key[2]) | |||
{ | |||
_push_key(key[1]); | |||
return key[0]; | |||
return CACA_EVENT_KEY_PRESS | key[0]; | |||
} | |||
if(key[1] == 0x4f) | |||
if(key[1] == 'O') | |||
{ | |||
switch(key[2]) | |||
{ | |||
case 0x50: return CACA_KEY_F1; | |||
case 0x51: return CACA_KEY_F2; | |||
case 0x52: return CACA_KEY_F3; | |||
case 0x53: return CACA_KEY_F4; | |||
case 'P': return CACA_EVENT_KEY_PRESS | CACA_KEY_F1; | |||
case 'Q': return CACA_EVENT_KEY_PRESS | CACA_KEY_F2; | |||
case 'R': return CACA_EVENT_KEY_PRESS | CACA_KEY_F3; | |||
case 'S': return CACA_EVENT_KEY_PRESS | CACA_KEY_F4; | |||
} | |||
} | |||
else if(key[1] == 0x5b) | |||
else if(key[1] == '[') | |||
{ | |||
switch(key[2]) | |||
{ | |||
case 0x41: return CACA_KEY_UP; | |||
case 0x42: return CACA_KEY_DOWN; | |||
case 0x43: return CACA_KEY_LEFT; | |||
case 0x44: return CACA_KEY_RIGHT; | |||
case 'A': return CACA_EVENT_KEY_PRESS | CACA_KEY_UP; | |||
case 'B': return CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN; | |||
case 'C': return CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT; | |||
case 'D': return CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT; | |||
} | |||
key[3] = _read_key(); | |||
key[4] = _read_key(); | |||
if(key[2] == 0x31 && key[4] == 0x7e) | |||
if(key[2] == 'M') | |||
{ | |||
int event = CACA_EVENT_MOUSE_CLICK; | |||
key[5] = _read_key(); | |||
event |= (int)(key[3] - ' ') << 8; | |||
event |= (int)(key[4] - ' ') << 4; | |||
event |= (int)(key[5] - ' ') << 0; | |||
return event; | |||
} | |||
if(key[2] == '1' && key[4] == '~') | |||
switch(key[3]) | |||
{ | |||
case 0x35: return CACA_KEY_F5; | |||
case 0x37: return CACA_KEY_F6; | |||
case 0x38: return CACA_KEY_F7; | |||
case 0x39: return CACA_KEY_F8; | |||
case '5': return CACA_EVENT_KEY_PRESS | CACA_KEY_F5; | |||
case '7': return CACA_EVENT_KEY_PRESS | CACA_KEY_F6; | |||
case '8': return CACA_EVENT_KEY_PRESS | CACA_KEY_F7; | |||
case '9': return CACA_EVENT_KEY_PRESS | CACA_KEY_F8; | |||
} | |||
if(key[2] == 0x32 && key[4] == 0x7e) | |||
if(key[2] == '2' && key[4] == '~') | |||
switch(key[3]) | |||
{ | |||
case 0x30: return CACA_KEY_F9; | |||
case 0x31: return CACA_KEY_F10; | |||
case 0x33: return CACA_KEY_F11; | |||
case 0x34: return CACA_KEY_F12; | |||
case '0': return CACA_EVENT_KEY_PRESS | CACA_KEY_F9; | |||
case '1': return CACA_EVENT_KEY_PRESS | CACA_KEY_F10; | |||
case '3': return CACA_EVENT_KEY_PRESS | CACA_KEY_F11; | |||
case '4': return CACA_EVENT_KEY_PRESS | CACA_KEY_F12; | |||
} | |||
_push_key(key[4]); | |||
_push_key(key[3]); | |||
} | |||
/* Unknown escape sequence: return 0 */ | |||
/* Unknown escape sequence: return each key one after the other */ | |||
_push_key(key[2]); | |||
_push_key(key[1]); | |||
return key[0]; | |||
return CACA_EVENT_KEY_PRESS | key[0]; | |||
} | |||
static void _push_key(unsigned char key) | |||
{ | |||
back[4] = back[3]; | |||
back[3] = back[2]; | |||
back[2] = back[1]; | |||
back[1] = back[0]; | |||
back[0] = key; | |||
} | |||
static unsigned char _pop_key(void) | |||
{ | |||
unsigned char key = back[0]; | |||
back[0] = back[1]; | |||
back[1] = back[2]; | |||
back[2] = back[3]; | |||
back[3] = back[4]; | |||
return key; | |||
} | |||
static unsigned char _read_key(void) | |||
{ | |||
#if defined(USE_SLANG) | |||
return SLang_input_pending(0) ? SLang_getkey() : 0; | |||
#elif defined(USE_NCURSES) | |||
unsigned char key = getch(); | |||
return (key == ERR) ? 0 : key; | |||
#elif defined(USE_CONIO) | |||
return _conio_kbhit() ? getch() : 0; | |||
#endif | |||
} | |||