/*************************************************************************** * Copyright (C) 2006 by Massimiliano Torromeo * * massimiliano.torromeo@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU 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 General Public License for more details. * * * * You should have received a copy of the GNU 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 "debug.h" #include "inputmanager.h" #include "utilities.h" #include "powersaver.h" #include "menu.h" #include #include using namespace std; void InputManager::init(const string &conffile, Menu *menu) { this->menu = menu; for (int i = 0; i < BUTTON_TYPE_SIZE; i++) { buttonMap[i].source = UNMAPPED; } readConfFile(conffile); } InputManager::InputManager() { #ifndef SDL_JOYSTICK_DISABLED if (SDL_NumJoysticks() > 0) { joystick = SDL_JoystickOpen(0); } else { joystick = NULL; } #endif } InputManager::~InputManager() { #ifndef SDL_JOYSTICK_DISABLED if (joystick) { SDL_JoystickClose(joystick); } #endif } void InputManager::readConfFile(const string &conffile) { ifstream inf(conffile.c_str(), ios_base::in); if (inf.fail()) { ERROR("InputManager: failed to open config file\n"); return; } string line; while (getline(inf, line, '\n')) { string::size_type pos = line.find("="); string name = trim(line.substr(0,pos)); line = trim(line.substr(pos+1,line.length())); Button button; if (name == "up") button = UP; else if (name == "down") button = DOWN; else if (name == "left") button = LEFT; else if (name == "right") button = RIGHT; else if (name == "accept") button = ACCEPT; else if (name == "cancel") button = CANCEL; else if (name == "altleft") button = ALTLEFT; else if (name == "altright") button = ALTRIGHT; else if (name == "menu") button = MENU; else if (name == "settings") button = SETTINGS; else if (name == "volup") button = VOLUP; else if (name == "voldown") button = VOLDOWN; else if (name == "power") button = POWER; else if (name == "lock") button = LOCK; else { WARNING("InputManager: Ignoring unknown button name \"%s\"\n", name.c_str()); continue; } pos = line.find(","); string sourceStr = trim(line.substr(0,pos)); line = trim(line.substr(pos+1, line.length())); ButtonSource source; if (sourceStr == "keyboard") { source = KEYBOARD; #ifndef SDL_JOYSTICK_DISABLED } else if (sourceStr == "joystick") { source = JOYSTICK; #endif } else { WARNING("InputManager: Ignoring unknown button source \"%s\"\n", sourceStr.c_str()); continue; } buttonMap[button].source = source; buttonMap[button].code = atoi(line.c_str()); } inf.close(); } InputManager::Button InputManager::waitForPressedButton() { return waitForButton(PRESSED); } InputManager::Button InputManager::waitForReleasedButton() { return waitForButton(RELEASED); } InputManager::Button InputManager::waitForButton(ButtonState state) { ButtonEvent event; while (!waitForEvent(&event) || event.state != state); return event.button; } bool InputManager::waitForEvent(ButtonEvent *event) { return getEvent(event, true); } bool InputManager::pollEvent(ButtonEvent *event) { return getEvent(event, false); } bool InputManager::getEvent(ButtonEvent *bevent, bool wait) { //TODO: when an event is processed, program a new event //in some time, and when it occurs, do a key repeat int i; #ifndef SDL_JOYSTICK_DISABLED if (joystick) { SDL_JoystickUpdate(); } #endif SDL_Event event; if (wait) { SDL_WaitEvent(&event); } else { bevent->state = RELEASED; if (!SDL_PollEvent(&event)) { return false; } } ButtonSource source; switch(event.type) { case SDL_KEYDOWN: bevent->state = PRESSED; source = KEYBOARD; break; case SDL_KEYUP: bevent->state = RELEASED; source = KEYBOARD; break; #ifndef SDL_JOYSTICK_DISABLED case SDL_JOYBUTTONDOWN: bevent->state = PRESSED; source = JOYSTICK; break; case SDL_JOYBUTTONUP: bevent->state = RELEASED; source = JOYSTICK; break; #endif case SDL_USEREVENT: if (!event.user.code) menu->removePackageLink((const char *) event.user.data1); else if (event.user.code == 1) menu->openPackage((const char *) event.user.data1); else if (event.user.code == 2) menu->openPackagesFromDir( ((string) (const char *) event.user.data1 + "/apps").c_str()); free(event.user.data1); bevent->state = PRESSED; bevent->button = REPAINT; return true; default: return false; } if (source == KEYBOARD) { for (i = 0; i < BUTTON_TYPE_SIZE; i++) { if (buttonMap[i].source == KEYBOARD && (unsigned int)event.key.keysym.sym == buttonMap[i].code) { bevent->button = static_cast