git.y1.nz

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.