Selaa lähdekoodia

* src/io.c:

+ Use SLkp_getkey instead of SLang_getkey so that escape sequences are
      directly interpreted.
    + Major rehandling of the event code. All output drivers are now
      correctly separated.
  * src/graphics.c:
    + Fixed a compilation warning.
  * test/event.c:
    + More human-readable event printing.
tags/v0.99.beta14
Sam Hocevar sam 21 vuotta sitten
vanhempi
commit
b287496ea5
3 muutettua tiedostoa jossa 175 lisäystä ja 223 poistoa
  1. +3
    -0
      src/graphics.c
  2. +167
    -218
      src/io.c
  3. +5
    -5
      test/event.c

+ 3
- 0
src/graphics.c Näytä tiedosto

@@ -47,6 +47,9 @@
#endif
#if defined(USE_X11)
# include <X11/Xlib.h>
# if defined(HAVE_X11_XKBLIB_H)
# include <X11/XKBlib.h>
# endif
#endif

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)


+ 167
- 218
src/io.c Näytä tiedosto

@@ -54,15 +54,14 @@
#include "caca_internals.h"

static unsigned int _get_next_event(void);
static void _push_key(unsigned int);
static unsigned int _pop_key(void);
static unsigned int _read_key(void);
static void _push_event(unsigned int);
static unsigned int _pop_event(void);

#if !defined(_DOXYGEN_SKIP_ME)
#define KEY_BUFLEN 10
#define EVENTBUF_LEN 10
#endif
static unsigned int keybuf[KEY_BUFLEN + 1]; /* zero-terminated */
static int keys = 0;
static unsigned int eventbuf[EVENTBUF_LEN];
static int events = 0;

/** \brief Get the next mouse or keyboard input event.
*
@@ -115,7 +114,10 @@ unsigned int caca_wait_event(unsigned int event_mask)

static unsigned int _get_next_event(void)
{
unsigned int event = 0;
unsigned int event = _pop_event();

if(event)
return event;

#if defined(USE_X11)
/* The X11 event check routine */
@@ -200,136 +202,132 @@ static unsigned int _get_next_event(void)

return 0;
}
else
#endif

/* Read all available key events and push them into the buffer */
while(keys < KEY_BUFLEN)
{
unsigned int key = _read_key();
if(!key)
break;
_push_key(key);
}

/* If no keys were read, return */
if(!keys)
return 0;

#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
{
if(keybuf[0] == KEY_MOUSE)
int intkey = getch();
if(intkey == ERR)
return 0;

if(intkey < 0x100)
{
_push_event(CACA_EVENT_KEY_RELEASE | intkey);
return CACA_EVENT_KEY_PRESS | intkey;
}

if(intkey == KEY_MOUSE)
{
MEVENT mevent;
_pop_key();
getmouse(&mevent);

switch(mevent.bstate)
{
case BUTTON1_PRESSED:
_push_key(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
break;
case BUTTON1_RELEASED:
_push_key(CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_CLICKED:
_push_key(CACA_EVENT_MOUSE_PRESS | 1);
_push_key(CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(CACA_EVENT_MOUSE_PRESS | 1);
_push_event(CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_RESERVED_EVENT:
break;

case BUTTON2_PRESSED:
_push_key(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
break;
case BUTTON2_RELEASED:
_push_key(CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_CLICKED:
_push_key(CACA_EVENT_MOUSE_PRESS | 2);
_push_key(CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(CACA_EVENT_MOUSE_PRESS | 2);
_push_event(CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_RESERVED_EVENT:
break;

case BUTTON3_PRESSED:
_push_key(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
break;
case BUTTON3_RELEASED:
_push_key(CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_CLICKED:
_push_key(CACA_EVENT_MOUSE_PRESS | 3);
_push_key(CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(CACA_EVENT_MOUSE_PRESS | 3);
_push_event(CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_RESERVED_EVENT:
break;

case BUTTON4_PRESSED:
_push_key(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
break;
case BUTTON4_RELEASED:
_push_key(CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_CLICKED:
_push_key(CACA_EVENT_MOUSE_PRESS | 4);
_push_key(CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(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);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(CACA_EVENT_MOUSE_PRESS | 4);
_push_event(CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_RESERVED_EVENT:
break;
@@ -341,173 +339,124 @@ static unsigned int _get_next_event(void)
return CACA_EVENT_MOUSE_MOTION | (mevent.x << 12) | mevent.y;
}

switch(keybuf[0])
switch(intkey)
{
case KEY_UP: event = CACA_EVENT_KEY_PRESS | CACA_KEY_UP; break;
case KEY_DOWN: event = CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN; break;
case KEY_LEFT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT; break;
case KEY_RIGHT: event = CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT; break;
case KEY_F(1): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F1; break;
case KEY_F(2): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F2; break;
case KEY_F(3): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F3; break;
case KEY_F(4): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F4; break;
case KEY_F(5): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F5; break;
case KEY_F(6): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F6; break;
case KEY_F(7): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F7; break;
case KEY_F(8): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F8; break;
case KEY_F(9): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F9; break;
case KEY_F(10): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F10; break;
case KEY_F(11): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F11; break;
case KEY_F(12): event = CACA_EVENT_KEY_PRESS | CACA_KEY_F12; break;
case KEY_UP: event = CACA_KEY_UP; break;
case KEY_DOWN: event = CACA_KEY_DOWN; break;
case KEY_LEFT: event = CACA_KEY_LEFT; break;
case KEY_RIGHT: event = CACA_KEY_RIGHT; break;
case KEY_F(1): event = CACA_KEY_F1; break;
case KEY_F(2): event = CACA_KEY_F2; break;
case KEY_F(3): event = CACA_KEY_F3; break;
case KEY_F(4): event = CACA_KEY_F4; break;
case KEY_F(5): event = CACA_KEY_F5; break;
case KEY_F(6): event = CACA_KEY_F6; break;
case KEY_F(7): event = CACA_KEY_F7; break;
case KEY_F(8): event = CACA_KEY_F8; break;
case KEY_F(9): event = CACA_KEY_F9; break;
case KEY_F(10): event = CACA_KEY_F10; break;
case KEY_F(11): event = CACA_KEY_F11; break;
case KEY_F(12): event = CACA_KEY_F12; break;
}

if(event)
{
_pop_key();
if(event & CACA_EVENT_KEY_PRESS)
_push_key(CACA_EVENT_KEY_RELEASE
| (event & ~CACA_EVENT_KEY_PRESS));
return event;
}
_push_event(CACA_EVENT_KEY_RELEASE | event);
return CACA_EVENT_KEY_PRESS | event;
}
else
#endif
#if defined(USE_SLANG)
if(_caca_driver == CACA_DRIVER_SLANG)
{
int intkey;

/* If it's already a special event, return it */
if((keybuf[0] & ~0xff) != 0)
return _pop_key();
if(!SLang_input_pending(0))
return 0;

/* If it's not an escape sequence, return the key */
if(keybuf[0] != '\x1b')
{
event = _pop_key();
_push_key(CACA_EVENT_KEY_RELEASE | event);
return CACA_EVENT_KEY_PRESS | event;
}
intkey = SLkp_getkey();

/*
* Handle known escape sequences
*/
if(intkey < 0x100)
{
_push_event(CACA_EVENT_KEY_RELEASE | intkey);
return CACA_EVENT_KEY_PRESS | intkey;
}

_pop_key();
if(intkey == 0x3e9)
{
int button = (SLang_getkey() - ' ' + 1) & 0xf;
int x = SLang_getkey() - '!';
int y = SLang_getkey() - '!';
_push_event(CACA_EVENT_MOUSE_PRESS | button);
_push_event(CACA_EVENT_MOUSE_RELEASE | button);
return CACA_EVENT_MOUSE_MOTION | (x << 12) | (y << 0);
}

if(keybuf[0] == 'O' && keybuf[1] >= 'P' && keybuf[1] <= 'S')
{
/* ^[OP ^[OQ ^[OR ^[OS */
static unsigned int keylist[] =
{ CACA_KEY_F1, CACA_KEY_F2, CACA_KEY_F3, CACA_KEY_F4 };
_pop_key();
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')
{
/* ^[[A ^[[B ^[[C ^[[D */
static unsigned int keylist[] =
{ CACA_KEY_UP, CACA_KEY_DOWN, CACA_KEY_RIGHT, CACA_KEY_LEFT };
_pop_key();
event = keylist[_pop_key() - 'A'];
_push_key(CACA_EVENT_KEY_RELEASE | event);
switch(intkey)
{
case SL_KEY_UP: event = CACA_KEY_UP; break;
case SL_KEY_DOWN: event = CACA_KEY_DOWN; break;
case SL_KEY_LEFT: event = CACA_KEY_LEFT; break;
case SL_KEY_RIGHT: event = CACA_KEY_RIGHT; break;

case SL_KEY_F(1): event = CACA_KEY_F1; break;
case SL_KEY_F(2): event = CACA_KEY_F2; break;
case SL_KEY_F(3): event = CACA_KEY_F3; break;
case SL_KEY_F(4): event = CACA_KEY_F4; break;
case SL_KEY_F(5): event = CACA_KEY_F5; break;
case SL_KEY_F(6): event = CACA_KEY_F6; break;
case SL_KEY_F(7): event = CACA_KEY_F7; break;
case SL_KEY_F(8): event = CACA_KEY_F8; break;
case SL_KEY_F(9): event = CACA_KEY_F9; break;
case SL_KEY_F(10): event = CACA_KEY_F10; break;
case SL_KEY_F(11): event = CACA_KEY_F11; break;
case SL_KEY_F(12): event = CACA_KEY_F12; break;
}

_push_event(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();
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);
}
else if(keybuf[0] == '[' && keybuf[1] == '1' && keybuf[3] == '~' &&
keybuf[2] >= '5' && keybuf[2] != '6' && keybuf[2] <= '9')
else
#endif
#if defined(USE_CONIO)
if(_caca_driver == CACA_DRIVER_CONIO)
{
/* ^[[15~ ^[[17~ ^[[18~ ^[[19~ */
static unsigned int keylist[] =
{ CACA_KEY_F5, 0, CACA_KEY_F6, CACA_KEY_F7, CACA_KEY_F8 };
_pop_key();
_pop_key();
event = keylist[_pop_key() - '5'];
_pop_key();
_push_key(CACA_EVENT_KEY_RELEASE | event);
if(!_conio_kbhit())
return 0;

event = getch();
_push_event(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')
else
#endif
{
/* ^[[20~ ^[[21~ ^[[23~ ^[[24~ */
static unsigned int keylist[] =
{ CACA_KEY_F9, CACA_KEY_F10, 0, CACA_KEY_F11, CACA_KEY_F12 };
_pop_key();
_pop_key();
event = keylist[_pop_key() - '0'];
_pop_key();
_push_key(CACA_EVENT_KEY_RELEASE | event);
return CACA_EVENT_KEY_PRESS | event;
/* Dummy */
}

/* Unknown escape sequence: return the ESC key */
_push_key(CACA_EVENT_KEY_RELEASE | '\x1b');
return CACA_EVENT_KEY_PRESS | '\x1b';
return 0;
}

static void _push_key(unsigned int key)
static void _push_event(unsigned int event)
{
if(keys == KEY_BUFLEN)
if(events == EVENTBUF_LEN)
return;
keybuf[keys] = key;
keys++;
keybuf[keys] = 0;
eventbuf[events] = event;
events++;
}

static unsigned int _pop_key(void)
static unsigned int _pop_event(void)
{
int i;
unsigned int key = keybuf[0];
keys--;
for(i = 0; i < keys; i++)
keybuf[i] = keybuf[i + 1];
keybuf[keys] = 0;

return key;
}
unsigned int event;

static unsigned int _read_key(void)
{
#if defined(USE_NCURSES)
int intkey;
#endif
#if defined(USE_X11)
#endif
if(events == 0)
return 0;

switch(_caca_driver)
{
#if defined(USE_SLANG)
case CACA_DRIVER_SLANG:
return SLang_input_pending(0) ? SLang_getkey() : 0;
#endif
#if defined(USE_NCURSES)
case CACA_DRIVER_NCURSES:
intkey = getch();
return (intkey == ERR) ? 0 : intkey;
#endif
#if defined(USE_CONIO)
case CACA_DRIVER_CONIO:
return _conio_kbhit() ? getch() : 0;
#endif
#if defined(USE_X11)
case CACA_DRIVER_X11:
#endif
default:
break;
}
event = eventbuf[0];
for(i = 1; i < events; i++)
eventbuf[i - 1] = eventbuf[i];
events--;

return 0;
return event;
}


+ 5
- 5
test/event.c Näytä tiedosto

@@ -91,23 +91,23 @@ static void print_event(int x, int y, unsigned int event)
caca_printf(x, y, "CACA_EVENT_NONE");
break;
case CACA_EVENT_KEY_PRESS:
caca_printf(x, y, "CACA_EVENT_KEY_PRESS 0x%06x",
caca_printf(x, y, "CACA_EVENT_KEY_PRESS 0x%x",
event & 0x00ffffff);
break;
case CACA_EVENT_KEY_RELEASE:
caca_printf(x, y, "CACA_EVENT_KEY_RELEASE 0x%06x",
caca_printf(x, y, "CACA_EVENT_KEY_RELEASE 0x%x",
event & 0x00ffffff);
break;
case CACA_EVENT_MOUSE_MOTION:
caca_printf(x, y, "CACA_EVENT_MOUSE_MOTION 0x%03x 0x%03x",
caca_printf(x, y, "CACA_EVENT_MOUSE_MOTION %u %u",
(event & 0x00fff000) >> 12, event & 0x00000fff);
break;
case CACA_EVENT_MOUSE_PRESS:
caca_printf(x, y, "CACA_EVENT_MOUSE_PRESS 0x%06x",
caca_printf(x, y, "CACA_EVENT_MOUSE_PRESS %u",
event & 0x00ffffff);
break;
case CACA_EVENT_MOUSE_RELEASE:
caca_printf(x, y, "CACA_EVENT_MOUSE_RELEASE 0x%06x",
caca_printf(x, y, "CACA_EVENT_MOUSE_RELEASE %u",
event & 0x00ffffff);
break;
default:


Ladataan…
Peruuta
Tallenna