Fixed AutoDoc indentation, spelling, grammar.
[AROS.git] / workbench / tools / commodities / ASCIITable.c
blob94a3e0aa45ba9771b5f2b7fc39b9620f580beb88
1 /*
2 Copyright © 2012, 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>
60 #include <workbench/startup.h>
62 #include <proto/muimaster.h>
63 #include <proto/locale.h>
64 #include <proto/intuition.h>
65 #include <proto/exec.h>
66 #include <proto/dos.h>
67 #include <proto/alib.h>
68 #include <proto/commodities.h>
69 #include <proto/utility.h>
70 #include <proto/icon.h>
72 #define CATCOMP_ARRAY
73 #include "strings.h"
75 #define CATALOG_NAME "System/Tools/Commodities.catalog"
76 #define CATALOG_VERSION 3
78 TEXT version[] = "$VER: ASCIITable 1.2 (14.01.2012)";
80 #define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S"
81 #define DEF_POPKEY "ctrl alt a"
83 enum {
84 ARG_CXPRI,
85 ARG_CXPOPKEY,
86 ARG_CXPOPUP,
87 NUM_ARGS
90 static Object *app, *wnd;
91 static struct Catalog *catalog;
92 static UBYTE s[257];
94 static struct Hook broker_hook;
95 static struct Hook show_hook;
97 static LONG cx_pri;
98 static char *cx_popkey;
99 static BOOL cx_popup = FALSE;
100 static CxObj *broker;
101 static struct MsgPort *brokermp;
102 static struct Task *maintask;
104 static void Cleanup(CONST_STRPTR txt);
105 static void GetArguments(int argc, char **argv);
106 static void HandleAll(void);
107 static void InitMenus(void);
108 static VOID Locale_Deinitialize(VOID);
109 static int Locale_Initialize(VOID);
110 static void MakeGUI(void);
111 static void showSimpleMessage(CONST_STRPTR msgString);
112 static CONST_STRPTR _(ULONG id);
114 static struct IOClipReq *CBOpen(ULONG unit);
115 static void CBClose(struct IOClipReq *ior);
116 static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string);
117 static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata);
118 static struct DiskObject *disko;
120 /*** ASCIITable class *******************************************************/
122 #define MAXLEN (60)
124 #define ASCIITableObject BOOPSIOBJMACRO_START(ASCIITable_CLASS->mcc_Class)
126 #define MUIM_ASCIITable_Copy (TAG_USER | 1)
127 #define MUIM_ASCIITable_Clear (TAG_USER | 2)
128 #define MUIM_ASCIITable_Insert (TAG_USER | 3)
129 struct MUIP_ASCIITable_Insert {STACKED ULONG MethodID; STACKED LONG code;};
131 struct ASCIITable_DATA
133 Object *copy_button;
134 Object *clear_button;
135 Object *ascii_string;
136 TEXT buffer[MAXLEN + 1];
137 struct IOClipReq *clip_req;
138 TEXT shorthelp[192][20];
141 /*** CBOpen *****************************************************************/
142 static struct IOClipReq *CBOpen(ULONG unit)
144 struct MsgPort *mp;
145 struct IORequest *ior;
147 if ((mp = CreatePort(0, 0)))
149 if ((ior = (struct IORequest *)CreateExtIO(mp, sizeof(struct IOClipReq))))
151 if (!(OpenDevice("clipboard.device", unit, ior, 0)))
153 return (struct IOClipReq *)ior;
155 DeleteExtIO(ior);
157 DeletePort(mp);
159 return NULL;
162 /*** CBCLose ****************************************************************/
163 static void CBClose(struct IOClipReq *ior)
165 if (ior)
167 struct MsgPort *mp = ior->io_Message.mn_ReplyPort;
169 CloseDevice((struct IORequest *)ior);
170 DeleteExtIO((struct IORequest *)ior);
171 DeletePort(mp);
175 /*** CBWriteFTXT ************************************************************/
176 static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string)
178 LONG length, slen, temp;
179 BOOL odd;
181 if (!ior || !string)
182 return FALSE;
184 slen = strlen(string);
185 odd = (slen & 1);
187 length = (odd) ? slen+1 : slen;
189 ior->io_Offset = 0;
190 ior->io_Error = 0;
191 ior->io_ClipID = 0;
193 CBWriteLong(ior, (LONG *) "FORM");
194 length += 12;
196 temp = AROS_LONG2BE(length);
197 CBWriteLong(ior, &temp);
198 CBWriteLong(ior, (LONG *) "FTXT");
199 CBWriteLong(ior, (LONG *) "CHRS");
200 temp = AROS_LONG2BE(slen);
201 CBWriteLong(ior, &temp);
203 ior->io_Data = (STRPTR)string;
204 ior->io_Length = slen;
205 ior->io_Command = CMD_WRITE;
206 DoIO((struct IORequest *)ior);
208 if (odd)
210 ior->io_Data = (APTR)"";
211 ior->io_Length = 1;
212 DoIO((struct IORequest *)ior);
215 ior->io_Command=CMD_UPDATE;
216 DoIO ((struct IORequest *)ior);
218 return ior->io_Error ? FALSE : TRUE;
221 /*** WriteLong **************************************************************/
222 static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata)
224 ior->io_Data = (APTR)ldata;
225 ior->io_Length = 4;
226 ior->io_Command = CMD_WRITE;
227 DoIO( (struct IORequest *) ior);
229 if (ior->io_Actual == 4)
231 return ior->io_Error ? FALSE : TRUE;
234 return FALSE;
237 /*** MakeButton *************************************************************/
238 static Object *MakeButton(LONG code)
240 char buffer[2] = {0};
241 buffer[0] = code;
243 Object *btn = (Object *)TextObject,
244 ButtonFrame,
245 MUIA_Font, MUIV_Font_Button,
246 MUIA_Text_Contents, (IPTR)buffer,
247 MUIA_Text_PreParse, (IPTR)"\33c",
248 MUIA_InputMode , MUIV_InputMode_RelVerify,
249 MUIA_Background , MUII_ButtonBack,
250 MUIA_CycleChain , TRUE,
251 End;
252 return btn;
255 /*** OM_NEW *****************************************************************/
256 IPTR ASCIITable__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
258 struct ASCIITable_DATA *data = NULL;
259 Object *copy_button, *clear_button, *ascii_string, *key_group;
260 struct TagItem key_group_tags[200];
261 LONG i, code;
263 for (code = 32 , i = 0 ; code < 128 ; code++ , i++)
265 key_group_tags[i].ti_Tag = Child;
266 key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
268 for (code = 160 ; code < 256 ; code++, i++)
270 key_group_tags[i].ti_Tag = Child;
271 key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
273 key_group_tags[i].ti_Tag = MUIA_Group_Columns;
274 key_group_tags[i].ti_Data = 16;
275 key_group_tags[++i].ti_Tag = TAG_DONE;
276 key_group = MUI_NewObjectA(MUIC_Group, key_group_tags);
278 self = (Object *) DoSuperNewTags
280 CLASS, self, NULL,
281 Child, key_group,
282 Child, (IPTR) (RectangleObject,
283 MUIA_Rectangle_HBar, TRUE,
284 MUIA_FixHeight, 2,
285 End),
286 Child, (IPTR)(ascii_string = (Object *)StringObject,
287 StringFrame,
288 MUIA_String_MaxLen, MAXLEN,
289 End),
290 Child, (IPTR) (HGroup,
291 MUIA_Weight, 0,
292 MUIA_Group_SameSize, TRUE,
294 Child, (IPTR) (copy_button = SimpleButton(_(MSG_ASCIITABLE_GAD_COPY))),
295 Child, (IPTR) (clear_button = SimpleButton(_(MSG_ASCIITABLE_GAD_CLEAR))),
296 End),
297 TAG_MORE, message->ops_AttrList
300 if (self != NULL)
302 /*-- Store important variables -------------------------------------*/
303 data = INST_DATA(CLASS, self);
304 data->copy_button = copy_button;
305 data->clear_button = clear_button;
306 data->ascii_string = ascii_string;
308 /*-- Setup notifications -------------------------------------------*/
309 DoMethod
311 copy_button, MUIM_Notify, MUIA_Pressed, FALSE,
312 (IPTR) self, 1, MUIM_ASCIITable_Copy
314 DoMethod
316 clear_button, MUIM_Notify, MUIA_Pressed, FALSE,
317 (IPTR) self, 1, MUIM_ASCIITable_Clear
320 for (i = 0 ; i < 192 ; i++)
322 code = (i < 96) ? i + 32 : i + 64;
323 sprintf(data->shorthelp[i], "%c\n%d\n0x%x", (int)code, (int)code, (unsigned int)code);
324 set((Object *)key_group_tags[i].ti_Data, MUIA_ShortHelp, data->shorthelp[i]);
325 DoMethod
327 (Object *)key_group_tags[i].ti_Data, MUIM_Notify, MUIA_Pressed, FALSE,
328 (IPTR) self, 2, MUIM_ASCIITable_Insert, code
331 data->clip_req = CBOpen(0);
332 if (!data->clip_req)
334 showSimpleMessage(_(MSG_CANT_OPEN_CLIPDEVICE));
338 return (IPTR) self;
341 /*** OM_DISPOSE *************************************************************/
342 IPTR ASCIITable__OM_DISPOSE(Class *CLASS, Object *self, Msg message)
344 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
346 CBClose(data->clip_req);
348 return DoSuperMethodA(CLASS, self, message);
351 /*** MUIM_ASCIITable_Copy ***************************************************/
352 IPTR ASCIITable__MUIM_ASCIITable_Copy(Class *CLASS, Object *self, Msg msg)
354 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
355 CBWriteFTXT(data->clip_req, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
356 return TRUE;
359 /*** MUIM_ASCIITable_Clear **************************************************/
360 IPTR ASCIITable__MUIM_ASCIITable_Clear(Class *CLASS, Object *self, Msg msg)
362 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
363 data->buffer[0] = '\0';
364 set(data->ascii_string, MUIA_String_Contents, "");
365 return TRUE;
368 /*** MUIM_ASCIITable_Insert *************************************************/
369 IPTR ASCIITable__MUIM_ASCIITable_Insert(Class *CLASS, Object *self, struct MUIP_ASCIITable_Insert *msg)
371 struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
372 LONG len;
373 D(bug("insert code %d\n", msg->code));
374 strcpy(data->buffer, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
375 len = strlen(data->buffer);
376 if (len < MAXLEN)
378 data->buffer[len] = msg->code;
379 data->buffer[len+1] = '\0';
380 set(data->ascii_string, MUIA_String_Contents, data->buffer);
382 return TRUE;
385 /*** Setup ******************************************************************/
386 ZUNE_CUSTOMCLASS_5
388 ASCIITable, NULL, MUIC_Group, NULL,
389 OM_NEW, struct opSet *,
390 OM_DISPOSE, Msg,
391 MUIM_ASCIITable_Copy, Msg,
392 MUIM_ASCIITable_Clear, Msg,
393 MUIM_ASCIITable_Insert, struct MUIP_ASCIITable_Insert *
398 /*** Begin application ******************************************************/
401 static CONST_STRPTR _(ULONG id)
403 if (LocaleBase != NULL && catalog != NULL)
405 return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
407 else
409 return CatCompArray[id].cca_Str;
413 #define __(id) ((IPTR) _(id)) /* Get a message, as an IPTR */
415 /*** Locale_Initialize ******************************************************/
416 static int Locale_Initialize(VOID)
418 if (LocaleBase != NULL)
420 catalog = OpenCatalog
422 NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE
425 else
427 catalog = NULL;
429 return TRUE;
432 /*** Locale_Deinitialize ****************************************************/
433 static VOID Locale_Deinitialize(VOID)
435 if (LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
438 /*** GetArguments ***********************************************************/
439 static void GetArguments(int argc, char **argv)
441 static struct RDArgs *myargs;
442 static IPTR args[NUM_ARGS];
443 static UBYTE **wbargs;
444 static STRPTR cxname;
445 static struct WBStartup *argmsg;
446 static struct WBArg *wb_arg;
448 if (argc)
450 if (!(myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
452 Fault(IoErr(), 0, s, 256);
453 Cleanup(s);
455 if (args[ARG_CXPRI]) cx_pri = *(LONG*)args[ARG_CXPRI];
456 if (args[ARG_CXPOPKEY])
458 cx_popkey = StrDup((char *)args[ARG_CXPOPKEY]);
460 else
462 cx_popkey = StrDup(DEF_POPKEY);
464 if (args[ARG_CXPOPUP]) cx_popup = TRUE;
465 FreeArgs(myargs);
466 cxname = argv[0];
468 else
470 argmsg = (struct WBStartup *)argv;
471 wb_arg = argmsg->sm_ArgList;
472 cxname = wb_arg->wa_Name;
473 wbargs = ArgArrayInit(argc, (UBYTE**)argv);
474 cx_pri = ArgInt(wbargs, "CX_PRIORITY", 0);
475 cx_popkey = StrDup(ArgString(wbargs, "CX_POPKEY", DEF_POPKEY));
476 if (strnicmp(ArgString(wbargs, "CX_POPUP", "NO"), "Y", 1) == 0)
478 cx_popup = TRUE;
480 ArgArrayDone();
482 D(bug("ASCIITable Arguments pri %d popkey %s popup %d\n", cx_pri, cx_popkey, cx_popup));
483 disko = GetDiskObject(cxname);
486 /****************************************************************************/
487 static struct NewMenu nm[] =
489 {NM_TITLE, (STRPTR)MSG_MEN_PROJECT },
490 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_HIDE },
491 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ICONIFY },
492 {NM_ITEM, NM_BARLABEL },
493 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
494 {NM_END }
497 /*** InitMenus **************************************************************/
498 static void InitMenus(void)
500 struct NewMenu *actnm = nm;
502 for(actnm = nm; actnm->nm_Type != NM_END; actnm++)
504 if (actnm->nm_Label != NM_BARLABEL)
506 ULONG id = (IPTR)actnm->nm_Label;
507 CONST_STRPTR str = _(id);
509 if (actnm->nm_Type == NM_TITLE)
511 actnm->nm_Label = str;
512 } else {
513 actnm->nm_Label = str + 2;
514 if (str[0] != ' ') actnm->nm_CommKey = str;
516 actnm->nm_UserData = (APTR)(IPTR)id;
518 } /* if (actnm->nm_Label != NM_BARLABEL) */
520 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
523 /*** showSimpleMessage ******************************************************/
524 static void showSimpleMessage(CONST_STRPTR msgString)
526 struct EasyStruct easyStruct;
528 easyStruct.es_StructSize = sizeof(easyStruct);
529 easyStruct.es_Flags = 0;
530 easyStruct.es_Title = _(MSG_ASCIITABLE_CXNAME);
531 easyStruct.es_TextFormat = msgString;
532 easyStruct.es_GadgetFormat = _(MSG_OK);
534 if (IntuitionBase != NULL && !Cli() )
536 EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
538 else
540 PutStr(msgString);
544 /*** broker_func ************************************************************/
545 AROS_UFH3(void, broker_func,
546 AROS_UFHA(struct Hook *, h, A0),
547 AROS_UFHA(Object * , object, A2),
548 AROS_UFHA(CxMsg * , msg, A1))
550 AROS_USERFUNC_INIT
552 D(bug("ASCIITable: Broker hook called\n"));
553 if (CxMsgType(msg) == CXM_COMMAND)
555 if (CxMsgID(msg) == CXCMD_APPEAR)
557 CallHookPkt(&show_hook, NULL, NULL);
559 else if (CxMsgID(msg) == CXCMD_DISAPPEAR)
561 set(wnd, MUIA_Window_Open, FALSE);
564 AROS_USERFUNC_EXIT
567 /*** show_func ************************************************************/
568 AROS_UFH3(
569 void, show_func,
570 AROS_UFHA(struct Hook *, hook, A0),
571 AROS_UFHA(APTR *, obj, A2),
572 AROS_UFHA(APTR, param, A1)
575 AROS_USERFUNC_INIT
577 if (XGET(app, MUIA_Application_Iconified) == TRUE)
578 set(app, MUIA_Application_Iconified, FALSE);
579 else
580 set(wnd, MUIA_Window_Open, TRUE);
582 AROS_USERFUNC_EXIT
585 /*** MakeGUI ****************************************************************/
586 static void MakeGUI(void)
588 Object *menu;
589 static TEXT wintitle[100];
590 CxObj *popfilter;
592 menu = MUI_MakeObject(MUIO_MenustripNM, &nm, 0);
594 broker_hook.h_Entry = (HOOKFUNC)broker_func;
595 show_hook.h_Entry = (HOOKFUNC)show_func;
597 snprintf(wintitle, sizeof(wintitle), _(MSG_ASCIITABLE_WINTITLE), cx_popkey);
599 app = (Object *)ApplicationObject,
600 MUIA_Application_Title, __(MSG_ASCIITABLE_CXNAME),
601 MUIA_Application_Version, (IPTR)version,
602 MUIA_Application_Copyright, (IPTR)"Copyright © 2012, The AROS Development TEAM",
603 MUIA_Application_Author, (IPTR)"The AROS Development Team",
604 MUIA_Application_Description, __(MSG_ASCIITABLE_CXDESCR),
605 MUIA_Application_BrokerPri, cx_pri,
606 MUIA_Application_BrokerHook, (IPTR)&broker_hook,
607 MUIA_Application_Base, (IPTR)"ASCIITABLE",
608 MUIA_Application_SingleTask, TRUE,
609 MUIA_Application_Menustrip, (IPTR)menu,
610 MUIA_Application_DiskObject, (IPTR)disko,
611 SubWindow, (IPTR)(wnd = (Object *)WindowObject,
612 MUIA_Window_Title, (IPTR)wintitle,
613 MUIA_Window_ID, MAKE_ID('A', 'I', 'T', 'B'),
614 WindowContents, (IPTR)ASCIITableObject,
615 End,
616 End),
617 End;
619 if (! app)
620 Cleanup(NULL); // Propably double start
622 // enable hotkey
623 maintask = FindTask(NULL);
624 get(app, MUIA_Application_Broker, &broker);
625 get(app, MUIA_Application_BrokerPort, &brokermp);
626 if ( ! broker || ! brokermp)
627 Cleanup(_(MSG_CANT_CREATE_BROKER));
629 popfilter = CxFilter(cx_popkey);
630 if (popfilter)
632 CxObj *popsig = CxSignal(maintask, SIGBREAKB_CTRL_F);
633 if (popsig)
635 CxObj *trans;
636 AttachCxObj(popfilter, popsig);
637 trans = CxTranslate(NULL);
638 if (trans) AttachCxObj(popfilter, trans);
640 AttachCxObj(broker, popfilter);
643 DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
644 (IPTR)wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
646 DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE,
647 (IPTR)wnd, 2, MUIM_CallHook, &show_hook);
649 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_QUIT,
650 (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
652 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_HIDE,
653 (IPTR)wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
655 DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_ICONIFY,
656 (IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
659 /*** HandleAll **************************************************************/
660 static void HandleAll(void)
662 ULONG sigs = 0;
664 set(wnd, MUIA_Window_Open, cx_popup);
666 while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs)
667 != MUIV_Application_ReturnID_Quit)
669 if (sigs)
671 sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
672 if (sigs & SIGBREAKF_CTRL_C)
674 break;
676 if (sigs & SIGBREAKF_CTRL_F)
678 CallHookPkt(&show_hook, NULL, NULL);
684 /*** Cleanup ****************************************************************/
685 static void Cleanup(CONST_STRPTR txt)
687 MUI_DisposeObject(app);
688 FreeVec(cx_popkey);
689 FreeDiskObject(disko);
690 if (txt)
692 showSimpleMessage(txt);
693 exit(RETURN_ERROR);
695 exit(RETURN_OK);
698 /*** main *******************************************************************/
699 int main(int argc, char **argv)
701 D(bug("ASCIITable started\n"));
702 GetArguments(argc, argv);
703 InitMenus();
704 MakeGUI();
705 HandleAll();
706 Cleanup(NULL);
707 return RETURN_OK;
710 /****************************************************************************/
711 ADD2INIT(Locale_Initialize, 90);
712 ADD2EXIT(Locale_Deinitialize, 90);