keyboard.C

00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
00018  */
00019 
00020 #include <archon/util/keyboard.H>
00021 
00022 namespace Archon
00023 {
00024   namespace Utilities
00025   {
00026     namespace KeyboardEvents
00027     {
00028       Dispatcher::Dispatcher(unsigned numberOfModes,
00029                              unsigned maxMultipressLimit,
00030                              unsigned long multipressMaxDelay):
00031         numberOfModes(numberOfModes),
00032         maxMultipressLimit(maxMultipressLimit),
00033         multipressMaxDelay(multipressMaxDelay),
00034         currentMode(0)
00035       {
00036         if(maxMultipressLimit < 1)
00037           ARCHON_THROW1(ArgumentException, "Invalid multipress limit");
00038 
00039         keyAccounts = new KeyAccount[_key_last];
00040 
00041         handlers =
00042           new Handler *[_key_last *
00043                         numberOfModes *
00044                         maxMultipressLimit];
00045 
00046         for(unsigned i=0; i<_key_last *
00047               numberOfModes * maxMultipressLimit; ++i)
00048           handlers[i] = 0;
00049       }
00050 
00051       Dispatcher::~Dispatcher()
00052       {{ // The extra scope is needed to work around gcc3.2 bug #8287
00053         delete[] handlers;
00054         delete[] keyAccounts;
00055       }}
00056 
00057       void Dispatcher::setMultipressLimit(Key key,
00058                                           unsigned limit)
00059       {
00060         if(key < 0 || key >= _key_last)
00061           ARCHON_THROW1(ArgumentException, "Invalid key");
00062         if(limit < 1 || limit > maxMultipressLimit)
00063           ARCHON_THROW1(ArgumentException, "Invalid multipress limit");
00064 
00065         keyAccounts[key].multipressLimit = limit;
00066       }
00067 
00068       void Dispatcher::setMode(unsigned mode)
00069       {
00070         if(mode < 0 || mode >= numberOfModes)
00071           ARCHON_THROW1(ArgumentException, "Invalid mode");
00072         currentMode = mode;
00073       }
00074 
00075       void Dispatcher::setHandler(Key key, Handler *h,
00076                                   unsigned mode,
00077                                   unsigned multipressCardinality)
00078       {
00079         if(key < 0 || key >= _key_last)
00080           ARCHON_THROW1(ArgumentException, "Invalid key");
00081         if(mode < 0 || mode >= numberOfModes)
00082           ARCHON_THROW1(ArgumentException, "Invalid mode");
00083         if(multipressCardinality < 1 ||
00084            multipressCardinality > maxMultipressLimit)
00085           ARCHON_THROW1(ArgumentException, "Invalid multipress cardinality");
00086 
00087         handlers[(key*numberOfModes + mode)*maxMultipressLimit
00088                  + multipressCardinality - 1] = h;
00089       }
00090 
00091       void Dispatcher::press(Key key,
00092                              unsigned long millisecondTime)
00093       {
00094         if(key >= _key_last) return;
00095         KeyAccount &a = keyAccounts[key];
00096 
00097         if(millisecondTime - a.lastPress < multipressMaxDelay)
00098         {
00099           if(a.multipressCounter < a.multipressLimit) ++a.multipressCounter;
00100         }
00101         else a.multipressCounter = 1;
00102         a.lastPress = millisecondTime;
00103         a.pressMode = currentMode;
00104         Handler *h =
00105           handlers[(key*numberOfModes + currentMode)*maxMultipressLimit
00106                    + a.multipressCounter - 1];
00107         if(h) h->press();
00108       }
00109 
00110       void Dispatcher::release(Key key)
00111       {
00112         if(key >= _key_last) return;
00113         KeyAccount &a = keyAccounts[key];
00114         Handler *h =
00115           handlers[(key*numberOfModes + a.pressMode)*maxMultipressLimit
00116                    + a.multipressCounter - 1];
00117         if(h) h->release();
00118       }
00119     }
00120   }
00121 }

Generated on Sun Jul 30 22:55:44 2006 for Archon by  doxygen 1.4.4