2 Copyright © 2009-2011, The AROS Development Team. All rights reserved.
5 AltKeyQ -- Enter characters by their ANSI number.
8 /******************************************************************************
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.
30 CX_PRIORITY -- The priority of the commodity
38 <Alt> 1 2 0 inserts 'x' into the input stream.
42 You can only enter characters which are defined
43 in the keymap of your keyboard.
51 ******************************************************************************/
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
=
76 NBU_NOTIFY
| NBU_UNIQUE
,
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() */
100 static struct Catalog
*catalog
;
101 static struct Task
*mainTask
;
102 static ULONG sendSigBit
= -1;
104 #define CATCOMP_ARRAY
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
);
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
);
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
);
180 /************************************************************************************/
182 static BOOL
initiate(int argc
, char **argv
, struct AKQState
*as
)
186 memset(as
, 0, sizeof(struct AKQState
));
191 IPTR
*args
[] = { NULL
, (IPTR
)FALSE
};
193 rda
= ReadArgs(ARG_TEMPLATE
, (IPTR
*)args
, NULL
);
197 if (args
[ARG_PRI
] != NULL
)
199 nb
.nb_Pri
= *args
[ARG_PRI
];
206 UBYTE
**array
= ArgArrayInit(argc
, (UBYTE
**)argv
);
208 nb
.nb_Pri
= ArgInt(array
, "CX_PRIORITY", 0);
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
));
225 nb
.nb_Port
= as
->akq_msgPort
;
227 as
->akq_broker
= CxBroker(&nb
, 0);
229 if (as
->akq_broker
== NULL
)
234 customObj
= CxCustom(collectKeysFunc
, 0);
236 if (customObj
== NULL
)
238 showSimpleMessage(_(MSG_CANT_CREATE_CUSTOM
));
242 AttachCxObj(as
->akq_broker
, customObj
);
243 sendSigBit
= AllocSignal(-1);
244 if (sendSigBit
== -1)
246 showSimpleMessage(_(MSG_CANT_ALLOCATE_SIGNAL
));
249 mainTask
= FindTask(NULL
);
250 ActivateCxObj(as
->akq_broker
, TRUE
);
255 /************************************************************************************/
257 static void freeResources(struct AKQState
*as
)
263 if (as
->akq_broker
!= NULL
)
265 DeleteCxObjAll(as
->akq_broker
);
269 if (as
->akq_msgPort
!= NULL
)
271 while ((cxm
= GetMsg(as
->akq_msgPort
)))
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
;
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
))
301 /* User released left ALT key */
305 D(bug("Value %u Character %c\n", send
.value
, send
.value
));
306 Signal(mainTask
, 1 << sendSigBit
);
310 D(bug("Value too large\n"));
316 else if (ie
->ie_Qualifier
& IEQUALIFIER_LALT
)
318 if ((s
= strchr(keys
, ie
->ie_Code
)))
321 ie
->ie_Code
|= IECODE_UP_PREFIX
;
322 value
= value
* 10 + (s
- keys
);
335 /************************************************************************************/
337 /* React on command messages sent by commodities.library */
338 static void handleCx(struct AKQState
*as
)
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
);
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
))
370 switch (CxMsgID(msg
))
373 ActivateCxObj(as
->akq_broker
, FALSE
);
377 ActivateCxObj(as
->akq_broker
, TRUE
);
381 /* Running the program twice <=> quit */
388 } /* switch(CxMsgID(msg)) */
391 } /* switch (CxMsgType(msg))*/
393 ReplyMsg((struct Message
*)msg
);
395 } /* while((msg = (CxMsg *)GetMsg(cs->cs_msgPort))) */
398 if (signals
& SIGBREAKF_CTRL_C
)
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
))
422 freeResources(&akqState
);
427 /************************************************************************************/
429 ADD2INIT(Locale_Initialize
, 90);
430 ADD2EXIT(Locale_Deinitialize
, 90);