source: libcaca/branches/0.1/src/io.c @ 4891

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