source: mainline/uspace/app/calculator/calculator.c@ 38f5598

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 38f5598 was d942ca4, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Calculator should respond to keyboard control

  • Property mode set to 100644
File size: 17.5 KB
Line 
1/*
2 * Copyright (c) 2020 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
97typedef struct {
98 ui_t *ui;
99 ui_pbutton_t *btn_eval;
100 ui_pbutton_t *btn_clear;
101 ui_pbutton_t *btn_add;
102 ui_pbutton_t *btn_sub;
103 ui_pbutton_t *btn_mul;
104 ui_pbutton_t *btn_div;
105 ui_pbutton_t *btn_0;
106 ui_pbutton_t *btn_1;
107 ui_pbutton_t *btn_2;
108 ui_pbutton_t *btn_3;
109 ui_pbutton_t *btn_4;
110 ui_pbutton_t *btn_5;
111 ui_pbutton_t *btn_6;
112 ui_pbutton_t *btn_7;
113 ui_pbutton_t *btn_8;
114 ui_pbutton_t *btn_9;
115} calc_t;
116
117static void calc_pb_clicked(ui_pbutton_t *, void *);
118static void calc_eval_clicked(ui_pbutton_t *, void *);
119static void calc_clear_clicked(ui_pbutton_t *, void *);
120
121static ui_pbutton_cb_t calc_pbutton_cb = {
122 .clicked = calc_pb_clicked
123};
124
125static ui_pbutton_cb_t calc_clear_cb = {
126 .clicked = calc_clear_clicked
127};
128
129static ui_pbutton_cb_t calc_eval_cb = {
130 .clicked = calc_eval_clicked
131};
132
133static void wnd_close(ui_window_t *, void *);
134static void wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
135
136static ui_window_cb_t window_cb = {
137 .close = wnd_close,
138 .kbd = wnd_kbd_event
139};
140
141/** Window close request
142 *
143 * @param window Window
144 * @param arg Argument (calc_t *)
145 */
146static void wnd_close(ui_window_t *window, void *arg)
147{
148 calc_t *calc = (calc_t *) arg;
149
150 ui_quit(calc->ui);
151}
152
153/** Window keyboard event
154 *
155 * @param window Window
156 * @param arg Argument (calc_t *)
157 * @param event Keyboard event
158 */
159static void wnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
160{
161 calc_t *calc = (calc_t *) arg;
162
163 switch (event->key) {
164 case KC_ENTER:
165 if (event->type == KEY_PRESS)
166 ui_pbutton_press(calc->btn_eval);
167 else
168 ui_pbutton_release(calc->btn_eval);
169 break;
170 case KC_BACKSPACE:
171 if (event->type == KEY_PRESS)
172 ui_pbutton_press(calc->btn_clear);
173 else
174 ui_pbutton_release(calc->btn_clear);
175 break;
176 case KC_MINUS:
177 if (event->type == KEY_PRESS)
178 ui_pbutton_press(calc->btn_sub);
179 else
180 ui_pbutton_release(calc->btn_sub);
181 break;
182 case KC_EQUALS:
183 if (event->type == KEY_PRESS)
184 ui_pbutton_press(calc->btn_add);
185 else
186 ui_pbutton_release(calc->btn_add);
187 break;
188 case KC_SLASH:
189 if (event->type == KEY_PRESS)
190 ui_pbutton_press(calc->btn_div);
191 else
192 ui_pbutton_release(calc->btn_div);
193 break;
194 case KC_0:
195 if (event->type == KEY_PRESS)
196 ui_pbutton_press(calc->btn_0);
197 else
198 ui_pbutton_release(calc->btn_0);
199 break;
200 case KC_1:
201 if (event->type == KEY_PRESS)
202 ui_pbutton_press(calc->btn_1);
203 else
204 ui_pbutton_release(calc->btn_1);
205 break;
206 case KC_2:
207 if (event->type == KEY_PRESS)
208 ui_pbutton_press(calc->btn_2);
209 else
210 ui_pbutton_release(calc->btn_2);
211 break;
212 case KC_3:
213 if (event->type == KEY_PRESS)
214 ui_pbutton_press(calc->btn_3);
215 else
216 ui_pbutton_release(calc->btn_3);
217 break;
218 case KC_4:
219 if (event->type == KEY_PRESS)
220 ui_pbutton_press(calc->btn_4);
221 else
222 ui_pbutton_release(calc->btn_4);
223 break;
224 case KC_5:
225 if (event->type == KEY_PRESS)
226 ui_pbutton_press(calc->btn_5);
227 else
228 ui_pbutton_release(calc->btn_5);
229 break;
230 case KC_6:
231 if (event->type == KEY_PRESS)
232 ui_pbutton_press(calc->btn_6);
233 else
234 ui_pbutton_release(calc->btn_6);
235 break;
236 case KC_7:
237 if (event->type == KEY_PRESS)
238 ui_pbutton_press(calc->btn_7);
239 else
240 ui_pbutton_release(calc->btn_7);
241 break;
242 case KC_8:
243 if ((event->mods & KM_SHIFT) != 0) {
244 if (event->type == KEY_PRESS)
245 ui_pbutton_press(calc->btn_mul);
246 else
247 ui_pbutton_release(calc->btn_mul);
248 } else {
249 if (event->type == KEY_PRESS)
250 ui_pbutton_press(calc->btn_8);
251 else
252 ui_pbutton_release(calc->btn_8);
253 }
254 break;
255 case KC_9:
256 if (event->type == KEY_PRESS)
257 ui_pbutton_press(calc->btn_9);
258 else
259 ui_pbutton_release(calc->btn_9);
260 break;
261 default:
262 break;
263 }
264}
265
266static char *expr = NULL;
267static ui_entry_t *display;
268
269static bool is_digit(char c)
270{
271 return ((c >= '0') && (c <= '9'));
272}
273
274static int get_digit(char c)
275{
276 assert(is_digit(c));
277
278 return (c - '0');
279}
280
281static bool is_plus(char c)
282{
283 return (c == '+');
284}
285
286static bool is_minus(char c)
287{
288 return (c == '-');
289}
290
291static bool is_finish(char c)
292{
293 return (c == 0);
294}
295
296static operator_t get_operator(char c)
297{
298 switch (c) {
299 case '+':
300 return OPERATOR_ADD;
301 case '-':
302 return OPERATOR_SUB;
303 case '*':
304 return OPERATOR_MUL;
305 case '/':
306 return OPERATOR_DIV;
307 default:
308 return OPERATOR_NONE;
309 }
310}
311
312static bool is_operator(char c)
313{
314 return (get_operator(c) != OPERATOR_NONE);
315}
316
317static bool stack_push_value(list_t *stack, int64_t value, bool value_neg)
318{
319 stack_item_t *item = malloc(sizeof(stack_item_t));
320 if (!item)
321 return false;
322
323 link_initialize(&item->link);
324 item->type = ITEM_VALUE;
325
326 if (value_neg)
327 item->data.value = -value;
328 else
329 item->data.value = value;
330
331 list_prepend(&item->link, stack);
332
333 return true;
334}
335
336static bool stack_push_operator(list_t *stack, operator_t operator)
337{
338 stack_item_t *item = malloc(sizeof(stack_item_t));
339 if (!item)
340 return false;
341
342 link_initialize(&item->link);
343 item->type = ITEM_OPERATOR;
344 item->data.operator = operator;
345 list_prepend(&item->link, stack);
346
347 return true;
348}
349
350static bool stack_pop_value(list_t *stack, int64_t *value)
351{
352 link_t *link = list_first(stack);
353 if (!link)
354 return false;
355
356 stack_item_t *item = list_get_instance(link, stack_item_t, link);
357 if (item->type != ITEM_VALUE)
358 return false;
359
360 *value = item->data.value;
361
362 list_remove(link);
363 free(item);
364
365 return true;
366}
367
368static bool stack_pop_operator(list_t *stack, operator_t *operator)
369{
370 link_t *link = list_first(stack);
371 if (!link)
372 return false;
373
374 stack_item_t *item = list_get_instance(link, stack_item_t, link);
375 if (item->type != ITEM_OPERATOR)
376 return false;
377
378 *operator = item->data.operator;
379
380 list_remove(link);
381 free(item);
382
383 return true;
384}
385
386static void stack_cleanup(list_t *stack)
387{
388 while (!list_empty(stack)) {
389 link_t *link = list_first(stack);
390 if (link) {
391 stack_item_t *item = list_get_instance(link, stack_item_t,
392 link);
393
394 list_remove(link);
395 free(item);
396 }
397 }
398}
399
400static bool compute(int64_t a, operator_t operator, int64_t b, int64_t *value)
401{
402 switch (operator) {
403 case OPERATOR_ADD:
404 *value = a + b;
405 break;
406 case OPERATOR_SUB:
407 *value = a - b;
408 break;
409 case OPERATOR_MUL:
410 *value = a * b;
411 break;
412 case OPERATOR_DIV:
413 if (b == 0)
414 return false;
415
416 *value = a / b;
417 break;
418 default:
419 return false;
420 }
421
422 return true;
423}
424
425static unsigned int get_priority(operator_t operator)
426{
427 switch (operator) {
428 case OPERATOR_ADD:
429 return 0;
430 case OPERATOR_SUB:
431 return 0;
432 case OPERATOR_MUL:
433 return 1;
434 case OPERATOR_DIV:
435 return 1;
436 default:
437 return 0;
438 }
439}
440
441static void evaluate(list_t *stack, int64_t *value, parser_state_t *state,
442 error_type_t *error_type)
443{
444 while (!list_empty(stack)) {
445 if (!stack_pop_value(stack, value)) {
446 *state = STATE_ERROR;
447 *error_type = ERROR_SYNTAX;
448 break;
449 }
450
451 if (!list_empty(stack)) {
452 operator_t operator;
453 if (!stack_pop_operator(stack, &operator)) {
454 *state = STATE_ERROR;
455 *error_type = ERROR_SYNTAX;
456 break;
457 }
458
459 int64_t value_a;
460 if (!stack_pop_value(stack, &value_a)) {
461 *state = STATE_ERROR;
462 *error_type = ERROR_SYNTAX;
463 break;
464 }
465
466 if (!compute(value_a, operator, *value, value)) {
467 *state = STATE_ERROR;
468 *error_type = ERROR_NUMERIC;
469 break;
470 }
471
472 if (!stack_push_value(stack, *value, false)) {
473 *state = STATE_ERROR;
474 *error_type = ERROR_SYNTAX;
475 break;
476 }
477 }
478 }
479}
480
481static void display_update(void)
482{
483 if (expr != NULL)
484 (void) ui_entry_set_text(display, (void *) expr);
485 else
486 (void) ui_entry_set_text(display, (void *) NULL_DISPLAY);
487
488 ui_entry_paint(display);
489}
490
491static void display_error(error_type_t error_type)
492{
493 if (expr != NULL) {
494 free(expr);
495 expr = NULL;
496 }
497
498 switch (error_type) {
499 case ERROR_SYNTAX:
500 (void) ui_entry_set_text(display,
501 (void *) SYNTAX_ERROR_DISPLAY);
502 break;
503 case ERROR_NUMERIC:
504 (void) ui_entry_set_text(display,
505 (void *) NUMERIC_ERROR_DISPLAY);
506 break;
507 default:
508 (void) ui_entry_set_text(display,
509 (void *) UNKNOWN_ERROR_DISPLAY);
510 break;
511 }
512
513 ui_entry_paint(display);
514}
515
516static void calc_pb_clicked(ui_pbutton_t *pbutton, void *arg)
517{
518 const char *subexpr = (const char *) arg;
519
520 if (expr != NULL) {
521 char *new_expr;
522
523 if (str_length(expr) < EXPR_MAX_LEN) {
524 asprintf(&new_expr, "%s%s", expr, subexpr);
525 free(expr);
526 expr = new_expr;
527 }
528 } else {
529 expr = str_dup(subexpr);
530 }
531
532 display_update();
533}
534
535static void calc_clear_clicked(ui_pbutton_t *pbutton, void *arg)
536{
537 if (expr != NULL) {
538 free(expr);
539 expr = NULL;
540 }
541
542 display_update();
543}
544
545static void calc_eval_clicked(ui_pbutton_t *pbutton, void *arg)
546{
547 if (expr == NULL)
548 return;
549
550 list_t stack;
551 list_initialize(&stack);
552
553 error_type_t error_type = ERROR_SYNTAX;
554 size_t i = 0;
555 parser_state_t state = STATE_INITIAL;
556 int64_t value = 0;
557 bool value_neg = false;
558 operator_t last_operator = OPERATOR_NONE;
559
560 while ((state != STATE_FINISH) && (state != STATE_ERROR)) {
561 switch (state) {
562 case STATE_INITIAL:
563 if (is_digit(expr[i])) {
564 value = get_digit(expr[i]);
565 i++;
566 state = STATE_VALUE;
567 } else if (is_plus(expr[i])) {
568 i++;
569 value_neg = false;
570 state = STATE_DIGIT;
571 } else if (is_minus(expr[i])) {
572 i++;
573 value_neg = true;
574 state = STATE_DIGIT;
575 } else
576 state = STATE_ERROR;
577 break;
578
579 case STATE_DIGIT:
580 if (is_digit(expr[i])) {
581 value = get_digit(expr[i]);
582 i++;
583 state = STATE_VALUE;
584 } else
585 state = STATE_ERROR;
586 break;
587
588 case STATE_VALUE:
589 if (is_digit(expr[i])) {
590 value *= 10;
591 value += get_digit(expr[i]);
592 i++;
593 } else if (is_operator(expr[i])) {
594 if (!stack_push_value(&stack, value, value_neg)) {
595 state = STATE_ERROR;
596 break;
597 }
598
599 value = 0;
600 value_neg = false;
601
602 operator_t operator = get_operator(expr[i]);
603
604 if (get_priority(operator) <= get_priority(last_operator)) {
605 evaluate(&stack, &value, &state, &error_type);
606 if (state == STATE_ERROR)
607 break;
608
609 if (!stack_push_value(&stack, value, value_neg)) {
610 state = STATE_ERROR;
611 break;
612 }
613 }
614
615 if (!stack_push_operator(&stack, operator)) {
616 state = STATE_ERROR;
617 break;
618 }
619
620 last_operator = operator;
621 i++;
622 state = STATE_DIGIT;
623 } else if (is_finish(expr[i])) {
624 if (!stack_push_value(&stack, value, value_neg)) {
625 state = STATE_ERROR;
626 break;
627 }
628
629 state = STATE_FINISH;
630 } else
631 state = STATE_ERROR;
632 break;
633
634 default:
635 state = STATE_ERROR;
636 }
637 }
638
639 evaluate(&stack, &value, &state, &error_type);
640 stack_cleanup(&stack);
641
642 if (state == STATE_ERROR) {
643 display_error(error_type);
644 return;
645 }
646
647 free(expr);
648 asprintf(&expr, "%" PRId64, value);
649 display_update();
650}
651
652static errno_t calc_button_create(ui_resource_t *ui_res, ui_fixed_t *fixed,
653 int x, int y, const char *text, ui_pbutton_cb_t *cb, void *arg,
654 ui_pbutton_t **rbutton)
655{
656 ui_pbutton_t *pb;
657 gfx_rect_t rect;
658 errno_t rc;
659
660 rc = ui_pbutton_create(ui_res, text, &pb);
661 if (rc != EOK) {
662 printf("Error creating button.\n");
663 return rc;
664 }
665
666 ui_pbutton_set_cb(pb, cb, arg);
667
668 rect.p0.x = 10 + 60 * x;
669 rect.p0.y = 90 + 45 * y;
670 rect.p1.x = 60 + 60 * x;
671 rect.p1.y = 125 + 45 * y;
672 ui_pbutton_set_rect(pb, &rect);
673
674 rc = ui_fixed_add(fixed, ui_pbutton_ctl(pb));
675 if (rc != EOK) {
676 printf("Error adding control to layout.\n");
677 return rc;
678 }
679
680 if (rbutton != NULL)
681 *rbutton = pb;
682 return EOK;
683}
684
685static void print_syntax(void)
686{
687 printf("Syntax: %s [-d <display-spec>]\n", NAME);
688}
689
690int main(int argc, char *argv[])
691{
692 const char *display_spec = UI_DISPLAY_DEFAULT;
693 ui_t *ui;
694 ui_resource_t *ui_res;
695 ui_fixed_t *fixed;
696 ui_wnd_params_t params;
697 ui_window_t *window;
698 gfx_rect_t rect;
699 calc_t calc;
700 errno_t rc;
701 int i;
702
703 i = 1;
704 while (i < argc) {
705 if (str_cmp(argv[i], "-d") == 0) {
706 ++i;
707 if (i >= argc) {
708 printf("Argument missing.\n");
709 print_syntax();
710 return 1;
711 }
712
713 display_spec = argv[i++];
714 } else {
715 printf("Invalid option '%s'.\n", argv[i]);
716 print_syntax();
717 return 1;
718 }
719 }
720
721 rc = ui_create(display_spec, &ui);
722 if (rc != EOK) {
723 printf("Error creating UI on display %s.\n", display_spec);
724 return rc;
725 }
726
727 ui_wnd_params_init(&params);
728 params.caption = "Calculator";
729 params.rect.p0.x = 0;
730 params.rect.p0.y = 0;
731 params.rect.p1.x = 250;
732 params.rect.p1.y = 270;
733
734 rc = ui_window_create(ui, &params, &window);
735 if (rc != EOK) {
736 printf("Error creating window.\n");
737 return rc;
738 }
739
740 ui_window_set_cb(window, &window_cb, (void *) &calc);
741 calc.ui = ui;
742
743 ui_res = ui_window_get_res(window);
744
745 rc = ui_fixed_create(&fixed);
746 if (rc != EOK) {
747 printf("Error creating fixed layout.\n");
748 return rc;
749 }
750
751 rc = ui_entry_create(ui_res, NULL_DISPLAY, &display);
752 if (rc != EOK) {
753 printf("Error creating text lentry.\n");
754 return rc;
755 }
756
757 rect.p0.x = 15;
758 rect.p0.y = 45;
759 rect.p1.x = 235;
760 rect.p1.y = 70;
761 ui_entry_set_rect(display, &rect);
762 ui_entry_set_halign(display, gfx_halign_right);
763
764 rc = ui_fixed_add(fixed, ui_entry_ctl(display));
765 if (rc != EOK) {
766 printf("Error adding control to layout.\n");
767 return rc;
768 }
769
770 rc = calc_button_create(ui_res, fixed, 0, 0, "7", &calc_pbutton_cb,
771 (void *) "7", &calc.btn_7);
772 if (rc != EOK)
773 return rc;
774
775 rc = calc_button_create(ui_res, fixed, 1, 0, "8", &calc_pbutton_cb,
776 (void *) "8", &calc.btn_8);
777 if (rc != EOK)
778 return rc;
779
780 rc = calc_button_create(ui_res, fixed, 2, 0, "9", &calc_pbutton_cb,
781 (void *) "9", &calc.btn_9);
782 if (rc != EOK)
783 return rc;
784
785 rc = calc_button_create(ui_res, fixed, 3, 0, "/", &calc_pbutton_cb,
786 (void *) "/", &calc.btn_div);
787 if (rc != EOK)
788 return rc;
789
790 rc = calc_button_create(ui_res, fixed, 0, 1, "4", &calc_pbutton_cb,
791 (void *) "4", &calc.btn_4);
792 if (rc != EOK)
793 return rc;
794
795 rc = calc_button_create(ui_res, fixed, 1, 1, "5", &calc_pbutton_cb,
796 (void *) "5", &calc.btn_5);
797 if (rc != EOK)
798 return rc;
799
800 rc = calc_button_create(ui_res, fixed, 2, 1, "6", &calc_pbutton_cb,
801 (void *) "6", &calc.btn_6);
802 if (rc != EOK)
803 return rc;
804
805 rc = calc_button_create(ui_res, fixed, 3, 1, "*", &calc_pbutton_cb,
806 (void *) "*", &calc.btn_mul);
807 if (rc != EOK)
808 return rc;
809
810 rc = calc_button_create(ui_res, fixed, 0, 2, "1", &calc_pbutton_cb,
811 (void *) "1", &calc.btn_1);
812 if (rc != EOK)
813 return rc;
814
815 rc = calc_button_create(ui_res, fixed, 1, 2, "2", &calc_pbutton_cb,
816 (void *) "2", &calc.btn_2);
817 if (rc != EOK)
818 return rc;
819
820 rc = calc_button_create(ui_res, fixed, 2, 2, "3", &calc_pbutton_cb,
821 (void *) "3", &calc.btn_3);
822 if (rc != EOK)
823 return rc;
824
825 rc = calc_button_create(ui_res, fixed, 3, 2, "-", &calc_pbutton_cb,
826 (void *) "-", &calc.btn_sub);
827 if (rc != EOK)
828 return rc;
829
830 rc = calc_button_create(ui_res, fixed, 0, 3, "0", &calc_pbutton_cb,
831 (void *) "0", &calc.btn_0);
832 if (rc != EOK)
833 return rc;
834
835 rc = calc_button_create(ui_res, fixed, 1, 3, "C", &calc_clear_cb,
836 (void *) "C", &calc.btn_clear);
837 if (rc != EOK)
838 return rc;
839
840 rc = calc_button_create(ui_res, fixed, 2, 3, "=", &calc_eval_cb,
841 (void *) "=", &calc.btn_eval);
842 if (rc != EOK)
843 return rc;
844
845 rc = calc_button_create(ui_res, fixed, 3, 3, "+", &calc_pbutton_cb,
846 (void *) "+", &calc.btn_add);
847 if (rc != EOK)
848 return rc;
849
850 ui_pbutton_set_default(calc.btn_eval, true);
851
852 ui_window_add(window, ui_fixed_ctl(fixed));
853
854 rc = ui_window_paint(window);
855 if (rc != EOK) {
856 printf("Error painting window.\n");
857 return rc;
858 }
859
860 ui_run(ui);
861 ui_window_destroy(window);
862 ui_destroy(ui);
863
864 return 0;
865}
Note: See TracBrowser for help on using the repository browser.