Root/src/inputmanager.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#include "debug.h"
22#include "inputmanager.h"
23#include "utilities.h"
24#include "powersaver.h"
25#include "menu.h"
26
27#include <iostream>
28#include <fstream>
29
30using namespace std;
31
32void InputManager::init(const string &conffile, Menu *menu) {
33    this->menu = menu;
34
35    for (int i = 0; i < BUTTON_TYPE_SIZE; i++) {
36        buttonMap[i].source = UNMAPPED;
37    }
38    readConfFile(conffile);
39}
40
41InputManager::InputManager()
42{
43#ifndef SDL_JOYSTICK_DISABLED
44    int i;
45
46    if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
47        ERROR("Unable to init joystick subsystem\n");
48        return;
49    }
50
51    for (i = 0; i < SDL_NumJoysticks(); i++) {
52        struct Joystick joystick = {
53            SDL_JoystickOpen(i), false, false, false, false,
54        };
55        joysticks.push_back(joystick);
56    }
57
58    DEBUG("Opening %i joysticks\n", i);
59#endif
60}
61
62InputManager::~InputManager()
63{
64#ifndef SDL_JOYSTICK_DISABLED
65    for (auto it : joysticks)
66        SDL_JoystickClose(it.joystick);
67#endif
68}
69
70void InputManager::readConfFile(const string &conffile) {
71    ifstream inf(conffile.c_str(), ios_base::in);
72    if (inf.fail()) {
73        ERROR("InputManager: failed to open config file\n");
74        return;
75    }
76
77    string line;
78    while (getline(inf, line, '\n')) {
79        string::size_type pos = line.find("=");
80        string name = trim(line.substr(0,pos));
81        line = trim(line.substr(pos+1,line.length()));
82
83        Button button;
84        if (name == "up") button = UP;
85        else if (name == "down") button = DOWN;
86        else if (name == "left") button = LEFT;
87        else if (name == "right") button = RIGHT;
88        else if (name == "accept") button = ACCEPT;
89        else if (name == "cancel") button = CANCEL;
90        else if (name == "altleft") button = ALTLEFT;
91        else if (name == "altright") button = ALTRIGHT;
92        else if (name == "menu") button = MENU;
93        else if (name == "settings") button = SETTINGS;
94        else {
95            WARNING("InputManager: Ignoring unknown button name \"%s\"\n",
96                    name.c_str());
97            continue;
98        }
99
100        pos = line.find(",");
101        string sourceStr = trim(line.substr(0,pos));
102        line = trim(line.substr(pos+1, line.length()));
103
104        ButtonSource source;
105        if (sourceStr == "keyboard") {
106            source = KEYBOARD;
107#ifndef SDL_JOYSTICK_DISABLED
108        } else if (sourceStr == "joystick") {
109            source = JOYSTICK;
110#endif
111        } else {
112            WARNING("InputManager: Ignoring unknown button source \"%s\"\n",
113                    sourceStr.c_str());
114            continue;
115        }
116        buttonMap[button].source = source;
117        buttonMap[button].code = atoi(line.c_str());
118    }
119
120    inf.close();
121}
122
123InputManager::Button InputManager::waitForPressedButton() {
124    Button button;
125    while (!getButton(&button, true));
126    return button;
127}
128
129bool InputManager::pollButton(Button *button) {
130    return getButton(button, false);
131}
132
133bool InputManager::getButton(Button *button, bool wait) {
134    //TODO: when an event is processed, program a new event
135    //in some time, and when it occurs, do a key repeat
136
137#ifndef SDL_JOYSTICK_DISABLED
138    if (joysticks.size() > 0)
139        SDL_JoystickUpdate();
140#endif
141
142    SDL_Event event;
143    if (wait)
144        SDL_WaitEvent(&event);
145    else if (!SDL_PollEvent(&event))
146        return false;
147
148    ButtonSource source;
149    switch(event.type) {
150        case SDL_KEYDOWN:
151            source = KEYBOARD;
152            break;
153#ifndef SDL_JOYSTICK_DISABLED
154        case SDL_JOYBUTTONDOWN:
155            source = JOYSTICK;
156            break;
157        case SDL_JOYAXISMOTION: {
158                source = JOYSTICK;
159
160                unsigned int axis = event.jaxis.axis;
161                /* We only handle the first joystick */
162                if (axis > 1)
163                    return false;
164
165                bool *axisState = joysticks[event.jaxis.which].axisState[axis];
166
167                if (event.jaxis.value < -20000) {
168                    if (axisState[AXIS_STATE_NEGATIVE])
169                        return false;
170                    axisState[AXIS_STATE_NEGATIVE] = true;
171                    axisState[AXIS_STATE_POSITIVE] = false;
172                    *button = axis ? UP : LEFT;
173                } else if (event.jaxis.value > 20000) {
174                    if (axisState[AXIS_STATE_POSITIVE])
175                        return false;
176                    axisState[AXIS_STATE_NEGATIVE] = false;
177                    axisState[AXIS_STATE_POSITIVE] = true;
178                    *button = axis ? DOWN : RIGHT;
179                } else {
180                    axisState[0] = axisState[1] = false;
181                    return false;
182                }
183                break;
184            }
185#endif
186        case SDL_USEREVENT:
187            switch ((enum EventCode) event.user.code) {
188#ifdef HAVE_LIBOPK
189                case REMOVE_LINKS:
190                    menu->removePackageLink((const char *) event.user.data1);
191                    break;
192                case OPEN_PACKAGE:
193                    menu->openPackage((const char *) event.user.data1);
194                    break;
195                case OPEN_PACKAGES_FROM_DIR:
196                    menu->openPackagesFromDir(
197                                ((string) (const char *) event.user.data1
198                                 + "/apps").c_str());
199                    break;
200#endif /* HAVE_LIBOPK */
201                case REPAINT_MENU:
202                default:
203                    break;
204            }
205
206            if (event.user.data1)
207                free(event.user.data1);
208            *button = REPAINT;
209            return true;
210
211        default:
212            return false;
213    }
214
215    int i = 0;
216    if (source == KEYBOARD) {
217        for (i = 0; i < BUTTON_TYPE_SIZE; i++) {
218            if (buttonMap[i].source == KEYBOARD
219                    && (unsigned int)event.key.keysym.sym == buttonMap[i].code) {
220                *button = static_cast<Button>(i);
221                break;
222            }
223        }
224#ifndef SDL_JOYSTICK_DISABLED
225    } else if (source == JOYSTICK && event.type != SDL_JOYAXISMOTION) {
226        for (i = 0; i < BUTTON_TYPE_SIZE; i++) {
227            if (buttonMap[i].source == JOYSTICK
228                    && (unsigned int)event.jbutton.button == buttonMap[i].code) {
229                *button = static_cast<Button>(i);
230                break;
231            }
232        }
233#endif
234    }
235
236    if (i == BUTTON_TYPE_SIZE)
237        return false;
238
239    if (wait && PowerSaver::isRunning()) {
240        PowerSaver::getInstance()->resetScreenTimer();
241    }
242
243    return true;
244}
245

Archive Download this file



interactive