source: libcaca/trunk/src/io.c @ 203

Last change on this file since 203 was 203, checked in by Sam Hocevar, 17 years ago
  • src/io.c: + Fixed an off-by-one error in the mouse driver.
  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1/*
2 *   libcaca       ASCII-Art library
3 *   Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: io.c 203 2003-11-21 14:14:26Z sam $
7 *
8 *   This library is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU Lesser General Public
10 *   License as published by the Free Software Foundation; either
11 *   version 2 of the License, or (at your option) any later version.
12 *
13 *   This library is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *   Lesser General Public License for more details.
17 *
18 *   You should have received a copy of the GNU Lesser General Public
19 *   License along with this library; if not, write to the Free Software
20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *   02111-1307  USA
22 */
23
24#include "config.h"
25
26#if defined(USE_SLANG)
27#   include <slang.h>
28#elif defined(USE_NCURSES)
29#   include <curses.h>
30#elif defined(USE_CONIO)
31#   include <conio.h>
32#else
33#   error "no graphics library detected"
34#endif
35
36#include "caca.h"
37#include "caca_internals.h"
38
39static void _push_key(unsigned char);
40static unsigned char _pop_key(void);
41static unsigned char _read_key(void);
42
43static unsigned char back[5] = {0, 0, 0, 0, 0};
44
45int caca_get_event(void)
46{
47    unsigned char key[6];
48
49    /* If there were legacy keys, pop them */
50    key[0] = _pop_key();
51    if(key[0])
52        return CACA_EVENT_KEY_PRESS | key[0];
53
54    key[0] = _read_key();
55    if(!key[0])
56        return 0;
57
58    if(key[0] != 0x1b)
59        return CACA_EVENT_KEY_PRESS | key[0];
60
61    /*
62     * Handle escape sequences
63     */
64
65    key[1] = _read_key();
66    if(!key[1])
67        return CACA_EVENT_KEY_PRESS | key[0];
68
69    key[2] = _read_key();
70    if(!key[2])
71    {
72        _push_key(key[1]);
73        return CACA_EVENT_KEY_PRESS | key[0];
74    }
75
76    if(key[1] == 'O')
77    {
78        /* ^[OP ^[OQ ^[OR ^[OS */
79        switch(key[2])
80        {
81        case 'P': return CACA_EVENT_KEY_PRESS | CACA_KEY_F1;
82        case 'Q': return CACA_EVENT_KEY_PRESS | CACA_KEY_F2;
83        case 'R': return CACA_EVENT_KEY_PRESS | CACA_KEY_F3;
84        case 'S': return CACA_EVENT_KEY_PRESS | CACA_KEY_F4;
85        }
86    }
87    else if(key[1] == '[')
88    {
89        /* ^[[A ^[[B ^[[C ^[[D */
90        switch(key[2])
91        {
92        case 'A': return CACA_EVENT_KEY_PRESS | CACA_KEY_UP;
93        case 'B': return CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN;
94        case 'C': return CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT;
95        case 'D': return CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT;
96        }
97
98        key[3] = _read_key();
99        key[4] = _read_key();
100
101        /* ^[[Mxxx */
102        if(key[2] == 'M')
103        {
104            int event = CACA_EVENT_MOUSE_CLICK;
105
106            key[5] = _read_key();
107
108            event |= (int)(key[3] - ' ') << 16;
109            event |= (int)(key[4] - '!') << 8;
110            event |= (int)(key[5] - '!') << 0;
111
112            return event;
113        }
114
115        /* ^[[15~ ^[[17~ ^[[18~ ^[[19~ */
116        if(key[2] == '1' && key[4] == '~')
117            switch(key[3])
118            {
119            case '5': return CACA_EVENT_KEY_PRESS | CACA_KEY_F5;
120            case '7': return CACA_EVENT_KEY_PRESS | CACA_KEY_F6;
121            case '8': return CACA_EVENT_KEY_PRESS | CACA_KEY_F7;
122            case '9': return CACA_EVENT_KEY_PRESS | CACA_KEY_F8;
123            }
124
125        /* ^[[20~ ^[[21~ ^[[23~ ^[[24~ */
126        if(key[2] == '2' && key[4] == '~')
127            switch(key[3])
128            {
129            case '0': return CACA_EVENT_KEY_PRESS | CACA_KEY_F9;
130            case '1': return CACA_EVENT_KEY_PRESS | CACA_KEY_F10;
131            case '3': return CACA_EVENT_KEY_PRESS | CACA_KEY_F11;
132            case '4': return CACA_EVENT_KEY_PRESS | CACA_KEY_F12;
133            }
134
135        _push_key(key[4]);
136        _push_key(key[3]);
137    }
138
139    /* Unknown escape sequence: return each key one after the other */
140    _push_key(key[2]);
141    _push_key(key[1]);
142    return CACA_EVENT_KEY_PRESS | key[0];
143}
144
145static void _push_key(unsigned char key)
146{
147    back[4] = back[3];
148    back[3] = back[2];
149    back[2] = back[1];
150    back[1] = back[0];
151    back[0] = key;
152}
153
154static unsigned char _pop_key(void)
155{
156    unsigned char key = back[0];
157    back[0] = back[1];
158    back[1] = back[2];
159    back[2] = back[3];
160    back[3] = back[4];
161    return key;
162}
163
164static unsigned char _read_key(void)
165{
166#if defined(USE_SLANG)
167    return SLang_input_pending(0) ? SLang_getkey() : 0;
168#elif defined(USE_NCURSES)
169    unsigned char key = getch();
170    return (key == ERR) ? 0 : key;
171#elif defined(USE_CONIO)
172    return _conio_kbhit() ? getch() : 0;
173#endif
174}
175
Note: See TracBrowser for help on using the repository browser.