source: mainline/uspace/app/calculator/calculator.c@ bfb055b

Last change on this file since bfb055b was cd74fa8, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Downsize more controls to make calculator look better

  • Property mode set to 100644
File size: 18.5 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * Copyright (c) 2016 Martin Decky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup calculator
31 * @{
32 */
33/** @file
34 *
35 * Inspired by the code released at https://github.com/osgroup/HelenOSProject
36 *
37 */
38
39#include <ctype.h>
40#include <io/kbd_event.h>
41#include <stdbool.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <str.h>
45#include <ui/entry.h>
46#include <ui/fixed.h>
47#include <ui/pbutton.h>
48#include <ui/ui.h>
49#include <ui/window.h>
50
51#define NAME "calculator"
52
53#define NULL_DISPLAY "0"
54
55#define SYNTAX_ERROR_DISPLAY "Syntax error"
56#define NUMERIC_ERROR_DISPLAY "Numerical error"
57#define UNKNOWN_ERROR_DISPLAY "Unknown error"
58
59#define EXPR_MAX_LEN 22
60
61typedef enum {
62 STATE_INITIAL = 0,
63 STATE_FINISH,
64 STATE_ERROR,
65 STATE_DIGIT,
66 STATE_VALUE
67} parser_state_t;
68
69typedef enum {
70 ERROR_SYNTAX = 0,
71 ERROR_NUMERIC
72} error_type_t;
73
74typedef enum {
75 OPERATOR_NONE = 0,
76 OPERATOR_ADD,
77 OPERATOR_SUB,
78 OPERATOR_MUL,
79 OPERATOR_DIV
80} operator_t;
81
82typedef enum {
83 ITEM_VALUE = 0,
84 ITEM_OPERATOR
85} stack_item_type_t;
86
87typedef struct {
88 link_t link;
89
90 stack_item_type_t type;
91 union {
92 int64_t value;
93 operator_t operator;
94 } data;
95} stack_item_t;
96
97/** Dimensions. Most of this should not be needed with auto layout */
98typedef struct {
99 gfx_rect_t entry_rect;
100 gfx_coord2_t btn_orig;
101 gfx_coord2_t btn_stride;
102 gfx_coord2_t btn_dim;
103} calc_geom_t;
104
105typedef struct {
106 ui_t *ui;
107 ui_resource_t *ui_res;
108 ui_pbutton_t *btn_eval;
109 ui_pbutton_t *btn_clear;
110 ui_pbutton_t *btn_add;
111 ui_pbutton_t *btn_sub;
112 ui_pbutton_t *btn_mul;
113 ui_pbutton_t *btn_div;
114 ui_pbutton_t *btn_0;
115 ui_pbutton_t *btn_1;
116 ui_pbutton_t *btn_2;
117 ui_pbutton_t *btn_3;
118 ui_pbutton_t *btn_4;
119 ui_pbutton_t *btn_5;
120 ui_pbutton_t *btn_6;
121 ui_pbutton_t *btn_7;
122 ui_pbutton_t *btn_8;
123 ui_pbutton_t *btn_9;
124 calc_geom_t geom;
125} calc_t;
126
127static void calc_pb_clicked(ui_pbutton_t *, void *);
128static void calc_eval_clicked(ui_pbutton_t *, void *);
129static void calc_clear_clicked(ui_pbutton_t *, void *);
130
131static ui_pbutton_cb_t calc_pbutton_cb = {
132 .clicked = calc_pb_clicked
133};
134
135static ui_pbutton_cb_t calc_clear_cb = {
136 .clicked = calc_clear_clicked
137};
138
139static ui_pbutton_cb_t calc_eval_cb = {
140 .clicked = calc_eval_clicked
141};
142
143static void wnd_close(ui_window_t *, void *);
144static void wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
145
146static ui_window_cb_t window_cb = {
147 .close = wnd_close,
148 .kbd = wnd_kbd_event
149};
150
151/** Window close request
152 *
153 * @param window Window
154 * @param arg Argument (calc_t *)
155 */
156static void wnd_close(ui_window_t *window, void *arg)
157{
158 calc_t *calc = (calc_t *) arg;
159
160 ui_quit(calc->ui);
161}
162
163/** Window keyboard event
164 *
165 * @param window Window
166 * @param arg Argument (calc_t *)
167 * @param event Keyboard event
168 */
169static void wnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
170{
171 calc_t *calc = (calc_t *) arg;
172
173 switch (event->key) {
174 case KC_ENTER:
175 if (event->type == KEY_PRESS)
176 ui_pbutton_press(calc->btn_eval);
177 else
178 ui_pbutton_release(calc->btn_eval);
179 break;
180 case KC_BACKSPACE:
181 if (event->type == KEY_PRESS)
182 ui_pbutton_press(calc->btn_clear);
183 else
184 ui_pbutton_release(calc->btn_clear);
185 break;
186 case KC_MINUS:
187 if (event->type == KEY_PRESS)
188 ui_pbutton_press(calc->btn_sub);
189 else
190 ui_pbutton_release(calc->btn_sub);
191 break;
192 case KC_EQUALS:
193 if (event->type == KEY_PRESS)
194 ui_pbutton_press(calc->btn_add);
195 else
196 ui_pbutton_release(calc->btn_add);
197 break;
198 case KC_SLASH:
199 if (event->type == KEY_PRESS)
200 ui_pbutton_press(calc->btn_div);
201 else
202 ui_pbutton_release(calc->btn_div);
203 break;
204 case KC_0:
205 if (event->type == KEY_PRESS)
206 ui_pbutton_press(calc->btn_0);
207 else
208 ui_pbutton_release(calc->btn_0);
209 break;
210 case KC_1:
211 if (event->type == KEY_PRESS)
212 ui_pbutton_press(calc->btn_1);
213 else
214 ui_pbutton_release(calc->btn_1);
215 break;
216 case KC_2:
217 if (event->type == KEY_PRESS)
218 ui_pbutton_press(calc->btn_2);
219 else
220 ui_pbutton_release(calc->btn_2);
221 break;
222 case KC_3:
223 if (event->type == KEY_PRESS)
224 ui_pbutton_press(calc->btn_3);
225 else
226 ui_pbutton_release(calc->btn_3);
227 break;
228 case KC_4:
229 if (event->type == KEY_PRESS)
230 ui_pbutton_press(calc->btn_4);
231 else
232 ui_pbutton_release(calc->btn_4);
233 break;
234 case KC_5:
235 if (event->type == KEY_PRESS)
236 ui_pbutton_press(calc->btn_5);
237 else
238 ui_pbutton_release(calc->btn_5);
239 break;
240 case KC_6:
241 if (event->type == KEY_PRESS)
242 ui_pbutton_press(calc->btn_6);
243 else
244 ui_pbutton_release(calc->btn_6);
245 break;
246 case KC_7:
247 if (event->type == KEY_PRESS)
248 ui_pbutton_press(calc->btn_7);
249 else
250 ui_pbutton_release(calc->btn_7);
251 break;
252 case KC_8:
253 if ((event->mods & KM_SHIFT) != 0) {
254 if (event->type == KEY_PRESS)
255 ui_pbutton_press(calc->btn_mul);
256 else
257 ui_pbutton_release(calc->btn_mul);
258 } else {
259 if (event->type == KEY_PRESS)
260 ui_pbutton_press(calc->btn_8);
261 else
262 ui_pbutton_release(calc->btn_8);
263 }
264 break;
265 case KC_9:
266 if (event->type == KEY_PRESS)
267 ui_pbutton_press(calc->btn_9);
268 else
269 ui_pbutton_release(calc->btn_9);
270 break;
271 default:
272 break;
273 }
274}
275
276static char *expr = NULL;
277static ui_entry_t *display;
278
279static bool is_digit(char c)
280{
281 return ((c >= '0') && (c <= '9'));
282}
283
284static int get_digit(char c)
285{
286 assert(is_digit(c));
287
288 return (c - '0');
289}
290
291static bool is_plus(char c)
292{
293 return (c == '+');
294}
295
296static bool is_minus(char c)
297{
298 return (c == '-');
299}
300
301static bool is_finish(char c)
302{
303 return (c == 0);
304}
305
306static operator_t get_operator(char c)
307{
308 switch (c) {
309 case '+':
310 return OPERATOR_ADD;
311 case '-':
312 return OPERATOR_SUB;
313 case '*':
314 return OPERATOR_MUL;
315 case '/':
316 return OPERATOR_DIV;
317 default:
318 return OPERATOR_NONE;
319 }
320}
321
322static bool is_operator(char c)
323{
324 return (get_operator(c) != OPERATOR_NONE);
325}
326
327static bool stack_push_value(list_t *stack, int64_t value, bool value_neg)
328{
329 stack_item_t *item = malloc(sizeof(stack_item_t));
330 if (!item)
331 return false;
332
333 link_initialize(&item->link);
334 item->type = ITEM_VALUE;
335
336 if (value_neg)
337 item->data.value = -value;
338 else
339 item->data.value = value;
340
341 list_prepend(&item->link, stack);
342
343 return true;
344}
345
346static bool stack_push_operator(list_t *stack, operator_t operator)
347{
348 stack_item_t *item = malloc(sizeof(stack_item_t));
349 if (!item)
350 return false;
351
352 link_initialize(&item->link);
353 item->type = ITEM_OPERATOR;
354 item->data.operator = operator;
355 list_prepend(&item->link, stack);
356
357 return true;
358}
359
360static bool stack_pop_value(list_t *stack, int64_t *value)
361{
362 link_t *link = list_first(stack);
363 if (!link)
364 return false;
365
366 stack_item_t *item = list_get_instance(link, stack_item_t, link);
367 if (item->type != ITEM_VALUE)
368 return false;
369
370 *value = item->data.value;
371
372 list_remove(link);
373 free(item);
374
375 return true;
376}
377
378static bool stack_pop_operator(list_t *stack, operator_t *operator)
379{
380 link_t *link = list_first(stack);
381 if (!link)
382 return false;
383
384 stack_item_t *item = list_get_instance(link, stack_item_t, link);
385 if (item->type != ITEM_OPERATOR)
386 return false;
387
388 *operator = item->data.operator;
389
390 list_remove(link);
391 free(item);
392
393 return true;
394}
395
396static void stack_cleanup(list_t *stack)
397{
398 while (!list_empty(stack)) {
399 link_t *link = list_first(stack);
400 if (link) {
401 stack_item_t *item = list_get_instance(link, stack_item_t,
402 link);
403
404 list_remove(link);
405 free(item);
406 }
407 }
408}
409
410static bool compute(int64_t a, operator_t operator, int64_t b, int64_t *value)
411{
412 switch (operator) {
413 case OPERATOR_ADD:
414 *value = a + b;
415 break;
416 case OPERATOR_SUB:
417 *value = a - b;
418 break;
419 case OPERATOR_MUL:
420 *value = a * b;
421 break;
422 case OPERATOR_DIV:
423 if (b == 0)
424 return false;
425
426 *value = a / b;
427 break;
428 default:
429 return false;
430 }
431
432 return true;
433}
434
435static unsigned int get_priority(operator_t operator)
436{
437 switch (operator) {
438 case OPERATOR_ADD:
439 return 0;
440 case OPERATOR_SUB:
441 return 0;
442 case OPERATOR_MUL:
443 return 1;
444 case OPERATOR_DIV:
445 return 1;
446 default:
447 return 0;
448 }
449}
450
451static void evaluate(list_t *stack, int64_t *value, parser_state_t *state,
452 error_type_t *error_type)
453{
454 while (!list_empty(stack)) {
455 if (!stack_pop_value(stack, value)) {
456 *state = STATE_ERROR;
457 *error_type = ERROR_SYNTAX;
458 break;
459 }
460
461 if (!list_empty(stack)) {
462 operator_t operator;
463 if (!stack_pop_operator(stack, &operator)) {
464 *state = STATE_ERROR;
465 *error_type = ERROR_SYNTAX;
466 break;
467 }
468
469 int64_t value_a;
470 if (!stack_pop_value(stack, &value_a)) {
471 *state = STATE_ERROR;
472 *error_type = ERROR_SYNTAX;
473 break;
474 }
475
476 if (!compute(value_a, operator, *value, value)) {
477 *state = STATE_ERROR;
478 *error_type = ERROR_NUMERIC;
479 break;
480 }
481
482 if (!stack_push_value(stack, *value, false)) {
483 *state = STATE_ERROR;
484 *error_type = ERROR_SYNTAX;
485 break;
486 }
487 }
488 }
489}
490
491static void display_update(void)
492{
493 if (expr != NULL)
494 (void) ui_entry_set_text(display, (void *) expr);
495 else
496 (void) ui_entry_set_text(display, (void *) NULL_DISPLAY);
497
498 ui_entry_paint(display);
499}
500
501static void display_error(error_type_t error_type)
502{
503 if (expr != NULL) {
504 free(expr);
505 expr = NULL;
506 }
507
508 switch (error_type) {
509 case ERROR_SYNTAX:
510 (void) ui_entry_set_text(display,
511 (void *) SYNTAX_ERROR_DISPLAY);
512 break;
513 case ERROR_NUMERIC:
514 (void) ui_entry_set_text(display,
515 (void *) NUMERIC_ERROR_DISPLAY);
516 break;
517 default:
518 (void) ui_entry_set_text(display,
519 (void *) UNKNOWN_ERROR_DISPLAY);
520 break;
521 }
522
523 ui_entry_paint(display);
524}
525
526static void calc_pb_clicked(ui_pbutton_t *pbutton, void *arg)
527{
528 const char *subexpr = (const char *) arg;
529
530 if (expr != NULL) {
531 char *new_expr;
532
533 if (str_length(expr) < EXPR_MAX_LEN) {
534 asprintf(&new_expr, "%s%s", expr, subexpr);
535 free(expr);
536 expr = new_expr;
537 }
538 } else {
539 expr = str_dup(subexpr);
540 }
541
542 display_update();
543}
544
545static void calc_clear_clicked(ui_pbutton_t *pbutton, void *arg)
546{
547 if (expr != NULL) {
548 free(expr);
549 expr = NULL;
550 }
551
552 display_update();
553}
554
555static void calc_eval_clicked(ui_pbutton_t *pbutton, void *arg)
556{
557 if (expr == NULL)
558 return;
559
560 list_t stack;
561 list_initialize(&stack);
562
563 error_type_t error_type = ERROR_SYNTAX;
564 size_t i = 0;
565 parser_state_t state = STATE_INITIAL;
566 int64_t value = 0;
567 bool value_neg = false;
568 operator_t last_operator = OPERATOR_NONE;
569
570 while ((state != STATE_FINISH) && (state != STATE_ERROR)) {
571 switch (state) {
572 case STATE_INITIAL:
573 if (is_digit(expr[i])) {
574 value = get_digit(expr[i]);
575 i++;
576 state = STATE_VALUE;
577 } else if (is_plus(expr[i])) {
578 i++;
579 value_neg = false;
580 state = STATE_DIGIT;
581 } else if (is_minus(expr[i])) {
582 i++;
583 value_neg = true;
584 state = STATE_DIGIT;
585 } else
586 state = STATE_ERROR;
587 break;
588
589 case STATE_DIGIT:
590 if (is_digit(expr[i])) {
591 value = get_digit(expr[i]);
592 i++;
593 state = STATE_VALUE;
594 } else
595 state = STATE_ERROR;
596 break;
597
598 case STATE_VALUE:
599 if (is_digit(expr[i])) {
600 value *= 10;
601 value += get_digit(expr[i]);
602 i++;
603 } else if (is_operator(expr[i])) {
604 if (!stack_push_value(&stack, value, value_neg)) {
605 state = STATE_ERROR;
606 break;
607 }
608
609 value = 0;
610 value_neg = false;
611
612 operator_t operator = get_operator(expr[i]);
613
614 if (get_priority(operator) <= get_priority(last_operator)) {
615 evaluate(&stack, &value, &state, &error_type);
616 if (state == STATE_ERROR)
617 break;
618
619 if (!stack_push_value(&stack, value, value_neg)) {
620 state = STATE_ERROR;
621 break;
622 }
623 }
624
625 if (!stack_push_operator(&stack, operator)) {
626 state = STATE_ERROR;
627 break;
628 }
629
630 last_operator = operator;
631 i++;
632 state = STATE_DIGIT;
633 } else if (is_finish(expr[i])) {
634 if (!stack_push_value(&stack, value, value_neg)) {
635 state = STATE_ERROR;
636 break;
637 }
638
639 state = STATE_FINISH;
640 } else
641 state = STATE_ERROR;
642 break;
643
644 default:
645 state = STATE_ERROR;
646 }
647 }
648
649 evaluate(&stack, &value, &state, &error_type);
650 stack_cleanup(&stack);
651
652 if (state == STATE_ERROR) {
653 display_error(error_type);
654 return;
655 }
656
657 free(expr);
658 asprintf(&expr, "%" PRId64, value);
659 display_update();
660}
661
662static errno_t calc_button_create(calc_t *calc, ui_fixed_t *fixed,
663 int x, int y, const char *text, ui_pbutton_cb_t *cb, void *arg,
664 ui_pbutton_t **rbutton)
665{
666 ui_pbutton_t *pb;
667 gfx_rect_t rect;
668 errno_t rc;
669
670 rc = ui_pbutton_create(calc->ui_res, text, &pb);
671 if (rc != EOK) {
672 printf("Error creating button.\n");
673 return rc;
674 }
675
676 ui_pbutton_set_cb(pb, cb, arg);
677
678 rect.p0.x = calc->geom.btn_orig.x + calc->geom.btn_stride.x * x;
679 rect.p0.y = calc->geom.btn_orig.y + calc->geom.btn_stride.y * y;
680 rect.p1.x = rect.p0.x + calc->geom.btn_dim.x;
681 rect.p1.y = rect.p0.y + calc->geom.btn_dim.y;
682 ui_pbutton_set_rect(pb, &rect);
683
684 rc = ui_fixed_add(fixed, ui_pbutton_ctl(pb));
685 if (rc != EOK) {
686 printf("Error adding control to layout.\n");
687 return rc;
688 }
689
690 if (rbutton != NULL)
691 *rbutton = pb;
692 return EOK;
693}
694
695static void print_syntax(void)
696{
697 printf("Syntax: %s [-d <display-spec>]\n", NAME);
698}
699
700int main(int argc, char *argv[])
701{
702 const char *display_spec = UI_DISPLAY_DEFAULT;
703 ui_t *ui;
704 ui_resource_t *ui_res;
705 ui_fixed_t *fixed;
706 ui_wnd_params_t params;
707 ui_window_t *window;
708 calc_t calc;
709 errno_t rc;
710 int i;
711
712 i = 1;
713 while (i < argc) {
714 if (str_cmp(argv[i], "-d") == 0) {
715 ++i;
716 if (i >= argc) {
717 printf("Argument missing.\n");
718 print_syntax();
719 return 1;
720 }
721
722 display_spec = argv[i++];
723 } else {
724 printf("Invalid option '%s'.\n", argv[i]);
725 print_syntax();
726 return 1;
727 }
728 }
729
730 rc = ui_create(display_spec, &ui);
731 if (rc != EOK) {
732 printf("Error creating UI on display %s.\n", display_spec);
733 return rc;
734 }
735
736 ui_wnd_params_init(&params);
737 params.caption = "Calculator";
738 params.rect.p0.x = 0;
739 params.rect.p0.y = 0;
740
741 if (ui_is_textmode(ui)) {
742 params.rect.p1.x = 38;
743 params.rect.p1.y = 18;
744
745 calc.geom.entry_rect.p0.x = 4;
746 calc.geom.entry_rect.p0.y = 3;
747 calc.geom.entry_rect.p1.x = 34;
748 calc.geom.entry_rect.p1.y = 4;
749 calc.geom.btn_orig.x = 4;
750 calc.geom.btn_orig.y = 5;
751 calc.geom.btn_dim.x = 6;
752 calc.geom.btn_dim.y = 2;
753 calc.geom.btn_stride.x = 8;
754 calc.geom.btn_stride.y = 3;
755 } else {
756 params.rect.p1.x = 250;
757 params.rect.p1.y = 270;
758
759 calc.geom.entry_rect.p0.x = 15;
760 calc.geom.entry_rect.p0.y = 45;
761 calc.geom.entry_rect.p1.x = 235;
762 calc.geom.entry_rect.p1.y = 70;
763 calc.geom.btn_orig.x = 10;
764 calc.geom.btn_orig.y = 90;
765 calc.geom.btn_dim.x = 50;
766 calc.geom.btn_dim.y = 35;
767 calc.geom.btn_stride.x = 60;
768 calc.geom.btn_stride.y = 45;
769 }
770
771 rc = ui_window_create(ui, &params, &window);
772 if (rc != EOK) {
773 printf("Error creating window.\n");
774 return rc;
775 }
776
777 ui_window_set_cb(window, &window_cb, (void *) &calc);
778 calc.ui = ui;
779
780 ui_res = ui_window_get_res(window);
781 calc.ui_res = ui_res;
782
783 rc = ui_fixed_create(&fixed);
784 if (rc != EOK) {
785 printf("Error creating fixed layout.\n");
786 return rc;
787 }
788
789 rc = ui_entry_create(ui_res, NULL_DISPLAY, &display);
790 if (rc != EOK) {
791 printf("Error creating text lentry.\n");
792 return rc;
793 }
794
795 ui_entry_set_rect(display, &calc.geom.entry_rect);
796 ui_entry_set_halign(display, gfx_halign_right);
797
798 rc = ui_fixed_add(fixed, ui_entry_ctl(display));
799 if (rc != EOK) {
800 printf("Error adding control to layout.\n");
801 return rc;
802 }
803
804 rc = calc_button_create(&calc, fixed, 0, 0, "7", &calc_pbutton_cb,
805 (void *) "7", &calc.btn_7);
806 if (rc != EOK)
807 return rc;
808
809 rc = calc_button_create(&calc, fixed, 1, 0, "8", &calc_pbutton_cb,
810 (void *) "8", &calc.btn_8);
811 if (rc != EOK)
812 return rc;
813
814 rc = calc_button_create(&calc, fixed, 2, 0, "9", &calc_pbutton_cb,
815 (void *) "9", &calc.btn_9);
816 if (rc != EOK)
817 return rc;
818
819 rc = calc_button_create(&calc, fixed, 3, 0, "/", &calc_pbutton_cb,
820 (void *) "/", &calc.btn_div);
821 if (rc != EOK)
822 return rc;
823
824 rc = calc_button_create(&calc, fixed, 0, 1, "4", &calc_pbutton_cb,
825 (void *) "4", &calc.btn_4);
826 if (rc != EOK)
827 return rc;
828
829 rc = calc_button_create(&calc, fixed, 1, 1, "5", &calc_pbutton_cb,
830 (void *) "5", &calc.btn_5);
831 if (rc != EOK)
832 return rc;
833
834 rc = calc_button_create(&calc, fixed, 2, 1, "6", &calc_pbutton_cb,
835 (void *) "6", &calc.btn_6);
836 if (rc != EOK)
837 return rc;
838
839 rc = calc_button_create(&calc, fixed, 3, 1, "*", &calc_pbutton_cb,
840 (void *) "*", &calc.btn_mul);
841 if (rc != EOK)
842 return rc;
843
844 rc = calc_button_create(&calc, fixed, 0, 2, "1", &calc_pbutton_cb,
845 (void *) "1", &calc.btn_1);
846 if (rc != EOK)
847 return rc;
848
849 rc = calc_button_create(&calc, fixed, 1, 2, "2", &calc_pbutton_cb,
850 (void *) "2", &calc.btn_2);
851 if (rc != EOK)
852 return rc;
853
854 rc = calc_button_create(&calc, fixed, 2, 2, "3", &calc_pbutton_cb,
855 (void *) "3", &calc.btn_3);
856 if (rc != EOK)
857 return rc;
858
859 rc = calc_button_create(&calc, fixed, 3, 2, "-", &calc_pbutton_cb,
860 (void *) "-", &calc.btn_sub);
861 if (rc != EOK)
862 return rc;
863
864 rc = calc_button_create(&calc, fixed, 0, 3, "0", &calc_pbutton_cb,
865 (void *) "0", &calc.btn_0);
866 if (rc != EOK)
867 return rc;
868
869 rc = calc_button_create(&calc, fixed, 1, 3, "C", &calc_clear_cb,
870 (void *) "C", &calc.btn_clear);
871 if (rc != EOK)
872 return rc;
873
874 rc = calc_button_create(&calc, fixed, 2, 3, "=", &calc_eval_cb,
875 (void *) "=", &calc.btn_eval);
876 if (rc != EOK)
877 return rc;
878
879 rc = calc_button_create(&calc, fixed, 3, 3, "+", &calc_pbutton_cb,
880 (void *) "+", &calc.btn_add);
881 if (rc != EOK)
882 return rc;
883
884 ui_pbutton_set_default(calc.btn_eval, true);
885
886 ui_window_add(window, ui_fixed_ctl(fixed));
887
888 rc = ui_window_paint(window);
889 if (rc != EOK) {
890 printf("Error painting window.\n");
891 return rc;
892 }
893
894 ui_run(ui);
895 ui_window_destroy(window);
896 ui_destroy(ui);
897
898 return 0;
899}
Note: See TracBrowser for help on using the repository browser.