diff --git a/examples/demo.c b/examples/demo.c index e03e321..756d2d2 100644 --- a/examples/demo.c +++ b/examples/demo.c @@ -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(); } diff --git a/examples/spritedit.c b/examples/spritedit.c index 9707aad..3278c25 100644 --- a/examples/spritedit.c +++ b/examples/spritedit.c @@ -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(); diff --git a/src/blit.c b/src/blit.c index 26dcb28..ae8e0c3 100644 --- a/src/blit.c +++ b/src/blit.c @@ -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]); diff --git a/src/caca.c b/src/caca.c index dc6090a..83ae86d 100644 --- a/src/caca.c +++ b/src/caca.c @@ -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(); diff --git a/src/caca.h b/src/caca.h index 1a73063..8b36ffb 100644 --- a/src/caca.h +++ b/src/caca.h @@ -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); diff --git a/src/io.c b/src/io.c index ff0be94..a45f26b 100644 --- a/src/io.c +++ b/src/io.c @@ -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 }