Fixed some typos in comments and messages.
[AROS.git] / workbench / tools / commodities / ASCIITable.c
blob3c7599c2acdbe7a8aef86ab6380017ff24666c7b
1 /*
2 Copyright © 2009, The AROS Development Team. All rights reserved.
3 $Id$
5 ASCIITable -- Insert characters to clipboard from GUI.
6 */
8 /******************************************************************************
10 NAME
12 ASCIITable
14 SYNOPSIS
16 CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S
18 LOCATION
20 SYS:Tools/Commodities
22 FUNCTION
24 Insert characters to clipboard from GUI
26 INPUTS
28 CX_PRIORITY -- Priority of the ASCIITable broker
29 CX_POPKEY -- Hotkey combination for ASCIITable
30 CX_POPUP -- Appear at startup
32 RESULT
34 NOTES
36 EXAMPLE
38 BUGS
40 SEE ALSO
42 INTERNALS
44 ******************************************************************************/
46 #define MUIMASTER_YES_INLINE_STDARG
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
52 //#define DEBUG 1
53 #include <aros/debug.h>
54 #include <aros/asmcall.h>
55 #include <aros/symbolsets.h>
56 #include <libraries/iffparse.h>
57 #include <libraries/mui.h>
58 #include <zune/customclasses.h>
59 #include <devices/clipboard.h>
61 #include <proto/muimaster.h>
62 #include <proto/locale.h>
63 #include <proto/intuition.h>
64 #include <proto/exec.h>
65 #include <proto/dos.h>
66 #include <proto/alib.h>
67 #include <proto/commodities.h>
68 #include <proto/utility.h>
70 #define CATCOMP_ARRAY
71 #include "strings.h"
73 #define CATALOG_NAME "System/Tools/Commodities.catalog"
74 #define CATALOG_VERSION 3
76 TEXT version[] = "$VER: ASCIITable 1.1 (14.06.2009)";
78 #define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S"
79 #define DEF_POPKEY "ctrl alt a"
81 enum {
82 ARG_CXPRI,
83 ARG_CXPOPKEY,
84 ARG_CXPOPUP,
85 NUM_ARGS
88 static Object *app, *wnd;
89 static struct Catalog *catalog;
90 static UBYTE s[257];
92 static struct Hook broker_hook;
94 static LONG cx_pri;
95 static char *cx_popkey;
96 static BOOL cx_popup = FALSE;
97 static CxObj *broker;
98 static struct MsgPort *brokermp;
99 static struct Task *maintask;
101 static void Cleanup(CONST_STRPTR txt);
102 static void GetArguments(int argc, char **argv);
103 static void HandleAll(void);
104 static void InitMenus(void);
105 static VOID Locale_Deinitialize(VOID);
106 static int Locale_Initialize(VOID);
107 static void MakeGUI(void);
108 static void showSimpleMessage(CONST_STRPTR msgString);
109 static CONST_STRPTR _(ULONG id);
111 static struct IOClipReq *CBOpen(ULONG unit);
112 static void CBClose(struct IOClipReq *ior);
113 static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string);
114 static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata);
116 /*** ASCIITable class *******************************************************/
118 #define MAXLEN (60)
120 #define ASCIITableObject BOOPSIOBJMACRO_START(ASCIITable_CLASS->mcc_Class)
122 #define MUIM_ASCIITable_Copy (TAG_USER | 1)
123 #define MUIM_ASCIITable_Clear (TAG_USER | 2)
124 #define MUIM_ASCIITable_Insert (TAG_USER | 3)
125 struct MUIP_ASCIITable_Insert {STACKED ULONG MethodID; STACKED LONG code;};
127 struct ASCIITable_DATA
129 Object *copy_button;
130 Object *clear_button;
131 Object *ascii_string;
132 TEXT buffer[MAXLEN + 1];
133 struct IOClipReq *clip_req;
134 TEXT shorthelp[192][20];
137 /*** CBOpen *****************************************************************/
138 static struct IOClipReq *CBOpen(ULONG unit)
140 struct MsgPort *mp;
141 struct IORequest *ior;
143 if ((mp = CreatePort(0, 0)))
145 if ((ior = (struct IORequest *)CreateExtIO(mp, sizeof(struct IOClipReq))))
147 if (!(OpenDevice("clipboard.device", unit, ior, 0)))
149 return (struct IOClipReq *)ior;
151 DeleteExtIO(ior);
153 DeletePort(mp);
155 return NULL;
158 /*** CBCLose ****************************************************************/
159 static void CBClose(struct IOClipReq *ior)
161 if (ior)
163 struct MsgPort *mp = ior->io_Message.mn_ReplyPort;
165 CloseDevice((struct IORequest *)ior);
166 DeleteExtIO((struct IORequest *)ior);
167 DeletePort(mp);
171 /*** CBWriteFTXT ************************************************************/
172 static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string)
174 LONG length, slen, temp;
175 BOOL odd;
177 if (!ior || !string)
178 return FALSE;
180 slen = strlen(string);
181 odd = (slen & 1);
183 length = (odd) ? slen+1 : slen;
185 ior->io_Offset = 0;
186 ior->io_Error = 0;
187 ior->io_ClipID = 0;
189 CBWriteLong(ior, (LONG *) "FORM");
190 length += 12;
192 temp = AROS_LONG2BE(length);
193 CBWriteLong(ior, &temp);
194 CBWriteLong(ior, (LONG *) "FTXT");
195 CBWriteLong(ior, (LONG *) "CHRS");
196 temp = AROS_LONG2BE(slen);
197 CBWriteLong(ior, &temp);
199 ior->io_Data = (STRPTR)string;
200 ior->io_Length = slen;
201 ior->io_Command = CMD_WRITE;
202 DoIO((struct IORequest *)ior);
204 if (odd)
206 ior->io_Data = (APTR)"";
207 ior->io_Length = 1;
208 DoIO((struct IORequest *)ior);
211 ior->io_Command=CMD_UPDATE;
212 DoIO ((struct IORequest *)ior);
214 return ior->io_Error ? FALSE : TRUE;
217 /*** WriteLong **************************************************************/
218 static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata)
220 ior->io_Data = (APTR)ldata;
221 ior->io_Length = 4;
222 ior->io_Command = CMD_WRITE;
223 DoIO( (struct IORequest *) ior);
225 if (ior->io_Actual == 4)
227 return ior->io_Error ? FALSE : TRUE;
230 return FALSE;
233 /*** MakeButton *************************************************************/
234 static Object *MakeButton(LONG code)
236 char buffer[2] = {0};
237 buffer[0] = code;
239 Object *btn = (Object *)TextObject,
240 ButtonFrame,
241 MUIA_Font, MUIV_Font_Button,
242 MUIA_Text_Contents, (IPTR)buffer,
243 MUIA_Text_PreParse, (IPTR)"\33c",
244 MUIA_InputMode , MUIV_InputMode_RelVerify,
245 MUIA_Background , MUII_ButtonBack,
246 MUIA_CycleChain , TRUE,
247 End;
248 return btn;
251 /*** OM_NEW *****************************************************************/
252 IPTR ASCIITable__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
254 struct ASCIITable_DATA *data = NULL;
255 Object *copy_button, *clear_button, *ascii_string, *key_group;
256 struct TagItem key_group_tags[200];
257 LONG i, code;
259 for (code = 32 , i = 0 ; code < 128 ; code++ , i++)
261 key_group_tags[i].ti_Tag = Child;
262 key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
264 for (code = 160 ; code < 256 ; code++, i++)
266 key_group_tags[i].ti_Tag = Child;
267 key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
269 key_group_tags[i].ti_Tag = MUIA_Group_Columns;
270 key_group_tags[i].ti_Data = 16;
271 key_group_tags[++i].ti_Tag = TAG_DONE;
272 key_group = MUI_NewObjectA(MUIC_Group, key_group_tags);
274 self = (Object *) DoSuperNewTags
276 CLASS, self, NULL,
277 Child, key_group,
278 Child, (IPTR) (RectangleObject,
279 MUIA_Rectangle_HBar, TRUE,
280 MUIA_FixHeight, 2,
281 End),
282 Child, (IPTR)(ascii_string = (Object *)StringObject,
283 StringFrame,
284 MUIA_String_MaxLen, MAXLEN,
285 End),
286 Child, (IPTR) (HGroup,
287 MUIA_Weight, 0,
288 MUIA_Group_SameSize, TRUE,
290 Child, (IPTR) (copy_button = SimpleButton(_(MSG_ASCIITABLE_GAD_COPY))),
291 Child, (IPTR) (clear_button = SimpleButton(_(MSG_ASCIITABLE_GAD_CLEAR))),
292 End),
293 TAG_MORE, message->ops_AttrList
296 if (self != NULL)
298 /*-- Store important variables -------------------------------------*/
299 data = INST_DATA(CLASS, self);
300 data->copy_button = copy_button;
301 data->clear_button = clear_button;
302 data->ascii_string = ascii_string;
304 /*-- Setup notifications -------------------------------------------*/
305 DoMethod
307 copy_button, MUIM_Notify, MUIA_Pressed, FALSE,
308 (IPTR) self, 1, MUIM_ASCIITable_Copy
310 DoMethod
312 clear_button, MUIM_Notify, MUIA_Pressed, FALSE,
313 (IPTR) self, 1, MUIM_ASCIITable_Clear
316 for (i = 0 ; i < 192 ; i++)
318 code = (i < 96) ? i + 32 : i + 64;
319 sprintf(data->shorthelp[i], "%c\n%d\n0x%x", (int)code, (int)code, (unsigned int)code);
320 set((Object *)key_group_tags[i].ti_Data, MUIA_ShortHelp, data->shorthelp[i]);
321 DoMethod
323 (Object *)key_group_tags[i].ti_Data, MUIM_Notify, MUIA_Pressed, FALSE,
324 (IPTR) self, 2, MUIM_ASCIITable_Insert, code
327 data->clip_req = CBOpen(0);
328 if (!data->clip_req)
330 showSimpleMessage(_(MSG_CANT_OPEN_CLIPDEVICE));
334 return (IPTR) self;
337 /*** OM_DISPOSE *************************************************************/
338 IPTR ASCIITable__OM_DISPOSE(Class *CLASS, Object *self, Msg message)
340 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
342 CBClose(data->clip_req);
344 return DoSuperMethodA(CLASS, self, message);
347 /*** MUIM_ASCIITable_Copy ***************************************************/
348 IPTR ASCIITable__MUIM_ASCIITable_Copy(Class *CLASS, Object *self, Msg msg)
350 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
351 CBWriteFTXT(data->clip_req, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
352 return TRUE;
355 /*** MUIM_ASCIITable_Clear **************************************************/
356 IPTR ASCIITable__MUIM_ASCIITable_Clear(Class *CLASS, Object *self, Msg msg)
358 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
359 data->buffer[0] = '\0';
360 set(data->ascii_string, MUIA_String_Contents, "");
361 return TRUE;
364 /*** MUIM_ASCIITable_Insert *************************************************/
365 IPTR ASCIITable__MUIM_ASCIITable_Insert(Class *CLASS, Object *self, struct MUIP_ASCIITable_Insert *msg)
367 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
368 LONG len;
369 D(bug("insert code %d\n", msg->code));
370 strcpy(data->buffer, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
371 len = strlen(data->buffer);
372 if (len < MAXLEN)
374 data->buffer[len] = msg->code;
375 data->buffer[len+1] = '\0';
376 set(data->ascii_string, MUIA_String_Contents, data->buffer);
378 return TRUE;
381 /*** Setup ******************************************************************/
382 ZUNE_CUSTOMCLASS_5
384 ASCIITable, NULL, MUIC_Group, NULL,
385 OM_NEW, struct opSet *,
386 OM_DISPOSE, Msg,
387 MUIM_ASCIITable_Copy, Msg,
388 MUIM_ASCIITable_Clear, Msg,
389 MUIM_ASCIITable_Insert, struct MUIP_ASCIITable_Insert *
394 /*** Begin application ******************************************************/
397 static CONST_STRPTR _(ULONG id)
399 if (LocaleBase != NULL && catalog != NULL)
401 return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
403 else
405 return CatCompArray[id].cca_Str;
409 #define __(id) ((IPTR) _(id)) /* Get a message, as an IPTR */
411 /*** Locale_Initialize ******************************************************/
412 static int Locale_Initialize(VOID)
414 if (LocaleBase != NULL)
416 catalog = OpenCatalog
418 NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE
421 else
423 catalog = NULL;
425 return TRUE;
428 /*** Locale_Deinitialize ****************************************************/
429 static VOID Locale_Deinitialize(VOID)
431 if (LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
434 /*** GetArguments ***********************************************************/
435 static void GetArguments(int argc, char **argv)
437 static struct RDArgs *myargs;
438 static IPTR args[NUM_ARGS];
439 static UBYTE **wbargs;
440 if (argc)
442 if (!(myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
444 Fault(IoErr(), 0, s, 256);
445 Cleanup(s);
447 if (args[ARG_CXPRI]) cx_pri = *(LONG*)args[ARG_CXPRI];
448 if (args[ARG_CXPOPKEY])
450 cx_popkey = StrDup((char *)args[ARG_CXPOPKEY]);
452 else
454 cx_popkey = StrDup(DEF_POPKEY);
456 if (args[ARG_CXPOPUP]) cx_popup = TRUE;
457 FreeArgs(myargs);
459 else
461 wbargs = ArgArrayInit(argc, (UBYTE**)argv);
462 cx_pri = ArgInt(wbargs, "CX_PRIORITY", 0);
463 cx_popkey = StrDup(ArgString(wbargs, "CX_POPKEY", DEF_POPKEY));
464 if (strnicmp(ArgString(wbargs, "CX_POPUP", "NO"), "Y", 1) == 0)
466 cx_popup = TRUE;
468 ArgArrayDone();
470 D(bug("ASCIITable Arguments pri %d popkey %s popup %d\n", cx_pri, cx_popkey, cx_popup));
473 /****************************************************************************/
474 static struct NewMenu nm[] =
476 {NM_TITLE, (STRPTR)MSG_MEN_PROJECT },
477 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_HIDE },
478 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ICONIFY },
479 {NM_ITEM, NM_BARLABEL },
480 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
481 {NM_END }
484 /*** InitMenus **************************************************************/
485 static void InitMenus(void)
487 struct NewMenu *actnm = nm;
489 for(actnm = nm; actnm->nm_Type != NM_END; actnm++)
491 if (actnm->nm_Label != NM_BARLABEL)
493 ULONG id = (IPTR)actnm->nm_Label;
494 CONST_STRPTR str = _(id);
496 if (actnm->nm_Type == NM_TITLE)
498 actnm->nm_Label = str;
499 } else {
500 actnm->nm_Label = str + 2;
501 if (str[0] != ' ') actnm->nm_CommKey = str;
503 actnm->nm_UserData = (APTR)(IPTR)id;
505 } /* if (actnm->nm_Label != NM_BARLABEL) */
507 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
510 /*** showSimpleMessage ******************************************************/
511 static void showSimpleMessage(CONST_STRPTR msgString)
513 struct EasyStruct easyStruct;
515 easyStruct.es_StructSize = sizeof(easyStruct);
516 easyStruct.es_Flags = 0;
517 easyStruct.es_Title = _(MSG_ASCIITABLE_CXNAME);
518 easyStruct.es_TextFormat = msgString;
519 easyStruct.es_GadgetFormat = _(MSG_OK);
521 if (IntuitionBase != NULL && !Cli() )
523 EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
525 else
527 PutStr(msgString);
531 /*** broker_func ************************************************************/
532 AROS_UFH3(void, broker_func,
533 AROS_UFHA(struct Hook *, h, A0),
534 AROS_UFHA(Object * , object, A2),
535 AROS_UFHA(CxMsg * , msg, A1))
537 AROS_USERFUNC_INIT
539 D(bug("ASCIITable: Broker hook called\n"));
540 if (CxMsgType(msg) == CXM_COMMAND)
542 if (CxMsgID(msg) == CXCMD_APPEAR)
544 //This opens window if application was started with cx_popup=no
545 set(app, MUIA_Application_Iconified, FALSE);
548 AROS_USERFUNC_EXIT
551 /*** MakeGUI ****************************************************************/
552 static void MakeGUI(void)
554 Object *menu;
555 static TEXT wintitle[100];
556 CxObj *popfilter;
558 menu = MUI_MakeObject(MUIO_MenustripNM, &nm, 0);
560 broker_hook.h_Entry = (HOOKFUNC)broker_func;
562 snprintf(wintitle, sizeof(wintitle), _(MSG_ASCIITABLE_WINTITLE), cx_popkey);
564 app = (Object *)ApplicationObject,
565 MUIA_Application_Title, __(MSG_ASCIITABLE_CXNAME),
566 MUIA_Application_Version, (IPTR)version,
567 MUIA_Application_Copyright, (IPTR)"Copyright © 2009, The AROS Development TEAM",
568 MUIA_Application_Author, (IPTR)"The AROS Development Team",
569 MUIA_Application_Description, __(MSG_ASCIITABLE_CXDESCR),
570 MUIA_Application_BrokerPri, cx_pri,
571 MUIA_Application_BrokerHook, (IPTR)&broker_hook,
572 MUIA_Application_Base, (IPTR)"ASCIITABLE",
573 MUIA_Application_SingleTask, TRUE,
574 MUIA_Application_Menustrip, (IPTR)menu,
575 SubWindow, (IPTR)(wnd = (Object *)WindowObject,
576 MUIA_Window_Title, (IPTR)wintitle,
577 MUIA_Window_ID, MAKE_ID('A', 'I', 'T', 'B'),
578 WindowContents, (IPTR)ASCIITableObject,
579 End,
580 End),
581 End;
583 if (! app)
584 Cleanup(NULL); // Propably double start
586 // enable hotkey
587 maintask = FindTask(NULL);
588 get(app, MUIA_Application_Broker, &broker);
589 get(app, MUIA_Application_BrokerPort, &brokermp);
590 if ( ! broker || ! brokermp)
591 Cleanup(_(MSG_CANT_CREATE_BROKER));
593 popfilter = CxFilter(cx_popkey);
594 if (popfilter)
596 CxObj *popsig = CxSignal(maintask, SIGBREAKB_CTRL_F);
597 if (popsig)
599 CxObj *trans;
600 AttachCxObj(popfilter, popsig);
601 trans = CxTranslate(NULL);
602 if (trans) AttachCxObj(popfilter, trans);
604 AttachCxObj(broker, popfilter);
607 DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
608 (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
610 DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE,
611 (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, FALSE);
613 // Open the window when app isn't iconified
614 DoMethod(app, MUIM_Notify, MUIA_Application_Iconified, FALSE,
615 (IPTR)wnd, 3, MUIM_Set, MUIA_Window_Open, TRUE);
617 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_QUIT,
618 (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
620 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_HIDE,
621 (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
623 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_ICONIFY,
624 (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
627 /*** HandleAll **************************************************************/
628 static void HandleAll(void)
630 ULONG sigs = 0;
632 set(app, MUIA_Application_Iconified, cx_popup ? FALSE : TRUE);
634 while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs)
635 != MUIV_Application_ReturnID_Quit)
637 if (sigs)
639 sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
640 if (sigs & SIGBREAKF_CTRL_C)
642 break;
644 if (sigs & SIGBREAKF_CTRL_F)
646 set(app, MUIA_Application_Iconified, FALSE);
652 /*** Cleanup ****************************************************************/
653 static void Cleanup(CONST_STRPTR txt)
655 MUI_DisposeObject(app);
656 FreeVec(cx_popkey);
657 if (txt)
659 showSimpleMessage(txt);
660 exit(RETURN_ERROR);
662 exit(RETURN_OK);
665 /*** main *******************************************************************/
666 int main(int argc, char **argv)
668 D(bug("ASCIITable started\n"));
669 GetArguments(argc, argv);
670 InitMenus();
671 MakeGUI();
672 HandleAll();
673 Cleanup(NULL);
674 return RETURN_OK;
677 /****************************************************************************/
678 ADD2INIT(Locale_Initialize, 90);
679 ADD2EXIT(Locale_Deinitialize, 90);