Contiki 3.x
calc.c
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.
14  * 3. The name of the author may not be used to endorse or promote
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  *
32  *
33  */
34 
35 #include <stddef.h>
36 
37 #include "contiki.h"
38 #include "ctk/ctk.h"
39 
40 static struct ctk_window window;
41 
42 static char input[16];
43 static struct ctk_label inputlabel =
44  {CTK_LABEL(0, 0, 12, 1, input)};
45 
46 static struct ctk_button button7 =
47  {CTK_BUTTON(0, 3, 1, "7")};
48 static struct ctk_button button8 =
49  {CTK_BUTTON(3, 3, 1, "8")};
50 static struct ctk_button button9 =
51  {CTK_BUTTON(6, 3, 1, "9")};
52 static struct ctk_button button4 =
53  {CTK_BUTTON(0, 4, 1, "4")};
54 static struct ctk_button button5 =
55  {CTK_BUTTON(3, 4, 1, "5")};
56 static struct ctk_button button6 =
57  {CTK_BUTTON(6, 4, 1, "6")};
58 static struct ctk_button button1 =
59  {CTK_BUTTON(0, 5, 1, "1")};
60 static struct ctk_button button2 =
61  {CTK_BUTTON(3, 5, 1, "2")};
62 static struct ctk_button button3 =
63  {CTK_BUTTON(6, 5, 1, "3")};
64 static struct ctk_button button0 =
65  {CTK_BUTTON(0, 6, 3, " 0 ")};
66 
67 static struct ctk_button cbutton =
68  {CTK_BUTTON(0, 2, 1, "C")};
69 
70 static struct ctk_button divbutton =
71  {CTK_BUTTON(9, 2, 1, "/")};
72 static struct ctk_button mulbutton =
73  {CTK_BUTTON(9, 3, 1, "*")};
74 
75 static struct ctk_button subbutton =
76  {CTK_BUTTON(9, 4, 1, "-")};
77 static struct ctk_button addbutton =
78  {CTK_BUTTON(9, 5, 1, "+")};
79 static struct ctk_button calcbutton =
80  {CTK_BUTTON(9, 6, 1, "=")};
81 
82 PROCESS(calc_process, "Calculator");
83 
84 AUTOSTART_PROCESSES(&calc_process);
85 
86 static unsigned long operand1, operand2;
87 static unsigned char op;
88 #define OP_ADD 1
89 #define OP_SUB 2
90 #define OP_MUL 3
91 #define OP_DIV 4
92 
93 /*-----------------------------------------------------------------------------------*/
94 static void
95 calc_quit(void)
96 {
97  process_exit(&calc_process);
98  LOADER_UNLOAD();
99 }
100 /*-----------------------------------------------------------------------------------*/
101 static void
102 add_to_input(char c)
103 {
104  unsigned char i;
105 
106  for(i = 0; i < 11; ++i) {
107  input[i] = input[i + 1];
108  }
109  input[11] = c;
110 }
111 /*-----------------------------------------------------------------------------------*/
112 static void
113 clear_input(void)
114 {
115  unsigned char i;
116 
117  for(i = 0; i < sizeof(input); ++i) {
118  input[i] = ' ';
119  }
120 }
121 /*-----------------------------------------------------------------------------------*/
122 static void
123 input_to_operand1(void)
124 {
125  unsigned int m;
126  unsigned char i;
127 
128  operand1 = 0;
129  for(m = 1, i = 11;
130  i > 7; --i, m *= 10) {
131  if(input[i] >= '0' &&
132  input[i] <= '9') {
133  operand1 += (input[i] - '0') * m;
134  }
135  }
136  clear_input();
137 }
138 /*-----------------------------------------------------------------------------------*/
139 static void
140 operand2_to_input(void)
141 {
142  unsigned char i;
143 
144  input[7] = (char)((operand2/10000) % 10) + '0';
145  input[8] = (char)((operand2/1000) % 10) + '0';
146  input[9] = (char)((operand2/100) % 10) + '0';
147  input[10] = (char)((operand2/10) % 10) + '0';
148  input[11] = (char)(operand2 % 10) + '0';
149 
150  for(i = 0; i < 4; ++i) {
151  if(input[7 + i] == '0') {
152  input[7 + i] = ' ';
153  } else {
154  break;
155  }
156  }
157 }
158 /*-----------------------------------------------------------------------------------*/
159 static void
160 calculate(void)
161 {
162  operand2 = operand1;
163  input_to_operand1();
164  switch(op) {
165  case OP_ADD:
166  operand2 = operand2 + operand1;
167  break;
168  case OP_SUB:
169  operand2 = operand2 - operand1;
170  break;
171  case OP_MUL:
172  operand2 = operand2 * operand1;
173  break;
174  case OP_DIV:
175  operand2 = operand2 / operand1;
176  break;
177  }
178  operand2_to_input();
179 }
180 /*-----------------------------------------------------------------------------------*/
181 PROCESS_THREAD(calc_process, ev, data)
182 {
183  PROCESS_BEGIN();
184 
185  ctk_window_new(&window, 12, 7, "Calc");
186 
187  CTK_WIDGET_ADD(&window, &inputlabel);
188  CTK_WIDGET_SET_FLAG(&inputlabel, CTK_WIDGET_FLAG_MONOSPACE);
189 
190  CTK_WIDGET_ADD(&window, &cbutton);
191 
192  CTK_WIDGET_ADD(&window, &divbutton);
193 
194  CTK_WIDGET_ADD(&window, &button7);
195  CTK_WIDGET_ADD(&window, &button8);
196  CTK_WIDGET_ADD(&window, &button9);
197 
198  CTK_WIDGET_ADD(&window, &mulbutton);
199 
200 
201 
202  CTK_WIDGET_ADD(&window, &button4);
203  CTK_WIDGET_ADD(&window, &button5);
204  CTK_WIDGET_ADD(&window, &button6);
205 
206  CTK_WIDGET_ADD(&window, &subbutton);
207 
208  CTK_WIDGET_ADD(&window, &button1);
209  CTK_WIDGET_ADD(&window, &button2);
210  CTK_WIDGET_ADD(&window, &button3);
211 
212  CTK_WIDGET_ADD(&window, &addbutton);
213 
214  CTK_WIDGET_ADD(&window, &button0);
215 
216  CTK_WIDGET_ADD(&window, &calcbutton);
217 
218  clear_input();
219 
220  ctk_window_open(&window);
221 
222  while(1) {
223 
225 
226  if(ev == ctk_signal_keypress) {
227  if((char)(size_t)data >= '0' &&
228  (char)(size_t)data <= '9') {
229  add_to_input((char)(size_t)data);
230  } else if((char)(size_t)data == ' ') {
231  clear_input();
232  } else if((char)(size_t)data == '+') {
233  input_to_operand1();
234  op = OP_ADD;
235  } else if((char)(size_t)data == '-') {
236  input_to_operand1();
237  op = OP_SUB;
238  } else if((char)(size_t)data == '*') {
239  input_to_operand1();
240  op = OP_MUL;
241  } else if((char)(size_t)data == '/') {
242  input_to_operand1();
243  op = OP_DIV;
244  } else if((char)(size_t)data == '=' ||
245  (char)(size_t)data == CH_ENTER) {
246  calculate();
247  }
248 
249  CTK_WIDGET_REDRAW(&inputlabel);
250  } else if(ev == ctk_signal_button_activate) {
251  if(data == (process_data_t)&button0) {
252  add_to_input('0');
253  } else if(data == (process_data_t)&button1) {
254  add_to_input('1');
255  } else if(data == (process_data_t)&button2) {
256  add_to_input('2');
257  } else if(data == (process_data_t)&button3) {
258  add_to_input('3');
259  } else if(data == (process_data_t)&button4) {
260  add_to_input('4');
261  } else if(data == (process_data_t)&button5) {
262  add_to_input('5');
263  } else if(data == (process_data_t)&button6) {
264  add_to_input('6');
265  } else if(data == (process_data_t)&button7) {
266  add_to_input('7');
267  } else if(data == (process_data_t)&button8) {
268  add_to_input('8');
269  } else if(data == (process_data_t)&button9) {
270  add_to_input('9');
271  } else if(data == (process_data_t)&cbutton) {
272  clear_input();
273  } else if(data == (process_data_t)&calcbutton) {
274  calculate();
275  } else if(data == (process_data_t)&addbutton) {
276  input_to_operand1();
277  op = OP_ADD;
278  } else if(data == (process_data_t)&subbutton) {
279  input_to_operand1();
280  op = OP_SUB;
281  } else if(data == (process_data_t)&mulbutton) {
282  input_to_operand1();
283  op = OP_MUL;
284  } else if(data == (process_data_t)&divbutton) {
285  input_to_operand1();
286  op = OP_DIV;
287  }
288  CTK_WIDGET_REDRAW(&inputlabel);
289  } else if(ev == ctk_signal_window_close &&
290  data == (process_data_t)&window) {
291  calc_quit();
292  }
293  }
294  PROCESS_END();
295 }
296 /*-----------------------------------------------------------------------------------*/
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
Definition: ctk.h:752
process_event_t ctk_signal_window_close
Emitted when a window is closed.
Definition: ctk.c:155
process_event_t ctk_signal_button_activate
Same as ctk_signal_widget_activate.
Definition: ctk.c:126
void ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
Open a window, or bring window to front if already open.
Definition: ctk.c:347
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
Definition: ctk.h:171
process_event_t ctk_signal_keypress
Emitted for every key being pressed.
Definition: ctk.c:126
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void ctk_window_new(struct ctk_window *window, unsigned char w, unsigned char h, char *title)
Create a new window.
Definition: ctk.c:732
#define LOADER_UNLOAD()
Unload a program from memory.
Definition: loader.h:104
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define CTK_BUTTON(x, y, w, text)
Instantiating macro for the ctk_button widget.
Definition: ctk.h:140
Representation of a CTK window.
Definition: ctk.h:506
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
Definition: ctk.h:771
CTK header file.
void process_exit(struct process *p)
Cause a process to exit.
Definition: process.c:202