Fixed some typos in comments and messages.
[AROS.git] / workbench / tools / commodities / AltKeyQ.c
blobd151aa1e9331c032f01d69526b632195a60df4f2
1 /*
2 Copyright © 2009-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 AltKeyQ -- Enter characters by their ANSI number.
6 */
8 /******************************************************************************
10 NAME
12 AltKeyQ
14 SYNOPSIS
16 CX_PRIORITY/N/K
18 LOCATION
20 SYS:Tools/Commodities
22 FUNCTION
24 Enter characters by pressing the ALT key and ANSI number of
25 the character. It's a clone of a Commodity which you can
26 find under the same name in Aminet.
28 INPUTS
30 CX_PRIORITY -- The priority of the commodity
32 RESULT
34 NOTES
36 EXAMPLE
38 <Alt> 1 2 0 inserts 'x' into the input stream.
40 BUGS
42 You can only enter characters which are defined
43 in the keymap of your keyboard.
45 SEE ALSO
47 INTERNALS
49 HISTORY
51 ******************************************************************************/
53 #define DEBUG 0
54 #include <aros/debug.h>
56 #include <aros/symbolsets.h>
57 #include <devices/rawkeycodes.h>
59 #include <proto/exec.h>
60 #include <proto/dos.h>
61 #include <proto/locale.h>
62 #include <proto/intuition.h>
63 #include <proto/commodities.h>
64 #include <proto/alib.h>
66 const char *verstag = "\0$VER: AltKeyQ 1.0 (23.05.2009) © The AROS Development Team";
68 #define ARG_TEMPLATE "CX_PRIORITY=PRI/N/K"
70 static struct NewBroker nb =
72 NB_VERSION,
73 NULL,
74 NULL,
75 NULL,
76 NBU_NOTIFY | NBU_UNIQUE,
79 NULL,
83 struct AKQState
85 CxObj *akq_broker;
86 struct MsgPort *akq_msgPort;
89 struct /* structure with information to send: */
91 UBYTE value; /* ASCII value for the IEvent to send */
92 UBYTE nul; /* ASCII NUL byte for InvertString() */
93 } send;
95 enum {
96 ARG_PRI,
97 NUM_ARGS
100 static struct Catalog *catalog;
101 static struct Task *mainTask;
102 static ULONG sendSigBit = -1;
104 #define CATCOMP_ARRAY
105 #include "strings.h"
107 #define CATALOG_NAME "System/Tools/Commodities.catalog"
108 #define CATALOG_VERSION 3
110 /************************************************************************************/
112 static void collectKeysFunc(CxMsg *msg, CxObj *co);
113 static void handleCx(struct AKQState *as);
114 static void freeResources(struct AKQState *as);
115 static BOOL initiate(int argc, char **argv, struct AKQState *as);
116 static void showSimpleMessage(CONST_STRPTR msgString);
117 static VOID Locale_Deinitialize(VOID);
118 static BOOL Locale_Initialize(VOID);
119 static CONST_STRPTR _(ULONG id);
121 /************************************************************************************/
123 static CONST_STRPTR _(ULONG id)
125 if (LocaleBase != NULL && catalog != NULL)
127 return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
129 else
131 return CatCompArray[id].cca_Str;
135 /************************************************************************************/
137 static BOOL Locale_Initialize(VOID)
139 if (LocaleBase != NULL)
141 catalog = OpenCatalog(NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE);
143 else
145 catalog = NULL;
148 return TRUE;
151 /************************************************************************************/
153 static VOID Locale_Deinitialize(VOID)
155 if(LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
158 /************************************************************************************/
160 static void showSimpleMessage(CONST_STRPTR msgString)
162 struct EasyStruct easyStruct;
164 easyStruct.es_StructSize = sizeof(easyStruct);
165 easyStruct.es_Flags = 0;
166 easyStruct.es_Title = _(MSG_ALTKEYQ_CXNAME);
167 easyStruct.es_TextFormat = msgString;
168 easyStruct.es_GadgetFormat = _(MSG_OK);
170 if (IntuitionBase != NULL && !Cli() )
172 EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
174 else
176 PutStr(msgString);
180 /************************************************************************************/
182 static BOOL initiate(int argc, char **argv, struct AKQState *as)
184 CxObj *customObj;
186 memset(as, 0, sizeof(struct AKQState));
188 if (Cli() != NULL)
190 struct RDArgs *rda;
191 IPTR *args[] = { NULL, (IPTR)FALSE };
193 rda = ReadArgs(ARG_TEMPLATE, (IPTR *)args, NULL);
195 if (rda != NULL)
197 if (args[ARG_PRI] != NULL)
199 nb.nb_Pri = *args[ARG_PRI];
202 FreeArgs(rda);
204 else
206 UBYTE **array = ArgArrayInit(argc, (UBYTE **)argv);
208 nb.nb_Pri = ArgInt(array, "CX_PRIORITY", 0);
210 ArgArrayDone();
213 nb.nb_Name = _(MSG_ALTKEYQ_CXNAME);
214 nb.nb_Title = _(MSG_ALTKEYQ_CXTITLE);
215 nb.nb_Descr = _(MSG_ALTKEYQ_CXDESCR);
217 as->akq_msgPort = CreateMsgPort();
219 if (as->akq_msgPort == NULL)
221 showSimpleMessage(_(MSG_CANT_CREATE_MSGPORT));
222 return FALSE;
225 nb.nb_Port = as->akq_msgPort;
227 as->akq_broker = CxBroker(&nb, 0);
229 if (as->akq_broker == NULL)
231 return FALSE;
234 customObj = CxCustom(collectKeysFunc, 0);
236 if (customObj == NULL)
238 showSimpleMessage(_(MSG_CANT_CREATE_CUSTOM));
239 return FALSE;
242 AttachCxObj(as->akq_broker, customObj);
243 sendSigBit = AllocSignal(-1);
244 if (sendSigBit == -1)
246 showSimpleMessage(_(MSG_CANT_ALLOCATE_SIGNAL));
247 return FALSE;
249 mainTask = FindTask(NULL);
250 ActivateCxObj(as->akq_broker, TRUE);
252 return TRUE;
255 /************************************************************************************/
257 static void freeResources(struct AKQState *as)
259 struct Message *cxm;
261 if (CxBase != NULL)
263 if (as->akq_broker != NULL)
265 DeleteCxObjAll(as->akq_broker);
269 if (as->akq_msgPort != NULL)
271 while ((cxm = GetMsg(as->akq_msgPort)))
273 ReplyMsg(cxm);
276 DeleteMsgPort(as->akq_msgPort);
279 FreeSignal(sendSigBit);
282 /************************************************************************************/
284 static void collectKeysFunc(CxMsg *msg, CxObj *co)
286 /* Scancodes of numeric pad */
287 static TEXT keys[]= "\x0f\x1d\x1e\x1f\x2d\x2e\x2f\x3d\x3e\x3f";
289 static BOOL collflag;
290 static ULONG value;
291 TEXT *s;
293 struct InputEvent *ie = (struct InputEvent *)CxMsgData(msg);
295 if (ie->ie_Class == IECLASS_RAWKEY)
297 if (ie->ie_Code == (RAWKEY_LALT | IECODE_UP_PREFIX))
299 if (collflag)
301 /* User released left ALT key */
302 if (value < 256)
304 send.value = value;
305 D(bug("Value %u Character %c\n", send.value, send.value));
306 Signal(mainTask, 1 << sendSigBit);
308 else
310 D(bug("Value too large\n"));
313 goto setinactive;
316 else if (ie->ie_Qualifier & IEQUALIFIER_LALT)
318 if ((s= strchr(keys, ie->ie_Code)))
320 /* collect value */
321 ie->ie_Code |= IECODE_UP_PREFIX;
322 value = value * 10 + (s - keys);
323 collflag = TRUE;
326 else
327 setinactive:
329 value = 0;
330 collflag = FALSE;
335 /************************************************************************************/
337 /* React on command messages sent by commodities.library */
338 static void handleCx(struct AKQState *as)
340 CxMsg *msg;
341 BOOL quit = FALSE;
342 LONG signals;
344 while (!quit)
346 signals = Wait((1 << nb.nb_Port->mp_SigBit) | (1 << sendSigBit) | SIGBREAKF_CTRL_C);
348 if (signals & (1 << sendSigBit))
350 D(bug("signal received\n"));
351 struct InputEvent *ie = InvertString((TEXT *)&send, NULL);
352 if (ie)
354 AddIEvents(ie);
355 FreeIEvents(ie);
357 else
359 D(bug("No event added\n"));
363 if (signals & (1 << nb.nb_Port->mp_SigBit))
365 while ((msg = (CxMsg *)GetMsg(as->akq_msgPort)))
367 switch (CxMsgType(msg))
369 case CXM_COMMAND:
370 switch (CxMsgID(msg))
372 case CXCMD_DISABLE:
373 ActivateCxObj(as->akq_broker, FALSE);
374 break;
376 case CXCMD_ENABLE:
377 ActivateCxObj(as->akq_broker, TRUE);
378 break;
380 case CXCMD_UNIQUE:
381 /* Running the program twice <=> quit */
382 /* Fall through */
384 case CXCMD_KILL:
385 quit = TRUE;
386 break;
388 } /* switch(CxMsgID(msg)) */
390 break;
391 } /* switch (CxMsgType(msg))*/
393 ReplyMsg((struct Message *)msg);
395 } /* while((msg = (CxMsg *)GetMsg(cs->cs_msgPort))) */
398 if (signals & SIGBREAKF_CTRL_C)
400 quit = TRUE;
403 } /* while (!quit) */
406 /************************************************************************************/
408 int main(int argc, char **argv)
410 struct AKQState akqState;
411 int error = RETURN_OK;
413 if (initiate(argc, argv, &akqState))
415 handleCx(&akqState);
417 else
419 error = RETURN_FAIL;
422 freeResources(&akqState);
424 return error;
427 /************************************************************************************/
429 ADD2INIT(Locale_Initialize, 90);
430 ADD2EXIT(Locale_Deinitialize, 90);