HIDManager.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003-2005 The Pentagram team
00003 
00004 This program is free software; you can redistribute it and/or
00005 eventify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include "pent_include.h"
00020 #include "HIDManager.h"
00021 
00022 #include "SDL_timer.h"
00023 #include "SettingManager.h"
00024 #include "Console.h"
00025 #include "util.h"
00026 
00027 #include "ConfigFileManager.h" // temporary!
00028 
00029 HIDManager* HIDManager::hidmanager = 0;
00030 
00031 HIDManager::HIDManager()
00032 {
00033         con.Print(MM_INFO, "Creating HIDManager...\n");
00034 
00035         assert(hidmanager == 0);
00036         hidmanager = this;
00037 
00038         InitJoystick();
00039 
00040         resetBindings();
00041         double_timeout = 200;
00042 }
00043 
00044 HIDManager::~HIDManager()
00045 {
00046         std::vector<Console::ArgvType *>::iterator it;
00047         con.Print(MM_INFO, "Destroying HIDManager...\n");
00048 
00049         for (it = commands.begin(); it != commands.end(); ++it)
00050         {
00051                 if (*it)
00052                 {
00053                         delete *it;
00054                 }
00055         }
00056         commands.clear();
00057 
00058         ShutdownJoystick();
00059         hidmanager = 0;
00060 }
00061 
00062 bool HIDManager::handleEvent(const SDL_Event & event)
00063 {
00064         bool handled = false;
00065         HID_Key key = HID_LAST;
00066         HID_Event evn = HID_EVENT_LAST;
00067         Console::ArgvType * command = 0;
00068         switch (event.type) {
00069                 case SDL_KEYDOWN:
00070                         key = HID_translateSDLKey(event.key.keysym.sym);
00071                         evn = HID_EVENT_DEPRESS;
00072                 break;
00073                 case SDL_KEYUP:
00074                         key = HID_translateSDLKey(event.key.keysym.sym);
00075                         evn = HID_EVENT_RELEASE;
00076                 break;
00077                 case SDL_MOUSEBUTTONDOWN:
00078                         key = HID_translateSDLMouseButton(event.button.button);
00079                         evn = HID_EVENT_DEPRESS;
00080                 break;
00081                 case SDL_MOUSEBUTTONUP:
00082                         key = HID_translateSDLMouseButton(event.button.button);
00083                         evn = HID_EVENT_RELEASE;
00084                 break;
00085                 case SDL_JOYBUTTONDOWN:
00086                         key = HID_translateSDLJoystickButton(event.jbutton.button);
00087                         evn = HID_EVENT_DEPRESS;
00088                 break;
00089                 case SDL_JOYBUTTONUP:
00090                         key = HID_translateSDLJoystickButton(event.jbutton.button);
00091                         evn = HID_EVENT_RELEASE;
00092                 break;
00093         }
00094 
00095         if (key < HID_LAST && evn < HID_EVENT_LAST)
00096         {
00097                 command = bindings[key][evn];
00098         }
00099 
00100         if (command)
00101         {
00102                 con.ExecuteConsoleCommand(*command);
00103                 handled = true;
00104         }
00105 
00106         // Handle double separately since it should not stop depress
00107         if (key < HID_LAST && evn == HID_EVENT_DEPRESS )
00108         {
00109                 uint32 now = SDL_GetTicks();
00110                 if (now - lastDown[key] < double_timeout &&
00111                         lastDown[key] != 0)
00112                 {
00113                         lastDown[key] = 0;
00114                         command = bindings[key][HID_EVENT_DOUBLE];
00115                         if (command)
00116                         {
00117                                 con.ExecuteConsoleCommand(*command);
00118                                 handled = true;
00119                         }
00120                 }
00121                 else
00122                 {
00123                         lastDown[key] = now;
00124                 }
00125         }
00126 
00127         return handled;
00128 }
00129 
00130 void HIDManager::handleDelayedEvents()
00131 {
00132         uint16 key;
00133         uint32 now = SDL_GetTicks();
00134         Console::ArgvType * command = 0;
00135 
00136         for (key=0; key < HID_LAST; ++key)
00137         {
00138                 if (now - lastDown[key] > double_timeout &&
00139                         lastDown[key] != 0)
00140                 {
00141                         lastDown[key] = 0;
00142                         command = bindings[key][HID_EVENT_CLICK];
00143                         if (command)
00144                                 con.ExecuteConsoleCommand(*command);
00145                 }
00146         }
00147 }
00148 
00149 void HIDManager::resetBindings()
00150 {
00151         uint16 key, event;
00152         Console::ArgvType * cmd;
00153         std::vector<Console::ArgvType *>::iterator it;
00154 
00155         for (key=0; key < HID_LAST; ++key)
00156         {
00157                 lastDown[key] = 0;
00158                 for (event=0; event < HID_EVENT_LAST; ++event)
00159                 {
00160                         bindings[key][event]=0;
00161                 }
00162         }
00163 
00164         for (it = commands.begin(); it != commands.end(); ++it)
00165         {
00166                 if (*it)
00167                 {
00168                         delete *it;
00169                 }
00170         }
00171         commands.clear();
00172 
00173         cmd = new Console::ArgvType;
00174         cmd->push_back("ConsoleGump::toggle");
00175         commands.push_back(cmd);
00176 
00177         bindings[HID_BACKQUOTE][HID_EVENT_DEPRESS]= commands.back();
00178         bindings[HID_F5][HID_EVENT_DEPRESS]= commands.back();
00179 }
00180 
00181 void HIDManager::loadBindings()
00182 {
00183         Console::ArgsType args;
00184         Console::ArgvType argv;
00185 
00186         con.Print(MM_INFO, "Loading HIDBindings...\n");
00187 
00188         SettingManager* settings = SettingManager::get_instance();
00189         std::map<Pentagram::istring, std::string> keys;
00190         keys = settings->listDataValues("keys");
00191 
00192         std::map<Pentagram::istring, std::string>::iterator i = keys.begin();
00193         std::map<Pentagram::istring, std::string>::iterator end = keys.end();
00194         
00195         if (i == end)
00196         {
00197                 con.Print(MM_INFO, "Loading default HIDBindings...\n");
00198                 ConfigFileManager* config = ConfigFileManager::get_instance();
00199                 keys = config->listKeyValues("bindings/bindings");
00200                 i = keys.begin();
00201                 end = keys.end();
00202         }
00203 
00204         while (i != keys.end())
00205         {
00206                 args = i->second.c_str();
00207                 argv.clear();
00208 
00209                 Pentagram::StringToArgv(args, argv);
00210                 bind(i->first, argv);
00211                 ++i;
00212         }
00213         listBindings();
00214 }
00215 
00216 void HIDManager::saveBindings()
00217 {
00218         uint16 key, event;
00219         SettingManager* settings = SettingManager::get_instance();
00220         Pentagram::istring section = "keys/";
00221         Pentagram::istring confkey;
00222 
00223         for (key=0; key < HID_LAST; ++key)
00224         {
00225                 for (event=0; event < HID_EVENT_LAST; ++event)
00226                 {
00227                         confkey = section +
00228                                 HID_GetEventName((HID_Event) event) +
00229                                 HID_GetKeyName((HID_Key) key);
00230                         if (bindings[key][event])
00231                         {
00232                                 Console::ArgsType command;
00233                                 Pentagram::ArgvToString(*bindings[key][event], command);
00234                                 settings->set(confkey, command);
00235                         }
00236                         else if (settings->exists(confkey))
00237                         {
00238                                 settings->unset(confkey);
00239                         }
00240                 }
00241         }
00242 }
00243 
00244 void HIDManager::bind(const Pentagram::istring& control, const Console::ArgvType& argv)
00245 {
00246         HID_Key key = HID_LAST;
00247         HID_Event event = HID_EVENT_DEPRESS;
00248         std::vector<Pentagram::istring> ctrl_argv;
00249         Console::ArgvType * command = 0;
00250 
00251         if (! argv.empty())
00252         {
00253                 std::vector<Console::ArgvType *>::iterator it;
00254                 for (it = commands.begin(); it != commands.end(); ++it)
00255                 {
00256                         if (argv == (**it))
00257                         {
00258                                 // Change from iterator to pointer
00259                                 command = *it;
00260                                 break;
00261                         }
00262                 }
00263 
00264                 if (!command)
00265                 {
00266                         command = new Console::ArgvType(argv);
00267                         commands.push_back(command);
00268                 }
00269         }
00270 
00271         Pentagram::StringToArgv(control, ctrl_argv);
00272         if (ctrl_argv.size() == 1)
00273         {
00274                 key = HID_GetKeyFromName(ctrl_argv[0]);
00275         }
00276         else if (ctrl_argv.size() > 1)
00277         { // we have a event
00278                 event = HID_GetEventFromName(ctrl_argv[0]);
00279                 key = HID_GetKeyFromName(ctrl_argv[1]);
00280         }
00281 
00282         if (event < HID_EVENT_LAST && key < HID_LAST && key != HID_BACKQUOTE)
00283         {
00284                 bindings[key][event] = command;
00285         }
00286         else
00287         {
00288                 pout << "Error: Cannot bind " << control << std::endl;
00289         }
00290 }
00291 
00292 void HIDManager::unbind(const Pentagram::istring& control)
00293 {
00294         // bind to an empty control
00295         Console::ArgvType command;
00296         bind(control, command);
00297 }
00298 
00299 void HIDManager::ConCmd_bind(const Console::ArgvType &argv)
00300 {
00301         Console::ArgvType argv2;
00302         Console::ArgvType::const_iterator it;
00303         if (argv.size() < 3)
00304         {
00305                 if (! argv.empty())
00306                         pout << "Usage: " << argv[0] << " <key> <action> [<arg> ...]: binds a key or button to an action" << std::endl;
00307                 return;
00308         }
00309         HIDManager * hidmanager = HIDManager::get_instance();
00310 
00311         Pentagram::istring control(argv[1]);
00312 
00313         it = argv.begin();
00314         ++it;
00315         ++it;
00316         argv2.assign(it, argv.end());
00317 
00318         hidmanager->bind(control, argv2);
00319 }
00320 
00321 void HIDManager::ConCmd_unbind(const Console::ArgvType &argv)
00322 {
00323         if (argv.size() != 2)
00324         {
00325                 if (! argv.empty())
00326                         pout << "Usage: " << argv[0] << " <key>: unbinds a key or button" << std::endl;
00327                 return;
00328         }
00329         HIDManager * hidmanager = HIDManager::get_instance();
00330         
00331         Pentagram::istring control(argv[1]);
00332 
00333         hidmanager->unbind(control);
00334 }
00335 
00336 void HIDManager::ConCmd_listbinds(const Console::ArgvType &argv)
00337 {
00338         HIDManager * hidmanager = HIDManager::get_instance();
00339         hidmanager->listBindings();
00340 }
00341 
00342 void HIDManager::ConCmd_save(const Console::ArgvType &argv)
00343 {
00344         HIDManager * hidmanager = HIDManager::get_instance();
00345         hidmanager->saveBindings();
00346 
00347         SettingManager* settings = SettingManager::get_instance();
00348         settings->write();
00349 }
00350 
00351 void HIDManager::listBindings()
00352 {
00353         uint16 key, event;
00354         Console::ArgsType command;
00355 
00356         for (key=0; key < HID_LAST; ++key)
00357         {
00358                 for (event=0; event < HID_EVENT_LAST; ++event)
00359                 {
00360                         if (bindings[key][event])
00361                         {
00362                                 Pentagram::ArgvToString(*bindings[key][event], command);
00363                                 if (event != HID_EVENT_DEPRESS)
00364                                 {
00365                                         pout << HID_GetEventName((HID_Event) event) << ' ' <<
00366                                                 HID_GetKeyName((HID_Key) key) <<
00367                                                 " = " << command << std::endl;
00368                                 }
00369                                 else
00370                                 {
00371                                         pout << HID_GetKeyName((HID_Key) key) <<
00372                                                 " = " << command << std::endl;
00373                                 }
00374                         }
00375                 }
00376         }
00377 }
00378 

Generated on Fri Jul 27 22:27:18 2007 for pentagram by  doxygen 1.4.7