Libmacro  0.2
Libmacro is an extensible macro and hotkey library.
extras.h
Go to the documentation of this file.
1 /* Libmacro - A multi-platform, extendable macro and hotkey C library
2  Copyright (C) 2013 Jonathan Pelletier, New Paradigm Software
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
23 #ifndef __cplusplus
24  #pragma message "C++ support is required for extras module"
25  #include "mcr/err.h"
26 #endif
27 
28 #ifndef MCR_EXTRAS_EXTRAS_H_
29 #define MCR_EXTRAS_EXTRAS_H_
30 
34 #include "mcr/extras/macro.h"
36 #include "mcr/extras/registry.h"
37 #include "mcr/extras/serial.h"
38 #include "mcr/extras/wrappers.h"
43 #include "mcr/extras/dispatcher.h"
45 
46 namespace mcr
47 {
49 class LibmacroPrivate;
51 class LibmacroPlatform;
52 struct MCR_API Libmacro final // And that's final!
53 {
54  friend class LibmacroPrivate;
55  friend class LibmacroPlatform;
56 
57  mcr_context self;
58  // \todo C-structs inside mcr_context as functions instead of references?
59 
60  Registry isignalRegistry;
61  Registry itriggerRegistry;
62 
63  mcr_ISignal &iHidEcho;
64  mcr_ISignal &iKey;
65  mcr_ISignal &iModifier;
66  mcr_ISignal &iMoveCursor;
67  mcr_ISignal &iNoOp;
68  mcr_ISignal &iScroll;
69  ISignal iCommand;
70  ISignal iInterrupt;
71  ISignal iStringKey;
72 
73  mcr_ITrigger &iAction;
74 // //Trigger iAlarm;
75 // //Trigger iStaged;
76 
77  Dispatcher genericDispatcher;
78  Dispatcher hidEchoDispatcher;
79  KeyDispatcher keyDispatcher;
80  Dispatcher modifierDispatcher;
81  Dispatcher moveCursorDispatcher;
82  Dispatcher noOpDispatcher;
83  Dispatcher scrollDispatcher;
84  Dispatcher commandDispatcher;
85  Dispatcher interruptDispatcher;
86  Dispatcher stringKeyDispatcher;
87 
88  //CharacterRegistry characterRegistry
89  MacrosInterrupted macrosInterrupted;
90  Serial serial;
91 
96  Libmacro(bool enabled = true);
97  Libmacro(const Libmacro &);
101  ~Libmacro();
102  Libmacro &operator =(const Libmacro &);
103 
109  static Libmacro *instance();
110  static inline Libmacro *instance(Libmacro *contextIfNotNull)
111  {
112  return contextIfNotNull ? contextIfNotNull : instance();
113  }
116  inline mcr_context &operator *()
117  {
118  return self;
119  }
120  inline const mcr_context &operator *() const
121  {
122  return self;
123  }
124  static inline Libmacro *offset(mcr_context *originPt)
125  {
126  return mcr::offset<Libmacro>(originPt);
127  }
128  static inline const Libmacro *offset(const mcr_context *originPt)
129  {
130  return mcr::offset<Libmacro>(originPt);
131  }
132 
133  template<typename ISignalMemberT>
134  ISignal &registerSignal(ISignal &isignal)
135  {
136  ISignalMemberT inst;
137  size_t count = inst.addNameCount();
138  const char **addN = count ? new const char *[count] : nullptr;
139  /* If not implemented this will do nothing \ref IDataMember.addNames */
140  inst.addNames(addN, count);
141  mcr_register(mcr_ISignal_registry(&self), &isignal.interface(), inst.name(), addN, count);
142  if (addN)
143  delete []addN;
144  if (mcr_err)
145  throw mcr_read_err();
146  return isignal;
147  }
148  template<typename ITriggerMemberT>
149  ITrigger &registerTrigger(ITrigger &itrigger)
150  {
151  ITriggerMemberT inst;
152  size_t count = inst.addNameCount();
153  const char * const*addN = count ? new const char *[count] : nullptr;
154  /* If not implemented this will do nothing \ref IDataMember.addNames */
155  inst.addNames(addN, count);
156  mcr_register(mcr_ITrigger_registry(&self), &itrigger.interface(), inst.name(), addN, count);
157  if (addN)
158  delete []addN;
159  if (mcr_err)
160  throw mcr_read_err();
161  return itrigger;
162  }
163 
164  // \todo iAlarm + iStaged
168  inline bool enabled() const
169  {
170  return _enabled;
171  }
175  void setEnabled(bool val);
176 
178  size_t characterCount() const;
179  size_t characterCount(int c) const;
180  Signal *characterData(int c) const;
181 
183  template<typename T>
184  inline void setCharacter(int c, const T &val)
185  {
186  mcr_throwif(c < 0, EINVAL);
187  setCharacter(c, &val.front(), val.size());
188  }
199  void setCharacterKey(int c, int key, long msecDelay, bool shiftFlag);
204  void setCharacterDelays(mcr_NoOp delayValue);
205  void removeCharacter(int c);
206  void trimCharacters();
207  void clearCharacters();
208 
209  mcr_IDispatcher *dispatcher(size_t id) const;
210  inline mcr_IDispatcher *dispatcher(mcr_ISignal *isignalPt) const
211  {
212  return isignalPt ? dispatcher(isignalPt->interface.id) : nullptr;
213  }
214  inline mcr_IDispatcher *dispatcher(mcr_Signal *signalPt) const
215  {
216  return signalPt && signalPt->isignal ? dispatcher(signalPt->interface->id) : nullptr;
217  }
218  void setDispatcher(size_t id, mcr_IDispatcher *idispatcherPt);
219  inline void setGenericDispatcher(mcr_IDispatcher *idispatcherPt, bool enable = false)
220  {
221  setDispatcher(-1, idispatcherPt);
222  self.base.generic_dispatcher_flag = enable;
223  }
224  inline void setDispatcher(mcr_ISignal *isignalPt, mcr_IDispatcher *idispatcherPt, bool enable = false)
225  {
226  if (isignalPt) {
227  setDispatcher(mcr_ISignal_id(isignalPt), idispatcherPt);
228  isignalPt->dispatcher_pt = enable ? idispatcherPt : nullptr;
229  } else {
230  setGenericDispatcher(idispatcherPt, enable);
231  }
232  }
233  inline void setDispatcher(mcr_Signal *signalPt, mcr_IDispatcher *idispatcherPt, bool enable = false)
234  {
235  mcr_throwif(!signalPt, EFAULT);
236  mcr_throwif(!signalPt->isignal, EFAULT);
237  setDispatcher(signalPt->isignal, idispatcherPt, enable);
238  }
239  void clearDispatchers();
240 
241 private:
242  bool _enabled;
243  /* non-export */
244  LibmacroPrivate *_private;
245  LibmacroPlatform *_platform;
246 
247  void construct(bool enabled);
250  void initialize();
253  void deinitialize();
254 
255  void setCharacter(int c, const Signal *valueArray, size_t count);
256 };
257 }
258 
259 #endif
struct mcr_Interface interface
Definition: isignal.h:48
#define mcr_throwif(condition, errorNumber)
Definition: defines.h:415
MCR_API struct mcr_IRegistry * mcr_ISignal_registry(struct mcr_context *ctx)
Command - Execute a shell command, similar to execvp, with restrictions and without closing current p...
bool enabled() const
Definition: extras.h:168
StringKey - Turn a text string into a set of signals, such as a key press
MCR_API int mcr_register(struct mcr_IRegistry *iRegPt, struct mcr_Interface *interfacePt, const char *name, const char *const *addNames, size_t addNamesCount)
String contracts for serialization.
Raise a compiler error. Usage: #include "mcr/err.h"
String contract registry for a primitive type.
C++ wrappers and extensions of C types.
Definition: noop.h:33
Libmacro, by Jonathan Pelletier, New Paradigm Software. Alpha version.
Definition: classes.h:31
MCR_API size_t mcr_ISignal_id(const struct mcr_ISignal *isigPt)
MCR_API struct mcr_IRegistry * mcr_ITrigger_registry(struct mcr_context *ctx)
void setCharacter(int c, const T &val)
Definition: extras.h:184
struct mcr_IDispatcher * dispatcher_pt
Definition: isignal.h:52
rT * offset(vT *valuePt)
Definition: functions.h:44
String contract registry for a primitive type.
size_t id
Definition: interface.h:37