fbui | Framebuffer-based graphical environment |
| download: https://git.y1.nz/archives/fbui.tar.gz | |
| README | Files | Log | Refs |
libfbui/Calc/main.c
1
2 /*=========================================================================
3 *
4 * fbcalc, a simple calculator for FBUI (in-kernel framebuffer UI)
5 * Copyright (C) 2004 Zachary T Smith, fbui@comcast.net
6 *
7 * This module is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This module is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this module; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * (See the file COPYING in the main directory of this archive for
22 * more details.)
23 *
24 *=======================================================================*/
25
26
27 #define VERSION "0.2"
28
29
30 #include <stdio.h>
31 #include <time.h>
32 #include <unistd.h>
33 #include <math.h>
34
35 #include "libfbui.h"
36
37
38 static short win_w;
39 static short win_h;
40
41 static short button_width;
42 static short button_height;
43
44 static int rows = 6;
45 static int cols = 4;
46
47 static Display *dpy = NULL;
48 static Window *win = NULL;
49 static Font *font = NULL;
50
51 static unsigned long fgcolor = RGB_BLACK;
52 static unsigned long bgcolor = 0xC0C0C0;
53
54 static char diverr = false;
55
56 static char *keystring[] = {
57 "STO", "RCL", "CLR", "CE",
58 "1/x", "sqrt", "x^2", "/",
59 "7", "8", "9", "*",
60 "4", "5", "6", "-",
61 "1", "2", "3", "+",
62 "0", ".", "-", "=",
63 NULL
64
65 };
66
67 static char begin_new_value = false;
68
69 static double stored = 0.0;
70 static double result = 0.0;
71 static double value = 0.0;
72
73 static char got_point = 0;
74 static char rightgoing_place = 0;
75
76 static int operation = 0;
77
78
79 int whichbutton (short x, short y)
80 {
81 int i,j;
82
83 for (j=0; j<rows; j++) {
84 for (i=0; i<cols; i++) {
85 int x0 = i*button_width + (i+1) * button_width/2;
86 int y0 = (j+1)*button_height + (j+2) * button_height/2;
87 int x1 = x0 + button_width - 1;
88 int y1 = y0 + button_height - 1;
89
90 if (x >= x0 && x <= x1 && y >= y0 && y <= y1)
91 return i + j*cols;
92 }
93 }
94 return -1;
95 }
96
97
98 void draw_button (Display *dpy, Window *win, int i, int j, char highlight)
99 {
100 if (!dpy || !win)
101 return;
102 if (i<0 || j<0 || i>=cols || j>=rows)
103 return;
104
105 int x0 = i*button_width + (i+1) * button_width/2;
106 int y0 = (j+1)*button_height + (j+2) * button_height/2;
107 int x1 = x0 + button_width - 1;
108 int y1 = y0 + button_height - 1;
109
110 if (highlight)
111 fbui_fill_area (dpy, win, x0,y0,x1,y1, RGB_CYAN);
112
113 fbui_draw_rect (dpy, win, x0,y0,x1,y1, RGB_BLACK);
114
115 char *str = keystring [i + j*cols];
116
117 short w,a,d,h;
118 font_string_dims (font,str,&w,&a,&d);
119 h = a+d;
120 w = (button_width-w)/2;
121 h = (button_height-h)/2;
122
123 fbui_draw_string (dpy,win,NULL,
124 w+x0+1,h+y0+1, str, fgcolor);
125 }
126
127
128 void update_value ()
129 {
130 int x0 = button_width/2;
131 int y0 = button_height/2;
132 int x1 = win_w - 1 - x0;
133 int y1 = y0 + button_height - 1;
134 fbui_fill_area (dpy,win,x0,y0,x1,y1,RGB_WHITE);
135 fbui_draw_rect (dpy,win,x0,y0,x1,y1,fgcolor);
136 char valstr[100];
137
138 if (diverr)
139 sprintf (valstr, "Divide Error");
140 else
141 sprintf (valstr, "%.12g", value);
142
143 short w,a,d,h;
144 font_string_dims (font,valstr,&w,&a,&d);
145 h = a+d;
146 w = (win_w - w - button_width);
147 h = (button_height-h)/2;
148 fbui_draw_string (dpy,win,NULL,
149 w+x0,h+y0+1, valstr, fgcolor);
150 }
151
152
153 void
154 insert_digit (char ch)
155 {
156 if (ch < '0' || ch > '9')
157 return;
158
159 if (begin_new_value)
160 value = 0.0;
161 begin_new_value = false;
162
163 ch -= '0';
164
165 if (!got_point) {
166 value *= 10.0;
167 value += ch;
168 update_value ();
169 } else {
170 int i = rightgoing_place;
171 double tmp = ch;
172 while(i--)
173 tmp /= 10.0;
174 tmp /= 10.0;
175 ++rightgoing_place;
176 value += tmp;
177 }
178 update_value();
179 }
180
181 enum {
182
183 ADD = 1,
184 SUBTRACT = 2,
185 MULTIPLY = 3,
186 DIVIDE = 4
187
188 };
189
190
191 void perform_equals ()
192 {
193 printf ("____________\n");
194 printf ("value=%g\n", value);
195 printf ("result=%g\n", result);
196 printf ("operation=%d\n", operation);
197 switch (operation) {
198 case ADD:
199 result += value;
200 break;
201 case SUBTRACT:
202 result -= value;
203 break;
204 case MULTIPLY:
205 result *= value;
206 break;
207 case DIVIDE:
208 if (value != 0)
209 result /= value;
210 else
211 diverr = true;
212 break;
213 }
214 operation = 0;
215 value = result;
216 update_value();
217 begin_new_value = true;
218 }
219
220 void perform_neg()
221 {
222 value = -value;
223 update_value();
224 }
225
226 void perform_ix()
227 {
228 if (!value)
229 diverr=true;
230 else
231 value = 1.0/value;
232 update_value();
233 }
234
235 void perform_sqrt()
236 {
237 value = sqrt(value);
238 update_value();
239 }
240
241 void perform_square()
242 {
243 value = value*value;
244 update_value();
245 }
246
247 void perform_point()
248 {
249 if (!got_point) {
250 got_point = true;
251 rightgoing_place = 0;
252 }
253 }
254
255 void perform_store()
256 {
257 stored = value;
258 got_point = false;
259 begin_new_value = true;
260 }
261
262 void perform_recall()
263 {
264 value = stored;
265 got_point = false;
266 begin_new_value = true;
267 update_value();
268 }
269
270 void perform_clear()
271 {
272 value = 0.0;
273 got_point = false;
274 diverr = false;
275 update_value();
276 }
277 void perform_clearall()
278 {
279 value = result = stored = 0.0;
280 got_point = false;
281 diverr = false;
282 update_value();
283 }
284
285 void perform_div()
286 {
287 operation = DIVIDE;
288 got_point = false;
289 result = value;
290 begin_new_value = true;
291 }
292
293 void perform_sub()
294 {
295 operation = SUBTRACT;
296 got_point = false;
297 result = value;
298 begin_new_value = true;
299 }
300
301 void perform_mult()
302 {
303 operation = MULTIPLY;
304 got_point = false;
305 result = value;
306 begin_new_value = true;
307 }
308
309 void perform_add()
310 {
311 operation = ADD;
312 got_point = false;
313 result = value;
314 begin_new_value = true;
315 }
316
317 int
318 main(int argc, char** argv)
319 {
320 int i;
321
322 dpy = fbui_display_open ();
323 if (!dpy)
324 FATAL("cannot open display");
325
326 win_w = 200;
327 win_h = 180;
328 win = fbui_window_open (dpy, win_w,win_h, &win_w, &win_h, 9999,9999, 0, -1,
329 &fgcolor,
330 &bgcolor,
331 "fbcalc", VERSION,
332 FBUI_PROGTYPE_EPHEMERAL,
333 false, false,
334 -1,
335 true, // need keys
336 false,
337 false,
338 argc,argv);
339 if (!win)
340 FATAL ("cannot create window");
341
342 font = font_new ();
343
344 if (win_w < 200) {
345 if (!pcf_read (font, "courR10.pcf")) {
346 font_free (font);
347 FATAL ("cannot load font");
348 }
349 } else {
350 if (!pcf_read (font, "courR12.pcf")) {
351 font_free (font);
352 FATAL ("cannot load font");
353 }
354 }
355
356 fbui_set_font (dpy,win,font);
357
358 double tmp1,tmp2;
359 tmp1 = cols + (cols + 1.0)/2.0;
360 tmp2 = 1.0 + rows + (rows + 2.0)/2.0;
361 button_width = win_w / tmp1;
362 button_height = win_h / tmp2;
363
364 got_point = false;
365
366 short current_x = -1, current_y = -1;
367
368 while(1) {
369 char need_draw=0;
370 char full_draw=0;
371
372 Event ev;
373 int err;
374 if (err = fbui_wait_event (dpy, &ev, FBUI_EVENTMASK_ALL ))
375 {
376 if (err != FBUI_ERR_NOEVENT)
377 fbui_print_error (err);
378 continue;
379 }
380
381 Window *win2;
382
383 int num= ev.type;
384
385 win2 = ev.win;
386 if (win2 != win)
387 FATAL ("event's window is not ours");
388
389 if (num == FBUI_EVENT_EXPOSE) {
390 need_draw=1;
391 full_draw=1;
392 } else
393 if (num == FBUI_EVENT_MOTION) {
394 current_x = ev.x;
395 current_y = ev.y;
396 } else
397 if (num == FBUI_EVENT_ENTER) {
398 fbui_draw_rect (dpy, win, 0,0, win_w-1, win_h-1, RGB_RED);
399 fbui_draw_rect (dpy, win, 1,1, win_w-2, win_h-2, RGB_RED);
400 fbui_flush (dpy, win);
401 continue;
402 }
403 else
404 if (num == FBUI_EVENT_LEAVE) {
405 fbui_draw_rect (dpy, win, 0,0, win_w-1, win_h-1, bgcolor);
406 fbui_draw_rect (dpy, win, 1,1, win_w-2, win_h-2, bgcolor);
407 fbui_flush (dpy, win);
408 continue;
409 }
410 else
411 if (num == FBUI_EVENT_MOVE_RESIZE) {
412 win_w = ev.width;
413 win_h = ev.height;
414 need_draw=1;
415 }
416 else
417 if (num == FBUI_EVENT_KEY) {
418 short key = fbui_convert_key (dpy, ev.key);
419 if (!key)
420 continue;
421
422 if (key=='q')
423 break;
424
425 switch (key) {
426 case '.': perform_point(); break;
427 case '/': perform_div(); break;
428 case '=': perform_equals(); break;
429 case '*': perform_mult(); break;
430 case '+': perform_add(); break;
431 case '-': perform_sub(); break;
432 case 'c': perform_clear(); break;
433 case 's': perform_store(); break;
434 case 'r': perform_recall(); break;
435
436 case '0':
437 case '1':
438 case '2':
439 case '3':
440 case '4':
441 case '5':
442 case '6':
443 case '7':
444 case '8':
445 case '9':
446 insert_digit (key);
447 continue;
448 }
449
450 }
451 else
452 if (num == FBUI_EVENT_BUTTON) {
453 if (ev.key & FBUI_BUTTON_LEFT) {
454 if (ev.key & 1) {
455 int n = whichbutton (current_x, current_y);
456 switch (n) {
457 case 0: perform_store(); break;
458 case 1: perform_recall(); break;
459 case 2: perform_clearall(); break;
460 case 3: perform_clear(); break;
461
462 case 4: perform_ix(); break;
463 case 5: perform_sqrt(); break;
464 case 6: perform_square(); break;
465 case 7: perform_div(); break;
466
467 case 8: insert_digit ('7'); break;
468 case 9: insert_digit ('8'); break;
469 case 10: insert_digit ('9'); break;
470 case 11: perform_mult(); break;
471
472 case 12: insert_digit ('4'); break;
473 case 13: insert_digit ('5'); break;
474 case 14: insert_digit ('6'); break;
475 case 15: perform_sub(); break;
476
477 case 16: insert_digit ('1'); break;
478 case 17: insert_digit ('2'); break;
479 case 18: insert_digit ('3'); break;
480 case 19: perform_add(); break;
481
482 case 20: insert_digit ('0'); break;
483 case 21: perform_point(); break;
484 case 22: perform_neg(); break;
485 case 23: perform_equals (); break;
486
487 }
488 }
489 }
490 }
491
492 if (!need_draw)
493 continue;
494
495 if (need_draw) {
496 update_value ();
497
498 if (full_draw) {
499 int i,j;
500 for (j=0; j<rows; j++)
501 for (i=0; i<cols; i++)
502 draw_button (dpy,win,i,j, false);
503 }
504 }
505
506 fbui_flush (dpy, win);
507 }
508
509 fbui_window_close(dpy, win);
510 fbui_display_close(dpy);
511 return 0;
512 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.