From bf8f9744a4a2c4a7f104cc1ec3ef039c7b9fcb7e Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 7 Jan 2004 17:19:36 +0000 Subject: [PATCH] * test/event.c: + Small event lister, similar to X11's xev. * src/graphics.c: + If possible, disable autorepeat in the X11 driver. * src/io.c: + Implemented CACA_EVENT_MOUSE_RELEASE in all drivers. + Button number support in CACA_EVENT_MOUSE_{PRESS,RELEASE}. --- configure.ac | 1 + src/caca.c | 3 +- src/graphics.c | 17 +++++- src/io.c | 156 +++++++++++++++++++++++++++++++++++++++++++---- test/Makefile.am | 6 +- test/event.c | 117 +++++++++++++++++++++++++++++++++++ 6 files changed, 286 insertions(+), 14 deletions(-) create mode 100644 test/event.c diff --git a/configure.ac b/configure.ac index 417b09e..31dc542 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,7 @@ if test "${enable_x11}" != "no"; then CACA_DRIVERS="${CACA_DRIVERS} x11"], [ac_cv_my_have_x11="no"], [[-lXt -L${x_libraries}]]) + AC_CHECK_HEADERS(X11/XKBlib.h) if test "${ac_cv_my_have_x11}" != "yes" -a "${enable_x11}" = "yes"; then AC_MSG_ERROR([cannot find X11 development files]) fi diff --git a/src/caca.c b/src/caca.c index f923cb4..2ad23d1 100644 --- a/src/caca.c +++ b/src/caca.c @@ -137,8 +137,9 @@ int caca_init(void) curs_set(0); /* Activate mouse */ - newmask = ALL_MOUSE_EVENTS; + newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS; mousemask(newmask, &oldmask); + mouseinterval(-1); /* No click emulation */ } else #endif diff --git a/src/graphics.c b/src/graphics.c index fbfa24c..034cc15 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -156,6 +156,9 @@ static int x11_colors[16]; static Font x11_font; static XFontStruct *x11_font_struct; static int x11_font_offset; +#if defined(HAVE_X11_XKBLIB_H) +static Bool x11_detect_autorepeat; +#endif #endif static char *_caca_empty_line; @@ -714,8 +717,16 @@ int _caca_init_graphics(void) break; } + /* Disable autorepeat */ +#if defined(HAVE_X11_XKBLIB_H) + XkbSetDetectableAutoRepeat(x11_dpy, True, &x11_detect_autorepeat); + if(!x11_detect_autorepeat) + XAutoRepeatOff(x11_dpy); +#endif + XSelectInput(x11_dpy, x11_window, - KeyPressMask | ButtonPressMask | PointerMotionMask); + KeyPressMask | KeyReleaseMask | ButtonPressMask + | ButtonReleaseMask | PointerMotionMask); XSync(x11_dpy, False); @@ -762,6 +773,10 @@ int _caca_end_graphics(void) if(_caca_driver == CACA_DRIVER_X11) { XSync(x11_dpy, False); +#if defined(HAVE_X11_XKBLIB_H) + if(!x11_detect_autorepeat) + XAutoRepeatOn(x11_dpy); +#endif XFreePixmap(x11_dpy, x11_pixmap); XFreeFont(x11_dpy, x11_font_struct); XFreeGC(x11_dpy, x11_gc); diff --git a/src/io.c b/src/io.c index 2775c3e..dd61951 100644 --- a/src/io.c +++ b/src/io.c @@ -154,10 +154,12 @@ static unsigned int _get_next_event(void) /* Check for mouse press and release events */ if(xevent.type == ButtonPress) - return CACA_EVENT_MOUSE_PRESS | 1; + return CACA_EVENT_MOUSE_PRESS + | ((XButtonEvent *)&xevent)->button; if(xevent.type == ButtonRelease) - return CACA_EVENT_MOUSE_RELEASE | 1; + return CACA_EVENT_MOUSE_RELEASE + | ((XButtonEvent *)&xevent)->button; /* Check for key press and release events */ if(xevent.type == KeyPress) @@ -221,7 +223,121 @@ static unsigned int _get_next_event(void) MEVENT mevent; _pop_key(); getmouse(&mevent); - _push_key(CACA_EVENT_MOUSE_PRESS | 1); + + switch(mevent.bstate) + { + case BUTTON1_PRESSED: + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + break; + case BUTTON1_RELEASED: + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + break; + case BUTTON1_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + break; + case BUTTON1_DOUBLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + break; + case BUTTON1_TRIPLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + _push_key(CACA_EVENT_MOUSE_PRESS | 1); + _push_key(CACA_EVENT_MOUSE_RELEASE | 1); + break; + case BUTTON1_RESERVED_EVENT: + break; + + case BUTTON2_PRESSED: + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + break; + case BUTTON2_RELEASED: + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + break; + case BUTTON2_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + break; + case BUTTON2_DOUBLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + break; + case BUTTON2_TRIPLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + _push_key(CACA_EVENT_MOUSE_PRESS | 2); + _push_key(CACA_EVENT_MOUSE_RELEASE | 2); + break; + case BUTTON2_RESERVED_EVENT: + break; + + case BUTTON3_PRESSED: + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + break; + case BUTTON3_RELEASED: + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + break; + case BUTTON3_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + break; + case BUTTON3_DOUBLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + break; + case BUTTON3_TRIPLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + _push_key(CACA_EVENT_MOUSE_PRESS | 3); + _push_key(CACA_EVENT_MOUSE_RELEASE | 3); + break; + case BUTTON3_RESERVED_EVENT: + break; + + case BUTTON4_PRESSED: + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + break; + case BUTTON4_RELEASED: + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + break; + case BUTTON4_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + break; + case BUTTON4_DOUBLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + break; + case BUTTON4_TRIPLE_CLICKED: + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + _push_key(CACA_EVENT_MOUSE_PRESS | 4); + _push_key(CACA_EVENT_MOUSE_RELEASE | 4); + break; + case BUTTON4_RESERVED_EVENT: + break; + + default: + break; + } + return CACA_EVENT_MOUSE_MOTION | (mevent.x << 12) | mevent.y; } @@ -249,6 +365,9 @@ static unsigned int _get_next_event(void) if(event) { _pop_key(); + if(event & CACA_EVENT_KEY_PRESS) + _push_key(CACA_EVENT_KEY_RELEASE + | (event & ~CACA_EVENT_KEY_PRESS)); return event; } } @@ -260,7 +379,11 @@ static unsigned int _get_next_event(void) /* If it's not an escape sequence, return the key */ if(keybuf[0] != '\x1b') - return CACA_EVENT_KEY_PRESS | _pop_key(); + { + event = _pop_key(); + _push_key(CACA_EVENT_KEY_RELEASE | event); + return CACA_EVENT_KEY_PRESS | event; + } /* * Handle known escape sequences @@ -274,7 +397,9 @@ static unsigned int _get_next_event(void) static unsigned int keylist[] = { CACA_KEY_F1, CACA_KEY_F2, CACA_KEY_F3, CACA_KEY_F4 }; _pop_key(); - return CACA_EVENT_KEY_PRESS | keylist[_pop_key() - 'P']; + event = keylist[_pop_key() - 'P']; + _push_key(CACA_EVENT_KEY_RELEASE | event); + return CACA_EVENT_KEY_PRESS | event; } else if(keybuf[0] == '[' && keybuf[1] >= 'A' && keybuf[1] <= 'D') { @@ -282,15 +407,21 @@ static unsigned int _get_next_event(void) static unsigned int keylist[] = { CACA_KEY_UP, CACA_KEY_DOWN, CACA_KEY_RIGHT, CACA_KEY_LEFT }; _pop_key(); - return CACA_EVENT_KEY_PRESS | keylist[_pop_key() - 'A']; + event = keylist[_pop_key() - 'A']; + _push_key(CACA_EVENT_KEY_RELEASE | event); + return CACA_EVENT_KEY_PRESS | event; } else if(keybuf[0] == '[' && keybuf[1] == 'M' && keybuf[2] && keybuf[3] && keybuf[3]) { + int button; + /* ^[[Mxxx */ _pop_key(); _pop_key(); - _push_key(CACA_EVENT_MOUSE_PRESS | (_pop_key() - ' ')); + button = (1 + _pop_key() - ' ') & 0xf; + _push_key(CACA_EVENT_MOUSE_PRESS | button); + _push_key(CACA_EVENT_MOUSE_RELEASE | button); return CACA_EVENT_MOUSE_MOTION | ((_pop_key() - '!') << 12) | ((_pop_key() - '!') << 0); } @@ -302,9 +433,10 @@ static unsigned int _get_next_event(void) { CACA_KEY_F5, 0, CACA_KEY_F6, CACA_KEY_F7, CACA_KEY_F8 }; _pop_key(); _pop_key(); - event = CACA_EVENT_KEY_PRESS | keylist[_pop_key() - '5']; + event = keylist[_pop_key() - '5']; _pop_key(); - return event; + _push_key(CACA_EVENT_KEY_RELEASE | event); + return CACA_EVENT_KEY_PRESS | event; } else if(keybuf[0] == '[' && keybuf[1] == '2' && keybuf[3] == '~' && keybuf[2] >= '0' && keybuf[2] != '2' && keybuf[2] <= '4') @@ -314,12 +446,14 @@ static unsigned int _get_next_event(void) { CACA_KEY_F9, CACA_KEY_F10, 0, CACA_KEY_F11, CACA_KEY_F12 }; _pop_key(); _pop_key(); - event = CACA_EVENT_KEY_PRESS | keylist[_pop_key() - '0']; + event = keylist[_pop_key() - '0']; _pop_key(); - return event; + _push_key(CACA_EVENT_KEY_RELEASE | event); + return CACA_EVENT_KEY_PRESS | event; } /* Unknown escape sequence: return the ESC key */ + _push_key(CACA_EVENT_KEY_RELEASE | '\x1b'); return CACA_EVENT_KEY_PRESS | '\x1b'; } diff --git a/test/Makefile.am b/test/Makefile.am index 1ea0055..6de4136 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,12 +2,16 @@ # Automake targets and declarations for libcaca test programs ############################################################################### -noinst_PROGRAMS = dithering hsv optipal spritedit +noinst_PROGRAMS = dithering event hsv optipal spritedit dithering_SOURCES = dithering.c dithering_LDADD = ../src/libcaca.a @CACA_LIBS@ dithering_CPPFLAGS = -I$(top_srcdir)/src +event_SOURCES = event.c +event_LDADD = ../src/libcaca.a @CACA_LIBS@ +event_CPPFLAGS = -I$(top_srcdir)/src + hsv_SOURCES = hsv.c hsv_LDADD = ../src/libcaca.a @CACA_LIBS@ hsv_CPPFLAGS = -I$(top_srcdir)/src diff --git a/test/event.c b/test/event.c new file mode 100644 index 0000000..0b80b4e --- /dev/null +++ b/test/event.c @@ -0,0 +1,117 @@ +/* + * event event lister for libcaca + * Copyright (c) 2004 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +#include "config.h" + +#include +#include + +#include "caca.h" + +static void print_event(int, int, unsigned int); + +int main(int argc, char **argv) +{ + int *events; + int i, h; + + if(caca_init()) + return 1; + + caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE); + caca_draw_line(0, 0, caca_get_width() - 1, 0, ' '); + + caca_refresh(); + + h = caca_get_height(); + + events = malloc(h * sizeof(int)); + memset(events, 0, h * sizeof(int)); + + for( ; ; ) + { + unsigned int event = caca_wait_event(CACA_EVENT_ANY); + + if(!event) + continue; + + memmove(events + 1, events, (h - 1) * sizeof(int)); + events[0] = event; + + caca_clear(); + + /* Print current event */ + caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE); + caca_draw_line(0, 0, caca_get_width() - 1, 0, ' '); + print_event(0, 0, event); + + /* Print previous events */ + caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLACK); + for(i = 1; i < h && events[i]; i++) + print_event(0, i, events[i]); + + /* q quits */ + if(event == (CACA_EVENT_KEY_PRESS | 'q')) + break; + + caca_refresh(); + } + + /* Clean up */ + caca_end(); + + return 0; +} + +static void print_event(int x, int y, unsigned int event) +{ + switch(event & 0xff000000) + { + case CACA_EVENT_NONE: + caca_printf(x, y, "CACA_EVENT_NONE"); + break; + case CACA_EVENT_KEY_PRESS: + caca_printf(x, y, "CACA_EVENT_KEY_PRESS 0x%06x", + event & 0x00ffffff); + break; + case CACA_EVENT_KEY_RELEASE: + caca_printf(x, y, "CACA_EVENT_KEY_RELEASE 0x%06x", + event & 0x00ffffff); + break; + case CACA_EVENT_MOUSE_MOTION: + caca_printf(x, y, "CACA_EVENT_MOUSE_MOTION 0x%03x 0x%03x", + (event & 0x00fff000) >> 12, event & 0x00000fff); + break; + case CACA_EVENT_MOUSE_PRESS: + caca_printf(x, y, "CACA_EVENT_MOUSE_PRESS 0x%06x", + event & 0x00ffffff); + break; + case CACA_EVENT_MOUSE_RELEASE: + caca_printf(x, y, "CACA_EVENT_MOUSE_RELEASE 0x%06x", + event & 0x00ffffff); + break; + default: + caca_printf(x, y, "CACA_EVENT_UNKNOWN"); + } +} +