osd-contiki/apps/calc/calc.c

299 lines
8.1 KiB
C

/*
* Copyright (c) 2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This an example program for the Contiki desktop OS
*
* $Id: calc.c,v 1.4 2008/02/07 16:28:27 oliverschmidt Exp $
*
*/
#include <stddef.h>
#include "contiki.h"
#include "ctk/ctk.h"
static struct ctk_window window;
static char input[16];
static struct ctk_label inputlabel =
{CTK_LABEL(0, 0, 12, 1, input)};
static struct ctk_button button7 =
{CTK_BUTTON(0, 3, 1, "7")};
static struct ctk_button button8 =
{CTK_BUTTON(3, 3, 1, "8")};
static struct ctk_button button9 =
{CTK_BUTTON(6, 3, 1, "9")};
static struct ctk_button button4 =
{CTK_BUTTON(0, 4, 1, "4")};
static struct ctk_button button5 =
{CTK_BUTTON(3, 4, 1, "5")};
static struct ctk_button button6 =
{CTK_BUTTON(6, 4, 1, "6")};
static struct ctk_button button1 =
{CTK_BUTTON(0, 5, 1, "1")};
static struct ctk_button button2 =
{CTK_BUTTON(3, 5, 1, "2")};
static struct ctk_button button3 =
{CTK_BUTTON(6, 5, 1, "3")};
static struct ctk_button button0 =
{CTK_BUTTON(0, 6, 3, " 0 ")};
static struct ctk_button cbutton =
{CTK_BUTTON(0, 2, 1, "C")};
static struct ctk_button divbutton =
{CTK_BUTTON(9, 2, 1, "/")};
static struct ctk_button mulbutton =
{CTK_BUTTON(9, 3, 1, "*")};
static struct ctk_button subbutton =
{CTK_BUTTON(9, 4, 1, "-")};
static struct ctk_button addbutton =
{CTK_BUTTON(9, 5, 1, "+")};
static struct ctk_button calcbutton =
{CTK_BUTTON(9, 6, 1, "=")};
PROCESS(calc_process, "Calculator");
#if SELFSTART_PROCESS
AUTOSTART_PROCESSES(&calc_process);
#endif /* SELFSTART_PROCESS */
static unsigned long operand1, operand2;
static unsigned char op;
#define OP_ADD 1
#define OP_SUB 2
#define OP_MUL 3
#define OP_DIV 4
/*-----------------------------------------------------------------------------------*/
static void
calc_quit(void)
{
process_exit(&calc_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
add_to_input(char c)
{
unsigned char i;
for(i = 0; i < 11; ++i) {
input[i] = input[i + 1];
}
input[11] = c;
}
/*-----------------------------------------------------------------------------------*/
static void
clear_input(void)
{
unsigned char i;
for(i = 0; i < sizeof(input); ++i) {
input[i] = ' ';
}
}
/*-----------------------------------------------------------------------------------*/
static void
input_to_operand1(void)
{
unsigned int m;
unsigned char i;
operand1 = 0;
for(m = 1, i = 11;
i > 7; --i, m *= 10) {
if(input[i] >= '0' &&
input[i] <= '9') {
operand1 += (input[i] - '0') * m;
}
}
clear_input();
}
/*-----------------------------------------------------------------------------------*/
static void
operand2_to_input(void)
{
unsigned char i;
input[7] = (char)((operand2/10000) % 10) + '0';
input[8] = (char)((operand2/1000) % 10) + '0';
input[9] = (char)((operand2/100) % 10) + '0';
input[10] = (char)((operand2/10) % 10) + '0';
input[11] = (char)(operand2 % 10) + '0';
for(i = 0; i < 4; ++i) {
if(input[7 + i] == '0') {
input[7 + i] = ' ';
} else {
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
calculate(void)
{
operand2 = operand1;
input_to_operand1();
switch(op) {
case OP_ADD:
operand2 = operand2 + operand1;
break;
case OP_SUB:
operand2 = operand2 - operand1;
break;
case OP_MUL:
operand2 = operand2 * operand1;
break;
case OP_DIV:
operand2 = operand2 / operand1;
break;
}
operand2_to_input();
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(calc_process, ev, data)
{
PROCESS_BEGIN();
ctk_window_new(&window, 12, 7, "Calc");
CTK_WIDGET_ADD(&window, &inputlabel);
CTK_WIDGET_SET_FLAG(&inputlabel, CTK_WIDGET_FLAG_MONOSPACE);
CTK_WIDGET_ADD(&window, &cbutton);
CTK_WIDGET_ADD(&window, &divbutton);
CTK_WIDGET_ADD(&window, &button7);
CTK_WIDGET_ADD(&window, &button8);
CTK_WIDGET_ADD(&window, &button9);
CTK_WIDGET_ADD(&window, &mulbutton);
CTK_WIDGET_ADD(&window, &button4);
CTK_WIDGET_ADD(&window, &button5);
CTK_WIDGET_ADD(&window, &button6);
CTK_WIDGET_ADD(&window, &subbutton);
CTK_WIDGET_ADD(&window, &button1);
CTK_WIDGET_ADD(&window, &button2);
CTK_WIDGET_ADD(&window, &button3);
CTK_WIDGET_ADD(&window, &addbutton);
CTK_WIDGET_ADD(&window, &button0);
CTK_WIDGET_ADD(&window, &calcbutton);
clear_input();
ctk_window_open(&window);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_keypress) {
if((char)(size_t)data >= '0' &&
(char)(size_t)data <= '9') {
add_to_input((char)(size_t)data);
} else if((char)(size_t)data == ' ') {
clear_input();
} else if((char)(size_t)data == '+') {
input_to_operand1();
op = OP_ADD;
} else if((char)(size_t)data == '-') {
input_to_operand1();
op = OP_SUB;
} else if((char)(size_t)data == '*') {
input_to_operand1();
op = OP_MUL;
} else if((char)(size_t)data == '/') {
input_to_operand1();
op = OP_DIV;
} else if((char)(size_t)data == '=' ||
(char)(size_t)data == CH_ENTER) {
calculate();
}
CTK_WIDGET_REDRAW(&inputlabel);
} else if(ev == ctk_signal_button_activate) {
if(data == (process_data_t)&button0) {
add_to_input('0');
} else if(data == (process_data_t)&button1) {
add_to_input('1');
} else if(data == (process_data_t)&button2) {
add_to_input('2');
} else if(data == (process_data_t)&button3) {
add_to_input('3');
} else if(data == (process_data_t)&button4) {
add_to_input('4');
} else if(data == (process_data_t)&button5) {
add_to_input('5');
} else if(data == (process_data_t)&button6) {
add_to_input('6');
} else if(data == (process_data_t)&button7) {
add_to_input('7');
} else if(data == (process_data_t)&button8) {
add_to_input('8');
} else if(data == (process_data_t)&button9) {
add_to_input('9');
} else if(data == (process_data_t)&cbutton) {
clear_input();
} else if(data == (process_data_t)&calcbutton) {
calculate();
} else if(data == (process_data_t)&addbutton) {
input_to_operand1();
op = OP_ADD;
} else if(data == (process_data_t)&subbutton) {
input_to_operand1();
op = OP_SUB;
} else if(data == (process_data_t)&mulbutton) {
input_to_operand1();
op = OP_MUL;
} else if(data == (process_data_t)&divbutton) {
input_to_operand1();
op = OP_DIV;
}
CTK_WIDGET_REDRAW(&inputlabel);
} else if(ev == ctk_signal_window_close &&
data == (process_data_t)&window) {
calc_quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/