2 Copyright © 1995-2003, 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
;
117 struct LocaleBase
*LocaleBase
;
119 static struct Screen
*scr
;
120 static struct DrawInfo
*dri
;
121 static struct Gadget
*gadlist
, *gad
[NUM_BUTTONS
+ 2];
122 static struct Window
*win
;
123 static struct RDArgs
*MyArgs
;
127 static WORD win_borderleft
,win_bordertop
;
128 static WORD buttonwidth
,buttonheight
,ledheight
;
129 static WORD inner_winwidth
,inner_winheight
;
130 static WORD vallen
,state
,operation
;
134 static double leftval
,rightval
;
136 static char comma
,*pubscrname
;
137 static char ledstring
[256],visledstring
[256],
138 tempstring
[256],tapename
[256];
140 static char *deftapename
= "RAW:%ld/%ld/%ld/%ld/Calculator Tape/INACTIVE/SCREEN%s";
142 UBYTE version
[] = "$VER: Calculator 1.1 (1.5.2001)";
144 static LONG Args
[NUM_ARGS
];
146 static void Cleanup(char *msg
)
152 printf("Calculator: %s\n",msg
);
158 if (tapefh
) fclose(tapefh
);
160 if (win
) CloseWindow(win
);
162 if (gadlist
) FreeGadgets(gadlist
);
164 if (vi
) FreeVisualInfo(vi
);
165 if (dri
) FreeScreenDrawInfo(scr
,dri
);
166 if (scr
) UnlockPubScreen(0,scr
);
168 if (MyArgs
) FreeArgs(MyArgs
);
170 if (LocaleBase
) CloseLibrary((struct Library
*)LocaleBase
);
171 if (GadToolsBase
) CloseLibrary(GadToolsBase
);
172 if (GfxBase
) CloseLibrary((struct Library
*)GfxBase
);
173 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
178 static void DosError(void)
180 Fault(IoErr(),0,tempstring
,255);
184 static void OpenLibs(void)
186 if (!(IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",39)))
188 Cleanup("Can't open intuition.library V39!");
191 if (!(GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library",39)))
193 Cleanup("Can't open graphics.library V39!");
196 if (!(GadToolsBase
= OpenLibrary("gadtools.library",39)))
198 Cleanup("Can't open gadtools.library V39!");
201 LocaleBase
= (struct LocaleBase
*)OpenLibrary("locale.library",39);
204 static void GetArguments(void)
206 if (!(MyArgs
= ReadArgs(ARG_TEMPLATE
,(LONG
*)Args
,0)))
211 pubscrname
= (char *)Args
[ARG_PUBSCREEN
];
215 strcpy(tapename
,(char *)Args
[ARG_TAPE
]);
220 static void DoLocale(void)
222 //struct Locale *loc;
226 /* SDuvan: removed Locale code as it seemed to cause segfaults
227 when running calculator several times */
228 // if ((loc = OpenLocale(0)))
230 // comma = loc->loc_DecimalPoint[0];
234 bi
[16].text
[0] = comma
;
237 static void GetVisual(void)
239 if (pubscrname
) scr
= LockPubScreen(pubscrname
);
243 if (!(scr
= LockPubScreen(0)))
245 Cleanup("Can't lock screen!");
249 if (!(dri
= GetScreenDrawInfo(scr
)))
251 Cleanup("Can't get drawinfo!");
254 if (!(vi
= GetVisualInfo(scr
,0)))
256 Cleanup("Can't get visual info!");
259 win_borderleft
= scr
->WBorLeft
;
261 /* SDuvan: was scr->WBorTop + scr->Font->ta_YSize + 1 */
262 win_bordertop
= scr
->WBorTop
+ dri
->dri_Font
->tf_YSize
+ 1;
266 static void InitGUI(void)
268 static struct RastPort temprp
;
272 InitRastPort(&temprp
);
273 SetFont(&temprp
,dri
->dri_Font
);
275 buttonheight
= dri
->dri_Font
->tf_YSize
+ BUTTON_EXTRA_HEIGHT
;
277 for(i
= 0;i
< NUM_BUTTONS
;i
++)
279 len
= TextLength(&temprp
,bi
[i
].text
,strlen(bi
[i
].text
));
280 if (len
> buttonwidth
) buttonwidth
= len
;
283 buttonwidth
+= BUTTON_EXTRA_WIDTH
;
285 ledheight
= dri
->dri_Font
->tf_YSize
+ LED_EXTRA_HEIGHT
;
287 inner_winwidth
= buttonwidth
* NUM_BUTTON_COLS
+
288 BUTTON_SPACING_X
* (NUM_BUTTON_COLS
- 1) +
291 inner_winheight
= buttonheight
* NUM_BUTTON_ROWS
+
292 BUTTON_SPACING_Y
* (NUM_BUTTON_ROWS
- 1) +
297 DeinitRastPort(&temprp
);
298 strcpy(ledstring
,"0");
301 static void MakeGadgets(void)
303 struct Gadget
*mygad
= 0;
304 struct NewGadget ng
= {0};
307 ng
.ng_VisualInfo
= vi
;
309 mygad
= CreateContext(&gadlist
);
311 ng
.ng_GadgetID
= BTYPE_LED
;
313 ng
.ng_LeftEdge
= win_borderleft
+ INNER_SPACING_X
;
314 ng
.ng_TopEdge
= win_bordertop
+ INNER_SPACING_Y
;
315 ng
.ng_Width
= inner_winwidth
- INNER_SPACING_X
* 2;
316 ng
.ng_Height
= ledheight
;
318 mygad
= gad
[BTYPE_LED
] = CreateGadget(TEXT_KIND
,
321 GTTX_Text
, (IPTR
) ledstring
,
324 GTTX_Justification
,GTJ_RIGHT
,
329 ng
.ng_TopEdge
= win_bordertop
+
334 ng
.ng_Width
= buttonwidth
;
335 ng
.ng_Height
= buttonheight
;
337 for(row
= 0; row
< NUM_BUTTON_ROWS
; row
++)
339 for(col
= 0; col
< NUM_BUTTON_COLS
; col
++, i
++)
341 ng
.ng_GadgetID
= bi
[i
].type
;
343 ng
.ng_LeftEdge
= win_borderleft
+
345 col
* (buttonwidth
+ BUTTON_SPACING_X
);
347 ng
.ng_GadgetText
= bi
[i
].text
;
349 mygad
= gad
[bi
[i
].type
] = CreateGadgetA(BUTTON_KIND
,
354 } /* for(col = 0;col < NUM_BUTTON_COLS; col++) */
356 ng
.ng_TopEdge
+= buttonheight
+ BUTTON_SPACING_Y
;
358 } /* for(row = 0; row < NUM_BUTTON_ROWS; row++) */
362 Cleanup("Can't create gadgets!");
367 static void MakeWin(void)
369 win
= OpenWindowTags(0,WA_PubScreen
,(IPTR
)scr
,
372 WA_InnerWidth
,inner_winwidth
,
373 WA_InnerHeight
,inner_winheight
,
375 WA_Title
,(IPTR
)"Calculator",
380 WA_SimpleRefresh
,TRUE
,
381 WA_IDCMP
,IDCMP_CLOSEWINDOW
|
386 WA_Gadgets
,(IPTR
)gadlist
,
389 if (!win
) Cleanup("Can't open window!");
391 GT_RefreshWindow(win
,0);
393 ScreenToFront(win
->WScreen
);
396 static void OpenTape(void)
399 struct PubScreenNode
*psn
;
405 l
= LockPubScreenList();
407 psn
= (struct PubScreenNode
*)l
->lh_Head
;
409 while (psn
->psn_Node
.ln_Succ
)
411 if (psn
->psn_Screen
== scr
)
413 if (psn
->psn_Node
.ln_Name
)
415 scrname
= psn
->psn_Node
.ln_Name
;
419 psn
= (struct PubScreenNode
*)psn
->psn_Node
.ln_Succ
;
422 UnlockPubScreenList();
424 w
= win
->Width
* 5 / 4;
430 if (x
> (scr
->Width
- (x
+ w
)))
436 sprintf(tapename
,deftapename
,x
,y
,w
,h
,scrname
);
439 if (!(tapefh
= fopen(tapename
,"w")))
445 static double GetValue(void)
450 sp
= strchr(ledstring
,comma
);
457 val
= strtod(ledstring
,0);
464 static void GetLeftValue(void)
466 leftval
= GetValue();
469 static void GetRightValue(void)
471 rightval
= GetValue();
474 static void LeftValToLED(void)
478 sprintf(ledstring
,"%f",leftval
);
480 sp
= strchr(ledstring
,'.');
481 if (!sp
) sp
= strchr(ledstring
,',');
485 static char *DoOperation(void)
506 matherr
= "Division by zero!";
513 if (!matherr
) LeftValToLED();
518 static void RefreshLED(void)
520 strcpy(visledstring
,ledstring
);
522 if ((ledstring
[0] == ',') ||
523 (ledstring
[0] == '\0') ||
524 ((ledstring
[0] >= '0') && (ledstring
[0] <= '9')))
526 visledstring
[0] = '\0';
528 if ((ledstring
[0] == ',') ||
529 (ledstring
[0] == '.') ||
530 (ledstring
[0] == '\0'))
532 strcpy(visledstring
,"0");
534 strcat(visledstring
,ledstring
);
537 GT_SetGadgetAttrs(gad
[BTYPE_LED
],
540 GTTX_Text
,(IPTR
)visledstring
,
544 static void HandleButton(WORD type
)
548 BOOL refresh_led
= FALSE
;
563 if ((strchr(ledstring
,comma
))) checklen
--;
564 if ((strchr(ledstring
,'-'))) checklen
--;
566 if (checklen
< MAX_VAL_LEN
)
568 if (state
== STATE_OP
)
570 state
= STATE_RIGHTVAL
;
571 } else if (state
== STATE_EQU
)
573 state
= STATE_LEFTVAL
;
576 if ((vallen
> 0) || (type
!= BTYPE_0
))
578 ledstring
[vallen
++] = type
+ '0';
580 ledstring
[vallen
] = '\0';
584 } /* if (vallen < MAX_VAL_LEN) */
588 if (!strchr(ledstring
,comma
))
590 if (state
== STATE_OP
)
592 state
= STATE_RIGHTVAL
;
593 } else if (state
== STATE_EQU
)
595 state
= STATE_LEFTVAL
;
598 ledstring
[vallen
++] = comma
;
599 ledstring
[vallen
] = '\0';
603 } /* if (!strchr(ledstring,comma)) */
610 operation
= BTYPE_ADD
;
612 state
= STATE_LEFTVAL
;
614 strcpy(ledstring
,"0");
617 if (tapefh
) fputs("\n",tapefh
);
622 strcpy(ledstring
,"0");
641 ledstring
[--vallen
] = '\0';
642 if (vallen
== 0) strcpy(ledstring
,"0");
652 if (ledstring
[0] == '-')
654 strcpy(ledstring
,&ledstring
[1]);
656 strcpy(tempstring
,ledstring
);
657 strcpy(ledstring
,"-");
658 strcat(ledstring
,tempstring
);
684 strcpy(ledstring
,"0");
688 fprintf(tapefh
,"\t%s\n",visledstring
);
698 matherr
= DoOperation();
705 fprintf(tapefh
,"%s\t%s\n",(operation
== BTYPE_ADD
) ? "+" :
706 (operation
== BTYPE_SUB
) ? "-" :
707 (operation
== BTYPE_DIV
) ? ":" :
713 } /* switch(state) */
719 if (state
== STATE_LEFTVAL
)
724 fprintf(tapefh
,"\t%s\n",visledstring
);
728 else if (state
== STATE_RIGHTVAL
)
733 fprintf(tapefh
,"%s\t%s\n",(operation
== BTYPE_ADD
) ? "+" :
734 (operation
== BTYPE_SUB
) ? "-" :
735 (operation
== BTYPE_DIV
) ? ":" :
741 matherr
= DoOperation();
751 fprintf(tapefh
,"=\t%s\n",visledstring
);
763 leftval
= rightval
= 0.0;
764 state
= STATE_LEFTVAL
;
765 operation
= BTYPE_ADD
;
767 strcpy(ledstring
,matherr
);
771 if (refresh_led
) RefreshLED();
775 static void HandleAll(void)
777 struct IntuiMessage
*msg
;
783 if (dotape
) OpenTape();
787 signals
= Wait(1L << win
->UserPort
->mp_SigBit
| SIGBREAKF_CTRL_C
);
789 if (signals
& (1L << win
->UserPort
->mp_SigBit
))
791 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
795 case IDCMP_CLOSEWINDOW
:
799 case IDCMP_REFRESHWINDOW
:
800 GT_BeginRefresh(win
);
801 GT_EndRefresh(win
,TRUE
);
805 HandleButton(((struct Gadget
*)msg
->IAddress
)->GadgetID
);
808 case IDCMP_VANILLAKEY
:
809 icode
= toupper(msg
->Code
);
811 for(i
= 0;i
< NUM_BUTTONS
;i
++)
813 if ((icode
== bi
[i
].key1
) ||
814 (icode
== bi
[i
].key2
))
823 } else if (icode
== 27)
829 } /* switch(msg->Class) */
831 ReplyMsg((struct Message
*)msg
);
832 } /* while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
833 } /* if(signals & (1L << win->UserPort->mp_SigBit)) */
834 if (signals
& SIGBREAKF_CTRL_C
)
837 } /* while(!quitme) */