+ 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/pikachu.jpeg", NULL); | ||||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/pix/gradient.png", 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/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/pix/dranac.jpeg", NULL); | ||||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/artwork/aboire.png", 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/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/lilkim02.jpg", NULL); | ||||
//pixbuf = gdk_pixbuf_new_from_file("/home/sam/etw.bmp", 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; | if(!pixbuf) return -2; | ||||
pixels = gdk_pixbuf_get_pixels(pixbuf); | pixels = gdk_pixbuf_get_pixels(pixbuf); | ||||
bufx = gdk_pixbuf_get_width(pixbuf); | bufx = gdk_pixbuf_get_width(pixbuf); | ||||
@@ -99,18 +101,18 @@ fprintf(stderr, "w %i, h %i, stride %i\n", bufx, bufy, bufpitch); | |||||
/* Go ! */ | /* Go ! */ | ||||
while(!quit) | while(!quit) | ||||
{ | { | ||||
char key = caca_get_key(); | |||||
int event = caca_get_event(); | |||||
if(key && demo) | |||||
if(event && demo) | |||||
{ | { | ||||
display_menu(); | display_menu(); | ||||
caca_refresh(); | caca_refresh(); | ||||
demo = NULL; | demo = NULL; | ||||
} | } | ||||
else if(key) | |||||
else if(event & CACA_EVENT_KEY_PRESS) | |||||
{ | { | ||||
handle_key: | handle_key: | ||||
switch(key) | |||||
switch(event & 0xff) | |||||
{ | { | ||||
case 'q': | case 'q': | ||||
case 'Q': | case 'Q': | ||||
@@ -170,9 +172,12 @@ fprintf(stderr, "w %i, h %i, stride %i\n", bufx, bufy, bufpitch); | |||||
if(demo) | if(demo) | ||||
caca_clear(); | caca_clear(); | ||||
key = caca_get_key(); | |||||
if(key) | |||||
handle_event: | |||||
event = caca_get_event(); | |||||
if(event & CACA_EVENT_KEY_PRESS) | |||||
goto handle_key; | goto handle_key; | ||||
else if(event) | |||||
goto handle_event; | |||||
caca_refresh(); | caca_refresh(); | ||||
} | } | ||||
@@ -56,22 +56,27 @@ int main(int argc, char **argv) | |||||
{ | { | ||||
int xa, ya, xb, yb; | int xa, ya, xb, yb; | ||||
char buf[BUFSIZ]; | 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(); | 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; | 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++) | 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 fromx = w * (x - x1) / (x2 - x1 + 1); | ||||
int fromy = h * (y - y1) / (y2 - y1 + 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 hue, sat, val; | ||||
int min = r, max = r, delta; | 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 | else | ||||
hue = 1280 + 256 * (r - g) / delta; | 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) | if(val > (_get_dither() + 40) * 4) | ||||
caca_set_color(light_colors[hue]); | caca_set_color(light_colors[hue]); | ||||
@@ -97,6 +97,8 @@ int caca_init(void) | |||||
SLang_init_tty(-1, 0, 1); | SLang_init_tty(-1, 0, 1); | ||||
SLkp_define_keysym("\e[M", 1001); | |||||
if(SLsmg_init_smg() == -1) | if(SLsmg_init_smg() == -1) | ||||
{ | { | ||||
SLsig_unblock_signals(); | SLsig_unblock_signals(); | ||||
@@ -107,6 +109,7 @@ int caca_init(void) | |||||
SLsmg_cls(); | SLsmg_cls(); | ||||
SLtt_set_cursor_visibility(0); | SLtt_set_cursor_visibility(0); | ||||
SLtt_set_mouse_mode (1, 0); | |||||
SLsmg_refresh(); | SLsmg_refresh(); | ||||
for(i = 0; i < 16; i++) | for(i = 0; i < 16; i++) | ||||
@@ -291,6 +294,7 @@ void caca_refresh(void) | |||||
void caca_end(void) | void caca_end(void) | ||||
{ | { | ||||
#if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
SLtt_set_mouse_mode(0, 0); | |||||
SLtt_set_cursor_visibility(1); | SLtt_set_cursor_visibility(1); | ||||
SLang_reset_tty(); | SLang_reset_tty(); | ||||
SLsmg_reset_smg(); | SLsmg_reset_smg(); | ||||
@@ -62,6 +62,17 @@ enum caca_dithering | |||||
CACA_DITHER_RANDOM | 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 | * Keys | ||||
*/ | */ | ||||
@@ -107,7 +118,7 @@ const char *caca_get_color_name(unsigned int); | |||||
void caca_refresh(void); | void caca_refresh(void); | ||||
void caca_end(void); | void caca_end(void); | ||||
int caca_get_key(void); | |||||
int caca_get_event(void); | |||||
void caca_set_color(enum caca_color); | void caca_set_color(enum caca_color); | ||||
enum caca_color caca_get_color(void); | enum caca_color caca_get_color(void); | ||||
@@ -36,111 +36,135 @@ | |||||
#include "caca.h" | #include "caca.h" | ||||
#include "caca_internals.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 */ | /* If there were legacy keys, pop them */ | ||||
key[0] = _pop_key(); | key[0] = _pop_key(); | ||||
if(key[0]) | if(key[0]) | ||||
return key[0]; | |||||
return CACA_EVENT_KEY_PRESS | key[0]; | |||||
key[0] = _read_key(); | key[0] = _read_key(); | ||||
if(!key[0]) | |||||
return 0; | |||||
if(key[0] != 0x1b) | if(key[0] != 0x1b) | ||||
return key[0]; | |||||
return CACA_EVENT_KEY_PRESS | key[0]; | |||||
/* | |||||
* Handle escape sequences | |||||
*/ | |||||
key[1] = _read_key(); | key[1] = _read_key(); | ||||
if(!key[1]) | if(!key[1]) | ||||
return key[0]; | |||||
return CACA_EVENT_KEY_PRESS | key[0]; | |||||
key[2] = _read_key(); | key[2] = _read_key(); | ||||
if(!key[2]) | if(!key[2]) | ||||
{ | { | ||||
_push_key(key[1]); | _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]) | 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]) | 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[3] = _read_key(); | ||||
key[4] = _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]) | 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]) | 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[4]); | ||||
_push_key(key[3]); | _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[2]); | ||||
_push_key(key[1]); | _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 | |||||
} | } | ||||