adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2003, Adam Dunkels. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above |
| 11 | * copyright notice, this list of conditions and the following |
| 12 | * disclaimer in the documentation and/or other materials provided |
| 13 | * with the distribution. |
adamdunkels | 06f897e | 2004-06-06 05:59:20 +0000 | [diff] [blame] | 14 | * 3. The name of the author may not be used to endorse or promote |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 15 | * products derived from this software without specific prior |
| 16 | * written permission. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
| 19 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| 24 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | * |
| 30 | * This an example program for the Contiki desktop OS |
| 31 | * |
oliverschmidt | 10f4b8d | 2005-02-07 23:13:00 +0000 | [diff] [blame] | 32 | * $Id: calc.c,v 1.8 2005/02/07 23:13:00 oliverschmidt Exp $ |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 33 | * |
| 34 | */ |
| 35 | |
| 36 | /* This is an example of how to write programs for Contiki. It |
| 37 | displays a window with the famous message "Hello world" and two |
| 38 | buttons; one which changes the message slightly and one which quits |
| 39 | the application. */ |
| 40 | |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 41 | #include "ek.h" |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 42 | #include "ctk.h" |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 43 | #include "loader.h" |
| 44 | |
| 45 | static struct ctk_window window; |
| 46 | |
| 47 | static char input[16]; |
| 48 | static struct ctk_label inputlabel = |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 49 | {CTK_LABEL(0, 0, 12, 1, input)}; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 50 | |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 51 | static struct ctk_button button7 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 52 | {CTK_BUTTON(0, 3, 1, "7")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 53 | static struct ctk_button button8 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 54 | {CTK_BUTTON(3, 3, 1, "8")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 55 | static struct ctk_button button9 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 56 | {CTK_BUTTON(6, 3, 1, "9")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 57 | static struct ctk_button button4 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 58 | {CTK_BUTTON(0, 4, 1, "4")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 59 | static struct ctk_button button5 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 60 | {CTK_BUTTON(3, 4, 1, "5")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 61 | static struct ctk_button button6 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 62 | {CTK_BUTTON(6, 4, 1, "6")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 63 | static struct ctk_button button1 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 64 | {CTK_BUTTON(0, 5, 1, "1")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 65 | static struct ctk_button button2 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 66 | {CTK_BUTTON(3, 5, 1, "2")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 67 | static struct ctk_button button3 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 68 | {CTK_BUTTON(6, 5, 1, "3")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 69 | static struct ctk_button button0 = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 70 | {CTK_BUTTON(0, 6, 3, " 0 ")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 71 | |
| 72 | static struct ctk_button cbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 73 | {CTK_BUTTON(0, 2, 1, "C")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 74 | |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 75 | static struct ctk_button divbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 76 | {CTK_BUTTON(9, 2, 1, "/")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 77 | static struct ctk_button mulbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 78 | {CTK_BUTTON(9, 3, 1, "*")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 79 | |
| 80 | static struct ctk_button subbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 81 | {CTK_BUTTON(9, 4, 1, "-")}; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 82 | static struct ctk_button addbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 83 | {CTK_BUTTON(9, 5, 1, "+")}; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 84 | static struct ctk_button calcbutton = |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 85 | {CTK_BUTTON(9, 6, 1, "=")}; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 86 | |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 87 | EK_EVENTHANDLER(calc_eventhandler, ev, data); |
| 88 | EK_PROCESS(p, "Calculator", EK_PRIO_NORMAL, |
| 89 | calc_eventhandler, NULL, NULL); |
| 90 | static ek_id_t id = EK_ID_NONE; |
| 91 | |
| 92 | /* |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 93 | static DISPATCHER_SIGHANDLER(calc_sighandler, s, data); |
| 94 | static struct dispatcher_proc p = |
adamdunkels | c97a60b | 2003-04-11 20:12:34 +0000 | [diff] [blame] | 95 | {DISPATCHER_PROC("Calculator", NULL, calc_sighandler, NULL)}; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 96 | static ek_id_t id; |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 97 | */ |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 98 | |
adamdunkels | f180e34 | 2003-08-20 20:51:31 +0000 | [diff] [blame] | 99 | static unsigned long operand1, operand2; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 100 | static unsigned char op; |
| 101 | #define OP_ADD 1 |
| 102 | #define OP_SUB 2 |
| 103 | #define OP_MUL 3 |
| 104 | #define OP_DIV 4 |
| 105 | |
| 106 | /*-----------------------------------------------------------------------------------*/ |
adamdunkels | 8bb5cca | 2003-08-24 22:41:31 +0000 | [diff] [blame] | 107 | LOADER_INIT_FUNC(calc_init, arg) |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 108 | { |
adamdunkels | 8bb5cca | 2003-08-24 22:41:31 +0000 | [diff] [blame] | 109 | arg_free(arg); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 110 | |
| 111 | if(id == EK_ID_NONE) { |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 112 | id = ek_start(&p); |
| 113 | } |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 114 | } |
| 115 | /*-----------------------------------------------------------------------------------*/ |
| 116 | static void |
| 117 | calc_quit(void) |
| 118 | { |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 119 | ek_exit(); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 120 | id = EK_ID_NONE; |
| 121 | LOADER_UNLOAD(); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 122 | } |
| 123 | /*-----------------------------------------------------------------------------------*/ |
| 124 | static void |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 125 | add_to_input(char c) |
| 126 | { |
| 127 | unsigned char i; |
| 128 | |
| 129 | for(i = 0; i < 11; ++i) { |
| 130 | input[i] = input[i + 1]; |
| 131 | } |
| 132 | input[11] = c; |
| 133 | } |
| 134 | /*-----------------------------------------------------------------------------------*/ |
| 135 | static void |
| 136 | clear_input(void) |
| 137 | { |
| 138 | unsigned char i; |
| 139 | |
| 140 | for(i = 0; i < sizeof(input); ++i) { |
| 141 | input[i] = ' '; |
| 142 | } |
| 143 | } |
| 144 | /*-----------------------------------------------------------------------------------*/ |
| 145 | static void |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 146 | input_to_operand1(void) |
| 147 | { |
| 148 | unsigned int m; |
| 149 | unsigned char i; |
| 150 | |
| 151 | operand1 = 0; |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 152 | for(m = 1, i = 11; |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 153 | i > 7; --i, m *= 10) { |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 154 | if(input[i] >= '0' && |
| 155 | input[i] <= '9') { |
| 156 | operand1 += (input[i] - '0') * m; |
| 157 | } |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 158 | } |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 159 | clear_input(); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 160 | } |
| 161 | /*-----------------------------------------------------------------------------------*/ |
| 162 | static void |
| 163 | operand2_to_input(void) |
| 164 | { |
| 165 | unsigned char i; |
| 166 | |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 167 | input[7] = (operand2/10000) % 10 + '0'; |
| 168 | input[8] = (operand2/1000) % 10 + '0'; |
| 169 | input[9] = (operand2/100) % 10 + '0'; |
| 170 | input[10] = (operand2/10) % 10 + '0'; |
| 171 | input[11] = operand2 % 10 + '0'; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 172 | |
| 173 | for(i = 0; i < 4; ++i) { |
adamdunkels | 4e441cb | 2003-04-24 17:19:23 +0000 | [diff] [blame] | 174 | if(input[7 + i] == '0') { |
| 175 | input[7 + i] = ' '; |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 176 | } else { |
| 177 | break; |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | /*-----------------------------------------------------------------------------------*/ |
| 182 | static void |
| 183 | calculate(void) |
| 184 | { |
| 185 | operand2 = operand1; |
| 186 | input_to_operand1(); |
| 187 | switch(op) { |
| 188 | case OP_ADD: |
| 189 | operand2 = operand2 + operand1; |
| 190 | break; |
| 191 | case OP_SUB: |
| 192 | operand2 = operand2 - operand1; |
| 193 | break; |
| 194 | case OP_MUL: |
| 195 | operand2 = operand2 * operand1; |
| 196 | break; |
| 197 | case OP_DIV: |
| 198 | operand2 = operand2 / operand1; |
| 199 | break; |
| 200 | } |
| 201 | operand2_to_input(); |
| 202 | } |
| 203 | /*-----------------------------------------------------------------------------------*/ |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 204 | EK_EVENTHANDLER(calc_eventhandler, ev, data) |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 205 | { |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 206 | EK_EVENTHANDLER_ARGS(ev, data); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 207 | |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 208 | if(ev == EK_EVENT_INIT) { |
| 209 | ctk_window_new(&window, 12, 7, "Calc"); |
| 210 | |
| 211 | CTK_WIDGET_ADD(&window, &inputlabel); |
| 212 | CTK_WIDGET_SET_FLAG(&inputlabel, CTK_WIDGET_FLAG_MONOSPACE); |
| 213 | |
| 214 | CTK_WIDGET_ADD(&window, &cbutton); |
| 215 | |
| 216 | CTK_WIDGET_ADD(&window, &divbutton); |
| 217 | |
| 218 | CTK_WIDGET_ADD(&window, &button7); |
| 219 | CTK_WIDGET_ADD(&window, &button8); |
| 220 | CTK_WIDGET_ADD(&window, &button9); |
| 221 | |
| 222 | CTK_WIDGET_ADD(&window, &mulbutton); |
| 223 | |
| 224 | |
| 225 | |
| 226 | CTK_WIDGET_ADD(&window, &button4); |
| 227 | CTK_WIDGET_ADD(&window, &button5); |
| 228 | CTK_WIDGET_ADD(&window, &button6); |
| 229 | |
| 230 | CTK_WIDGET_ADD(&window, &subbutton); |
| 231 | |
| 232 | CTK_WIDGET_ADD(&window, &button1); |
| 233 | CTK_WIDGET_ADD(&window, &button2); |
| 234 | CTK_WIDGET_ADD(&window, &button3); |
| 235 | |
| 236 | CTK_WIDGET_ADD(&window, &addbutton); |
| 237 | |
| 238 | CTK_WIDGET_ADD(&window, &button0); |
| 239 | |
| 240 | CTK_WIDGET_ADD(&window, &calcbutton); |
| 241 | |
| 242 | clear_input(); |
| 243 | |
| 244 | ctk_window_open(&window); |
| 245 | |
| 246 | } else if(ev == ctk_signal_keypress) { |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 247 | if((char)data >= '0' && |
| 248 | (char)data <= '9') { |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 249 | add_to_input((char)data); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 250 | } else if((char)data == ' ') { |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 251 | clear_input(); |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 252 | } else if((char)data == '+') { |
| 253 | input_to_operand1(); |
| 254 | op = OP_ADD; |
| 255 | } else if((char)data == '-') { |
| 256 | input_to_operand1(); |
| 257 | op = OP_SUB; |
| 258 | } else if((char)data == '*') { |
| 259 | input_to_operand1(); |
| 260 | op = OP_MUL; |
| 261 | } else if((char)data == '/') { |
| 262 | input_to_operand1(); |
| 263 | op = OP_DIV; |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 264 | } else if((char)data == '=' || |
| 265 | (char)data == CH_ENTER) { |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 266 | calculate(); |
| 267 | } |
| 268 | |
| 269 | CTK_WIDGET_REDRAW(&inputlabel); |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 270 | } else if(ev == ctk_signal_button_activate) { |
| 271 | if(data == (ek_data_t)&button0) { |
| 272 | add_to_input('0'); |
| 273 | } else if(data == (ek_data_t)&button1) { |
| 274 | add_to_input('1'); |
| 275 | } else if(data == (ek_data_t)&button2) { |
| 276 | add_to_input('2'); |
| 277 | } else if(data == (ek_data_t)&button3) { |
| 278 | add_to_input('3'); |
| 279 | } else if(data == (ek_data_t)&button4) { |
| 280 | add_to_input('4'); |
| 281 | } else if(data == (ek_data_t)&button5) { |
| 282 | add_to_input('5'); |
| 283 | } else if(data == (ek_data_t)&button6) { |
| 284 | add_to_input('6'); |
| 285 | } else if(data == (ek_data_t)&button7) { |
| 286 | add_to_input('7'); |
| 287 | } else if(data == (ek_data_t)&button8) { |
| 288 | add_to_input('8'); |
| 289 | } else if(data == (ek_data_t)&button9) { |
| 290 | add_to_input('9'); |
| 291 | } else if(data == (ek_data_t)&cbutton) { |
| 292 | clear_input(); |
| 293 | } else if(data == (ek_data_t)&calcbutton) { |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 294 | calculate(); |
| 295 | } else if(data == (ek_data_t)&addbutton) { |
| 296 | input_to_operand1(); |
| 297 | op = OP_ADD; |
| 298 | } else if(data == (ek_data_t)&subbutton) { |
| 299 | input_to_operand1(); |
| 300 | op = OP_SUB; |
| 301 | } else if(data == (ek_data_t)&mulbutton) { |
| 302 | input_to_operand1(); |
| 303 | op = OP_MUL; |
| 304 | } else if(data == (ek_data_t)&divbutton) { |
| 305 | input_to_operand1(); |
| 306 | op = OP_DIV; |
| 307 | } |
| 308 | CTK_WIDGET_REDRAW(&inputlabel); |
adamdunkels | 04d2e37 | 2004-07-04 11:27:07 +0000 | [diff] [blame] | 309 | } else if(ev == ctk_signal_window_close && |
adamdunkels | eb0df01 | 2003-04-09 19:16:49 +0000 | [diff] [blame] | 310 | data == (ek_data_t)&window) { |
| 311 | calc_quit(); |
| 312 | } |
| 313 | } |
| 314 | /*-----------------------------------------------------------------------------------*/ |