+ 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 | |||
| } | |||