1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 /*
14  * keyboard mapping stuff
15  */
16 
17 #ifndef BZF_KEYMANAGER_H
18 #define BZF_KEYMANAGER_H
19 
20 #include "common.h"
21 
22 // system headers
23 #include <string>
24 #include <map>
25 #include <vector>
26 
27 // local implementation headers
28 #include "BzfEvent.h"
29 #include "CallbackList.h"
30 #include "Singleton.h"
31 
32 #define KEYMGR (KeyManager::instance())
33 
34 
35 
36 class KeyManager : public Singleton<KeyManager>
37 {
38 public:
39     typedef void (*IterateCallback)(const std::string& name, bool press,
40                                     const std::string& cmd, void* userData);
41     typedef IterateCallback ChangeCallback;
42 
43     // bind/unbind a command to/from a key event press or release
44     void          bind(const BzfKeyEvent&,
45                        bool press, const std::string& cmd);
46     void          unbind(const BzfKeyEvent&, bool press);
47 
48     // unbind all keys bound to a specific command
49     void          unbindCommand(const char* command);
50 
51     // get the command for a key event press or release
52     std::string       get(const BzfKeyEvent&, bool press) const;
53 
54     /** returns a set of keypress strings that correspond to keys bound
55      * to a particular command
56      */
57     std::vector<std::string> getKeysFromCommand(std::string command, bool press) const;
58 
59     // convert a key event to/from a string
60     std::string       keyEventToString(const BzfKeyEvent&) const;
61     bool          stringToKeyEvent(const std::string&, BzfKeyEvent&) const;
62 
63     // invoke callback for each bound key
64     void          iterate(IterateCallback callback, void* userData);
65 
66     // add/remove a callback to invoke when a key binding is added,
67     // removed, or changed.
68     void          addCallback(ChangeCallback, void* userData);
69     void          removeCallback(ChangeCallback, void* userData);
70 
71 protected:
72     friend class Singleton<KeyManager>;
73     KeyManager();
74     ~KeyManager();
75 
76 private:
77     void          notify(const BzfKeyEvent&,
78                          bool press, const std::string& cmd);
79 
80     struct CallbackInfo
81     {
82     public:
83         std::string     name;
84         bool        press;
85         std::string     cmd;
86     };
87     static bool       onCallback(ChangeCallback, void*, void*);
88 
89 private:
90     class KeyEventLess
91     {
92     public:
93         bool        operator() (const BzfKeyEvent&,
94                                 const BzfKeyEvent&) const;
95     };
96 
97     typedef std::map<BzfKeyEvent, std::string, KeyEventLess> EventToCommandMap;
98     typedef std::map<std::string, BzfKeyEvent> StringToEventMap;
99 
100     EventToCommandMap pressEventToCommand;
101     EventToCommandMap releaseEventToCommand;
102     StringToEventMap  stringToEvent;
103     CallbackList<ChangeCallback>  callbacks;
104     static const char*    buttonNames[];
105     static const char*    asciiNames[][2];
106 };
107 
108 // this is to be implemented within the requisite source file for the application using it.
109 // in BZFlag's case, it happens to be in bzflag.cxx
110 extern const unsigned int   numDefaultBindings;
111 extern const char*      defaultBindings[];
112 
113 #endif // BZF_KEYMANAGER_H
114 
115 // Local Variables: ***
116 // mode: C++ ***
117 // tab-width: 4 ***
118 // c-basic-offset: 4 ***
119 // indent-tabs-mode: nil ***
120 // End: ***
121 // ex: shiftwidth=4 tabstop=4
122