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
;
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.1 (1.5.2001)";
148 static LONG Args
[NUM_ARGS
];
150 static void Cleanup(char *msg
)
156 printf("Calculator: %s\n",msg
);
162 if (tapefh
) fclose(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
,(LONG
*)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
= fopen(tapename
,"w")))
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 (!matherr
) LeftValToLED();
522 static void RefreshLED(void)
524 strcpy(visledstring
,ledstring
);
526 if ((ledstring
[0] == ',') ||
527 (ledstring
[0] == '\0') ||
528 ((ledstring
[0] >= '0') && (ledstring
[0] <= '9')))
530 visledstring
[0] = '\0';
532 if ((ledstring
[0] == ',') ||
533 (ledstring
[0] == '.') ||
534 (ledstring
[0] == '\0'))
536 strcpy(visledstring
,"0");
538 strcat(visledstring
,ledstring
);
541 GT_SetGadgetAttrs(gad
[BTYPE_LED
],
544 GTTX_Text
,(IPTR
)visledstring
,
548 static void HandleButton(WORD type
)
552 BOOL refresh_led
= FALSE
;
567 if ((strchr(ledstring
,comma
))) checklen
--;
568 if ((strchr(ledstring
,'-'))) checklen
--;
570 if (checklen
< MAX_VAL_LEN
)
572 if (state
== STATE_OP
)
574 state
= STATE_RIGHTVAL
;
575 } else if (state
== STATE_EQU
)
577 state
= STATE_LEFTVAL
;
580 if ((vallen
> 0) || (type
!= BTYPE_0
))
582 ledstring
[vallen
++] = type
+ '0';
584 ledstring
[vallen
] = '\0';
588 } /* if (vallen < MAX_VAL_LEN) */
592 if (!strchr(ledstring
,comma
))
594 if (state
== STATE_OP
)
596 state
= STATE_RIGHTVAL
;
597 } else if (state
== STATE_EQU
)
599 state
= STATE_LEFTVAL
;
602 ledstring
[vallen
++] = comma
;
603 ledstring
[vallen
] = '\0';
607 } /* if (!strchr(ledstring,comma)) */
614 operation
= BTYPE_ADD
;
616 state
= STATE_LEFTVAL
;
618 strcpy(ledstring
,"0");
621 if (tapefh
) fputs("\n",tapefh
);
626 strcpy(ledstring
,"0");
645 ledstring
[--vallen
] = '\0';
646 if (vallen
== 0) strcpy(ledstring
,"0");
656 if (ledstring
[0] == '-')
658 strcpy(ledstring
,&ledstring
[1]);
660 strcpy(tempstring
,ledstring
);
661 strcpy(ledstring
,"-");
662 strcat(ledstring
,tempstring
);
688 strcpy(ledstring
,"0");
692 fprintf(tapefh
,"\t%s\n",visledstring
);
702 matherr
= DoOperation();
709 fprintf(tapefh
,"%s\t%s\n",(operation
== BTYPE_ADD
) ? "+" :
710 (operation
== BTYPE_SUB
) ? "-" :
711 (operation
== BTYPE_DIV
) ? ":" :
717 } /* switch(state) */
723 if (state
== STATE_LEFTVAL
)
728 fprintf(tapefh
,"\t%s\n",visledstring
);
732 else if (state
== STATE_RIGHTVAL
)
737 fprintf(tapefh
,"%s\t%s\n",(operation
== BTYPE_ADD
) ? "+" :
738 (operation
== BTYPE_SUB
) ? "-" :
739 (operation
== BTYPE_DIV
) ? ":" :
745 matherr
= DoOperation();
755 fprintf(tapefh
,"=\t%s\n",visledstring
);
767 leftval
= rightval
= 0.0;
768 state
= STATE_LEFTVAL
;
769 operation
= BTYPE_ADD
;
771 strcpy(ledstring
,matherr
);
775 if (refresh_led
) RefreshLED();
779 static void HandleAll(void)
781 struct IntuiMessage
*msg
;
787 if (dotape
) OpenTape();
791 signals
= Wait(1L << win
->UserPort
->mp_SigBit
| SIGBREAKF_CTRL_C
);
793 if (signals
& (1L << win
->UserPort
->mp_SigBit
))
795 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
799 case IDCMP_CLOSEWINDOW
:
803 case IDCMP_REFRESHWINDOW
:
804 GT_BeginRefresh(win
);
805 GT_EndRefresh(win
,TRUE
);
809 HandleButton(((struct Gadget
*)msg
->IAddress
)->GadgetID
);
812 case IDCMP_VANILLAKEY
:
813 icode
= toupper(msg
->Code
);
815 for(i
= 0;i
< NUM_BUTTONS
;i
++)
817 if ((icode
== bi
[i
].key1
) ||
818 (icode
== bi
[i
].key2
))
827 } else if (icode
== 27)
833 } /* switch(msg->Class) */
835 ReplyMsg((struct Message
*)msg
);
836 } /* while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
837 } /* if(signals & (1L << win->UserPort->mp_SigBit)) */
838 if (signals
& SIGBREAKF_CTRL_C
)
841 } /* while(!quitme) */