2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
6 #include <intuition/intuition.h>
7 #include <libraries/gadtools.h>
8 #include <libraries/locale.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <proto/gadtools.h>
15 #include <proto/locale.h>
16 #include <proto/alib.h>
24 #define ARG_TEMPLATE "PUBSCREEN,TAPE/K"
26 enum {ARG_PUBSCREEN
,ARG_TAPE
,NUM_ARGS
};
28 #define MAX_VAL_LEN 13
30 #define INNER_SPACING_X 4
31 #define INNER_SPACING_Y 4
33 #define BUTTON_SPACING_X 4
34 #define BUTTON_SPACING_Y 4
36 #define BUTTON_LED_SPACING 4
38 #define NUM_BUTTONS 20
39 #define NUM_BUTTON_COLS 5
40 #define NUM_BUTTON_ROWS 4
42 #define BUTTON_EXTRA_WIDTH 8
43 #define BUTTON_EXTRA_HEIGHT 4
45 #define LED_EXTRA_HEIGHT 4
49 STATE_LEFTVAL
, STATE_OP
, STATE_RIGHTVAL
, STATE_EQU
86 static struct ButtonInfo bi
[NUM_BUTTONS
] =
88 {"7" ,BTYPE_7
, '7' , 0 },
89 {"8" ,BTYPE_8
, '8' , 0 },
90 {"9" ,BTYPE_9
, '9' , 0 },
91 {"CA" ,BTYPE_CA
, 'A' , 127 },
92 {"CE" ,BTYPE_CE
, 'E' , 0 },
94 {"4" ,BTYPE_4
, '4' , 0 },
95 {"5" ,BTYPE_5
, '5' , 0 },
96 {"6" ,BTYPE_6
, '6' , 0 },
97 {"×" ,BTYPE_MUL
, '*' , 'X' },
98 {":" ,BTYPE_DIV
, '/' , ':' },
100 {"1" ,BTYPE_1
, '1' , 0 },
101 {"2" ,BTYPE_2
, '2' , 0 },
102 {"3" ,BTYPE_3
, '3' , 0 },
103 {"+" ,BTYPE_ADD
, '+' , 0 },
104 {"-" ,BTYPE_SUB
, '-' , 0 },
106 {"0" ,BTYPE_0
, '0' , 0 },
107 {"." ,BTYPE_COMMA
, '.' , ',' },
108 {"«" ,BTYPE_BS
, 8 , 0 },
109 {"±" ,BTYPE_SIGN
, 'S' , 0 },
110 {"=" ,BTYPE_EQU
, '=' , 13 }
114 struct IntuitionBase
*IntuitionBase
;
115 struct GfxBase
*GfxBase
;
116 struct Library
*GadToolsBase
;
118 struct LocaleBase
*LocaleBase
;
120 struct Library
*LocaleBase
;
123 static struct Screen
*scr
;
124 static struct DrawInfo
*dri
;
125 static struct Gadget
*gadlist
, *gad
[NUM_BUTTONS
+ 2];
126 static struct Window
*win
;
127 static struct RDArgs
*MyArgs
;
131 static WORD win_borderleft
,win_bordertop
;
132 static WORD buttonwidth
,buttonheight
,ledheight
;
133 static WORD inner_winwidth
,inner_winheight
;
134 static WORD vallen
,state
,operation
;
138 static double leftval
,rightval
;
140 static char comma
,*pubscrname
;
141 static char ledstring
[256],visledstring
[256],
142 tempstring
[256],tapename
[256];
144 static char *deftapename
= "RAW:%ld/%ld/%ld/%ld/Calculator Tape/INACTIVE/SCREEN%s";
146 UBYTE version
[] = "$VER: Calculator 1.3 (07.10.2007) © AROS Dev Team";
148 static IPTR Args
[NUM_ARGS
];
150 static void Cleanup(char *msg
)
156 printf("Calculator: %s\n",msg
);
162 if (tapefh
) Close(tapefh
);
164 if (win
) CloseWindow(win
);
166 if (gadlist
) FreeGadgets(gadlist
);
168 if (vi
) FreeVisualInfo(vi
);
169 if (dri
) FreeScreenDrawInfo(scr
,dri
);
170 if (scr
) UnlockPubScreen(0,scr
);
172 if (MyArgs
) FreeArgs(MyArgs
);
174 if (LocaleBase
) CloseLibrary((struct Library
*)LocaleBase
);
175 if (GadToolsBase
) CloseLibrary(GadToolsBase
);
176 if (GfxBase
) CloseLibrary((struct Library
*)GfxBase
);
177 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
182 static void DosError(void)
184 Fault(IoErr(),0,tempstring
,255);
188 static void OpenLibs(void)
190 if (!(IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",39)))
192 Cleanup("Can't open intuition.library V39!");
195 if (!(GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library",39)))
197 Cleanup("Can't open graphics.library V39!");
200 if (!(GadToolsBase
= OpenLibrary("gadtools.library",39)))
202 Cleanup("Can't open gadtools.library V39!");
205 LocaleBase
= (struct LocaleBase
*)OpenLibrary("locale.library",39);
208 static void GetArguments(void)
210 if (!(MyArgs
= ReadArgs(ARG_TEMPLATE
,(IPTR
*)Args
,0)))
215 pubscrname
= (char *)Args
[ARG_PUBSCREEN
];
219 strcpy(tapename
,(char *)Args
[ARG_TAPE
]);
224 static void DoLocale(void)
230 if ((loc
= OpenLocale(0)))
232 comma
= loc
->loc_DecimalPoint
[0];
236 bi
[16].text
[0] = comma
;
239 static void GetVisual(void)
241 if (pubscrname
) scr
= LockPubScreen(pubscrname
);
245 if (!(scr
= LockPubScreen(0)))
247 Cleanup("Can't lock screen!");
251 if (!(dri
= GetScreenDrawInfo(scr
)))
253 Cleanup("Can't get drawinfo!");
256 if (!(vi
= GetVisualInfo(scr
,0)))
258 Cleanup("Can't get visual info!");
261 win_borderleft
= scr
->WBorLeft
;
263 /* SDuvan: was scr->WBorTop + scr->Font->ta_YSize + 1 */
264 win_bordertop
= scr
->WBorTop
+ dri
->dri_Font
->tf_YSize
+ 1;
268 static void InitGUI(void)
270 static struct RastPort temprp
;
274 InitRastPort(&temprp
);
275 SetFont(&temprp
,dri
->dri_Font
);
277 buttonheight
= dri
->dri_Font
->tf_YSize
+ BUTTON_EXTRA_HEIGHT
;
279 for(i
= 0;i
< NUM_BUTTONS
;i
++)
281 len
= TextLength(&temprp
,bi
[i
].text
,strlen(bi
[i
].text
));
282 if (len
> buttonwidth
) buttonwidth
= len
;
285 buttonwidth
+= BUTTON_EXTRA_WIDTH
;
287 ledheight
= dri
->dri_Font
->tf_YSize
+ LED_EXTRA_HEIGHT
;
289 inner_winwidth
= buttonwidth
* NUM_BUTTON_COLS
+
290 BUTTON_SPACING_X
* (NUM_BUTTON_COLS
- 1) +
293 inner_winheight
= buttonheight
* NUM_BUTTON_ROWS
+
294 BUTTON_SPACING_Y
* (NUM_BUTTON_ROWS
- 1) +
300 DeinitRastPort(&temprp
);
302 strcpy(ledstring
,"0");
305 static void MakeGadgets(void)
307 struct Gadget
*mygad
= 0;
308 struct NewGadget ng
= {0};
311 ng
.ng_VisualInfo
= vi
;
313 mygad
= CreateContext(&gadlist
);
315 ng
.ng_GadgetID
= BTYPE_LED
;
317 ng
.ng_LeftEdge
= win_borderleft
+ INNER_SPACING_X
;
318 ng
.ng_TopEdge
= win_bordertop
+ INNER_SPACING_Y
;
319 ng
.ng_Width
= inner_winwidth
- INNER_SPACING_X
* 2;
320 ng
.ng_Height
= ledheight
;
322 mygad
= gad
[BTYPE_LED
] = CreateGadget(TEXT_KIND
,
325 GTTX_Text
, (IPTR
) ledstring
,
328 GTTX_Justification
,GTJ_RIGHT
,
333 ng
.ng_TopEdge
= win_bordertop
+
338 ng
.ng_Width
= buttonwidth
;
339 ng
.ng_Height
= buttonheight
;
341 for(row
= 0; row
< NUM_BUTTON_ROWS
; row
++)
343 for(col
= 0; col
< NUM_BUTTON_COLS
; col
++, i
++)
345 ng
.ng_GadgetID
= bi
[i
].type
;
347 ng
.ng_LeftEdge
= win_borderleft
+
349 col
* (buttonwidth
+ BUTTON_SPACING_X
);
351 ng
.ng_GadgetText
= bi
[i
].text
;
353 mygad
= gad
[bi
[i
].type
] = CreateGadgetA(BUTTON_KIND
,
358 } /* for(col = 0;col < NUM_BUTTON_COLS; col++) */
360 ng
.ng_TopEdge
+= buttonheight
+ BUTTON_SPACING_Y
;
362 } /* for(row = 0; row < NUM_BUTTON_ROWS; row++) */
366 Cleanup("Can't create gadgets!");
371 static void MakeWin(void)
373 win
= OpenWindowTags(0,WA_PubScreen
,(IPTR
)scr
,
376 WA_InnerWidth
,inner_winwidth
,
377 WA_InnerHeight
,inner_winheight
,
379 WA_Title
,(IPTR
)"Calculator",
384 WA_SimpleRefresh
,TRUE
,
385 WA_IDCMP
,IDCMP_CLOSEWINDOW
|
390 WA_Gadgets
,(IPTR
)gadlist
,
393 if (!win
) Cleanup("Can't open window!");
395 GT_RefreshWindow(win
,0);
397 ScreenToFront(win
->WScreen
);
400 static void OpenTape(void)
403 struct PubScreenNode
*psn
;
409 l
= LockPubScreenList();
411 psn
= (struct PubScreenNode
*)l
->lh_Head
;
413 while (psn
->psn_Node
.ln_Succ
)
415 if (psn
->psn_Screen
== scr
)
417 if (psn
->psn_Node
.ln_Name
)
419 scrname
= psn
->psn_Node
.ln_Name
;
423 psn
= (struct PubScreenNode
*)psn
->psn_Node
.ln_Succ
;
426 UnlockPubScreenList();
428 w
= win
->Width
* 5 / 4;
434 if (x
> (scr
->Width
- (x
+ w
)))
440 sprintf(tapename
,deftapename
,x
,y
,w
,h
,scrname
);
443 if (!(tapefh
= Open(tapename
,MODE_NEWFILE
)))
449 static double GetValue(void)
454 sp
= strchr(ledstring
,comma
);
461 val
= strtod(ledstring
,0);
468 static void GetLeftValue(void)
470 leftval
= GetValue();
473 static void GetRightValue(void)
475 rightval
= GetValue();
478 static void LeftValToLED(void)
482 sprintf(ledstring
,"%f",leftval
);
484 sp
= strchr(ledstring
,'.');
485 if (!sp
) sp
= strchr(ledstring
,',');
489 static char *DoOperation(void)
510 matherr
= "Division by zero!";
517 if (leftval
> 9999999999999.0) // because of MAX_VAL_LEN
519 matherr
= "Buffer overflow!";
522 if (!matherr
) LeftValToLED();
527 static void RefreshLED(void)
529 strcpy(visledstring
,ledstring
);
531 if ((ledstring
[0] == ',') ||
532 (ledstring
[0] == '\0') ||
533 ((ledstring
[0] >= '0') && (ledstring
[0] <= '9')))
535 visledstring
[0] = '\0';
537 if ((ledstring
[0] == ',') ||
538 (ledstring
[0] == '.') ||
539 (ledstring
[0] == '\0'))
541 strcpy(visledstring
,"0");
543 strcat(visledstring
,ledstring
);
546 GT_SetGadgetAttrs(gad
[BTYPE_LED
],
549 GTTX_Text
,(IPTR
)visledstring
,
553 static void HandleButton(WORD type
)
557 BOOL refresh_led
= FALSE
;
572 if ((strchr(ledstring
,comma
))) checklen
--;
573 if ((strchr(ledstring
,'-'))) checklen
--;
575 if (checklen
< MAX_VAL_LEN
)
577 if (state
== STATE_OP
)
579 state
= STATE_RIGHTVAL
;
580 } else if (state
== STATE_EQU
)
582 state
= STATE_LEFTVAL
;
585 if ((vallen
> 0) || (type
!= BTYPE_0
))
587 ledstring
[vallen
++] = type
+ '0';
589 ledstring
[vallen
] = '\0';
593 } /* if (vallen < MAX_VAL_LEN) */
597 if (!strchr(ledstring
,comma
))
599 if (state
== STATE_OP
)
601 state
= STATE_RIGHTVAL
;
602 } else if (state
== STATE_EQU
)
604 state
= STATE_LEFTVAL
;
607 ledstring
[vallen
++] = comma
;
608 ledstring
[vallen
] = '\0';
612 } /* if (!strchr(ledstring,comma)) */
619 operation
= BTYPE_ADD
;
621 state
= STATE_LEFTVAL
;
623 strcpy(ledstring
,"0");
626 if (tapefh
) FPutC(tapefh
, '\n');
631 strcpy(ledstring
,"0");
650 ledstring
[--vallen
] = '\0';
651 if (vallen
== 0) strcpy(ledstring
,"0");
661 if (ledstring
[0] == '-')
663 strcpy(ledstring
,&ledstring
[1]);
665 strcpy(tempstring
,ledstring
);
666 strcpy(ledstring
,"-");
667 strcat(ledstring
,tempstring
);
693 strcpy(ledstring
,"0");
698 FPuts(tapefh
, visledstring
);
709 matherr
= DoOperation();
717 (operation
== BTYPE_ADD
) ? "+" :
718 (operation
== BTYPE_SUB
) ? "-" :
719 (operation
== BTYPE_DIV
) ? ":" :
722 FPuts(tapefh
, visledstring
);
728 } /* switch(state) */
734 if (state
== STATE_LEFTVAL
)
740 FPuts(tapefh
, visledstring
);
745 else if (state
== STATE_RIGHTVAL
)
751 (operation
== BTYPE_ADD
) ? "+" :
752 (operation
== BTYPE_SUB
) ? "-" :
753 (operation
== BTYPE_DIV
) ? ":" :
756 FPuts(tapefh
, visledstring
);
762 matherr
= DoOperation();
772 FPuts(tapefh
, "=\t");
773 FPuts(tapefh
, visledstring
);
786 leftval
= rightval
= 0.0;
787 state
= STATE_LEFTVAL
;
788 operation
= BTYPE_ADD
;
790 strcpy(ledstring
,matherr
);
794 if (refresh_led
) RefreshLED();
798 static void HandleAll(void)
800 struct IntuiMessage
*msg
;
806 if (dotape
) OpenTape();
810 signals
= Wait(1L << win
->UserPort
->mp_SigBit
| SIGBREAKF_CTRL_C
);
812 if (signals
& (1L << win
->UserPort
->mp_SigBit
))
814 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
818 case IDCMP_CLOSEWINDOW
:
822 case IDCMP_REFRESHWINDOW
:
823 GT_BeginRefresh(win
);
824 GT_EndRefresh(win
,TRUE
);
828 HandleButton(((struct Gadget
*)msg
->IAddress
)->GadgetID
);
831 case IDCMP_VANILLAKEY
:
832 icode
= toupper(msg
->Code
);
834 for(i
= 0;i
< NUM_BUTTONS
;i
++)
836 if ((icode
== bi
[i
].key1
) ||
837 (icode
== bi
[i
].key2
))
846 } else if (icode
== 27)
852 } /* switch(msg->Class) */
854 ReplyMsg((struct Message
*)msg
);
855 } /* while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
856 } /* if(signals & (1L << win->UserPort->mp_SigBit)) */
857 if (signals
& SIGBREAKF_CTRL_C
)
860 } /* while(!quitme) */