From 25e3f828aa2524d2ed21e16bbed6d770decb18dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 12 Apr 2011 21:45:27 +0200 Subject: [PATCH] Ncurses-based CTK backend for the native platform. --- examples/email/Makefile.native.defines | 1 + examples/irc/Makefile.native.defines | 1 + examples/webbrowser/Makefile.native.defines | 1 + platform/native/Makefile.native | 8 +- platform/native/contiki-conf.h | 64 +++ platform/native/contiki-main.c | 13 + platform/native/ctk/ctk-curses.c | 450 ++++++++++++++++++++ platform/native/ctk/ctk-curses.h | 68 +++ 8 files changed, 604 insertions(+), 2 deletions(-) create mode 100644 examples/email/Makefile.native.defines create mode 100644 examples/irc/Makefile.native.defines create mode 100644 examples/webbrowser/Makefile.native.defines create mode 100644 platform/native/ctk/ctk-curses.c create mode 100644 platform/native/ctk/ctk-curses.h diff --git a/examples/email/Makefile.native.defines b/examples/email/Makefile.native.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/email/Makefile.native.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/irc/Makefile.native.defines b/examples/irc/Makefile.native.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/irc/Makefile.native.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/webbrowser/Makefile.native.defines b/examples/webbrowser/Makefile.native.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/webbrowser/Makefile.native.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/platform/native/Makefile.native b/platform/native/Makefile.native index 60591c6a8..d74485149 100644 --- a/platform/native/Makefile.native +++ b/platform/native/Makefile.native @@ -10,12 +10,12 @@ ifeq ($(UIP_CONF_IPV6),1) CFLAGS += -DWITH_UIP6=1 endif -CONTIKI_TARGET_DIRS = . dev +CONTIKI_TARGET_DIRS = . dev ctk CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c leds.c leds-arch.c \ button-sensor.c pir-sensor.c vib-sensor.c xmem.c \ - sensors.c irq.c cfs-posix.c cfs-posix-dir.c + sensors.c irq.c cfs-posix.c cfs-posix-dir.c ctk-curses.c ifeq ($(HOST_OS),Windows) CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c @@ -30,6 +30,7 @@ CONTIKI_TARGET_SOURCEFILES += tapdev6.c endif endif +CONTIKI_SOURCEFILES += $(CTK) ctk-conio.c CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) .SUFFIXES: @@ -37,3 +38,6 @@ CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) ### Define the CPU directory CONTIKI_CPU=$(CONTIKI)/cpu/native include $(CONTIKI)/cpu/native/Makefile.native + +LDFLAGS += -lncurses + diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index d916350d5..54d338b45 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -165,6 +165,70 @@ typedef unsigned short uip_stats_t; #endif /* UIP_CONF_IPV6 */ +#include +#define ctk_arch_isprint isprint + +#include "ctk/ctk-curses.h" + +#define CH_ULCORNER -10 +#define CH_URCORNER -11 +#define CH_LLCORNER -12 +#define CH_LRCORNER -13 +#define CH_ENTER '\n' +#define CH_DEL '\b' +#define CH_CURS_UP -1 +#define CH_CURS_LEFT -2 +#define CH_CURS_RIGHT -3 +#define CH_CURS_DOWN -4 + +#define CTK_CONF_MENU_KEY -5 /* F10 */ +#define CTK_CONF_WINDOWSWITCH_KEY -6 /* Ctrl-Tab */ +#define CTK_CONF_WIDGETUP_KEY -7 /* Shift-Tab */ +#define CTK_CONF_WIDGETDOWN_KEY '\t' +#define CTK_CONF_WIDGET_FLAGS 0 +#define CTK_CONF_SCREENSAVER 0 + +#ifdef PLATFORM_BUILD +#define CTK_CONF_MOUSE_SUPPORT 1 +#define CTK_CONF_WINDOWS 1 +#define CTK_CONF_WINDOWMOVE 1 +#define CTK_CONF_WINDOWCLOSE 1 +#define CTK_CONF_ICONS 1 +#define CTK_CONF_ICON_BITMAPS 0 +#define CTK_CONF_ICON_TEXTMAPS 1 +#define CTK_CONF_MENUS 1 +#define CTK_CONF_MENUWIDTH 16 +#define CTK_CONF_MAXMENUITEMS 10 +#else /* PLATFORM_BUILD */ +#define CTK_CONF_MOUSE_SUPPORT 1 +#define CTK_CONF_WINDOWS 0 +#define CTK_CONF_WINDOWMOVE 0 +#define CTK_CONF_WINDOWCLOSE 0 +#define CTK_CONF_ICONS 0 +#define CTK_CONF_MENUS 0 +#endif /* PLATFORM_BUILD */ + +/* curses doesn't define this one */ +#define COLOR_GRAY COLOR_CYAN + +#define COLOR_BG COLOR_BLUE + +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK +#define BACKGROUNDCOLOR COLOR_BLACK +#define WINDOWCOLOR_FOCUS COLOR_WHITE | COLOR_BG * 0x10 +#define WINDOWCOLOR COLOR_GRAY | COLOR_BG * 0x10 +#define DIALOGCOLOR COLOR_WHITE | COLOR_BG * 0x10 +#define WIDGETCOLOR_HLINK COLOR_CYAN | COLOR_BG * 0x10 +#define WIDGETCOLOR_FWIN COLOR_WHITE | COLOR_BG * 0x10 +#define WIDGETCOLOR COLOR_GRAY | COLOR_BG * 0x10 +#define WIDGETCOLOR_DIALOG COLOR_WHITE | COLOR_BG * 0x10 +#define WIDGETCOLOR_FOCUS COLOR_YELLOW | COLOR_BG * 0x10 +#define MENUCOLOR COLOR_WHITE | COLOR_BG * 0x10 +#define OPENMENUCOLOR COLOR_WHITE | COLOR_BG * 0x10 +#define ACTIVEMENUITEMCOLOR COLOR_YELLOW | COLOR_BG * 0x10 + + typedef unsigned long clock_time_t; #define CLOCK_CONF_SECOND 1000 diff --git a/platform/native/contiki-main.c b/platform/native/contiki-main.c index a870670cb..73dca7e47 100644 --- a/platform/native/contiki-main.c +++ b/platform/native/contiki-main.c @@ -43,6 +43,9 @@ #include "contiki.h" #include "net/netstack.h" +#include "ctk/ctk.h" +#include "ctk/ctk-curses.h" + #include "dev/serial-line.h" #include "net/uip.h" @@ -188,6 +191,10 @@ main(int argc, char **argv) process_start(&etimer_process, NULL); ctimer_init(); +#if WITH_GUI + process_start(&ctk_process, NULL); +#endif + set_rime_addr(); queuebuf_init(); @@ -263,6 +270,12 @@ main(int argc, char **argv) } etimer_request_poll(); + +#if WITH_GUI + if(console_resize()) { + ctk_restore(); + } +#endif /* WITH_GUI */ } return 0; diff --git a/platform/native/ctk/ctk-curses.c b/platform/native/ctk/ctk-curses.c new file mode 100644 index 000000000..1a91cbc5c --- /dev/null +++ b/platform/native/ctk/ctk-curses.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 file is part of the Contiki operating system. + * + * Author: François Revol + */ + +#include +#include +#include +#include +#include +#include + +#include "contiki.h" +#include "ctk/ctk.h" + +#include "ctk-curses.h" + +/* references: + * http://math.hws.edu/orr/s04/cpsc225/curses.html + */ + +#define MKPAIR(bg, fg) (bg << 3 | fg) + +static int stdinhandle; +static int stdouthandle; + +static unsigned char width; +static unsigned char height; + +static unsigned char color; +static unsigned char reversed; + +static ctk_arch_key_t keys[256]; +static unsigned char keys_in, keys_out; +static unsigned char available; + +static unsigned short xpos; +static unsigned short ypos; +static unsigned char button; + +/*-----------------------------------------------------------------------------------*/ +static void +ctrlhandler(int sig) +{ + exit(EXIT_SUCCESS); +} +/*-----------------------------------------------------------------------------------*/ +void +console_init(void) +{ + static unsigned char done; + if(done) { + return; + } + done = 1; + + stdinhandle = STDIN_FILENO; + stdouthandle = STDOUT_FILENO; + + /* will display an error and exit if the term can't be initialized */ + /*setupterm((char *)0, STDOUT_FILENO, (int *)0);*/ + + initscr(); + start_color(); + cbreak(); + noecho(); + /*nonl();*/ + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); + + screensize(&width, &height); + + /* curses color handling is weird... */ + { + int bg, fg; + for (fg = 0; fg < 8; fg++) + for (bg = 0; bg < 8; bg++) + init_pair(MKPAIR(bg, fg), fg, bg); + } + + putp("\033]0;Contiki\a"); + + timeout(25); + + signal(SIGINT, ctrlhandler); + atexit(console_exit); + +} +/*-----------------------------------------------------------------------------------*/ +void +console_exit(void) +{ + static unsigned char done; + + if(done) { + return; + } + done = 1; + + revers(0); + clrscr(); + gotoxy(0, 0); + + + endwin(); +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +console_resize(void) +{ + unsigned char new_width; + unsigned char new_height; + + screensize(&new_width, &new_height); + + if(new_width != width || + new_height != height) { + width = new_width; + height = new_height; + return 1; + } + + return 0; +} +/*-----------------------------------------------------------------------------------*/ +static void +setcolor(void) +{ + int bg, fg; + int attrs; + fg = (color & 0x0F); + bg = (color & 0xF0) >> 4; + + attrs = COLOR_PAIR(MKPAIR(bg, fg)); + if (reversed) + attrs |= WA_REVERSE; + attrset(attrs); +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherex(void) +{ + int x, y; + getyx(stdscr, y, x); + return (unsigned char)x; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherey(void) +{ + int x, y; + getyx(stdscr, y, x); + return (unsigned char)y; +} +/*-----------------------------------------------------------------------------------*/ +void +clrscr(void) +{ + clear(); +} +/*-----------------------------------------------------------------------------------*/ +void +bgcolor(unsigned char c) +{ + /* Presume this to be one of the first calls. */ + console_init(); +} +/*-----------------------------------------------------------------------------------*/ +void +bordercolor(unsigned char c) +{ + /* Presume this to be one of the first calls. */ + console_init(); +} +/*-----------------------------------------------------------------------------------*/ +void +screensize(unsigned char *x, unsigned char *y) +{ + int mx, my; + getmaxyx(stdscr, my, mx); + *x = (unsigned char)mx; + *y = (unsigned char)my; +} +/*-----------------------------------------------------------------------------------*/ +void +revers(unsigned char c) +{ + reversed = c; + setcolor(); +} +/*-----------------------------------------------------------------------------------*/ +void +console_cputc(char c) +{ + int ch = c; + /* usually ACS_* don't fit in a char */ + switch (c) { + case CH_ULCORNER: + ch = ACS_ULCORNER; + break; + case CH_LLCORNER: + ch = ACS_LLCORNER; + break; + case CH_URCORNER: + ch = ACS_URCORNER; + break; + case CH_LRCORNER: + ch = ACS_LRCORNER; + break; + default: + break; + } + addch(ch); + /*refresh();*/ +} +/*-----------------------------------------------------------------------------------*/ +void +console_cputs(char *str) +{ + addstr(str); + refresh(); +} +/*-----------------------------------------------------------------------------------*/ +void +cclear(unsigned char length) +{ + hline(' ', length); + /*refresh();*/ +} +/*-----------------------------------------------------------------------------------*/ +void +chline(unsigned char length) +{ + hline(ACS_HLINE, length); + refresh(); +} +/*-----------------------------------------------------------------------------------*/ +void +cvline(unsigned char length) +{ + vline(ACS_VLINE, length); +} +/*-----------------------------------------------------------------------------------*/ +void +gotoxy(unsigned char x, unsigned char y) +{ + move(y, x); +} +/*-----------------------------------------------------------------------------------*/ +void +cclearxy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cclear(length); +} +/*-----------------------------------------------------------------------------------*/ +void +chlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + chline(length); +} +/*-----------------------------------------------------------------------------------*/ +void +cvlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cvline(length); +} +/*-----------------------------------------------------------------------------------*/ +void +cputsxy(unsigned char x, unsigned char y, char *str) +{ + gotoxy(x, y); + console_cputs(str); +} +/*-----------------------------------------------------------------------------------*/ +void +cputcxy(unsigned char x, unsigned char y, char c) +{ + gotoxy(x, y); + console_cputc(c); +} +/*-----------------------------------------------------------------------------------*/ +void +textcolor(unsigned char c) +{ + color = c; + setcolor(); +} +/*-----------------------------------------------------------------------------------*/ +static void +console_readkey(int k) +{ + ctk_arch_key_t key; + + key = (ctk_arch_key_t)k; + /*fprintf(stderr, "key: %d\n", k);*/ + switch (k) { + case KEY_LEFT: + key = CH_CURS_LEFT; + break; + case KEY_UP: + key = CH_CURS_UP; + break; + case KEY_RIGHT: + key = CH_CURS_RIGHT; + break; + case KEY_DOWN: + key = CH_CURS_DOWN; + break; + case KEY_F(10): + key = CTK_CONF_MENU_KEY; + break; + case KEY_ENTER: + key = CH_ENTER; + break; + case 127: + case KEY_BACKSPACE: + case KEY_DC: + key = CH_DEL; + break; + case KEY_BTAB: + case KEY_CTAB: + case KEY_PPAGE: + case KEY_PREVIOUS: + key = CTK_CONF_WIDGETUP_KEY; + break; + case KEY_NPAGE: + case KEY_NEXT: + key = CTK_CONF_WIDGETDOWN_KEY; + break; + case KEY_STAB: + case KEY_HOME: + case KEY_END: + key = CTK_CONF_WINDOWSWITCH_KEY; + break; + default: + break; + } + if(key == 0) { + return; + } + + memset(keys + keys_in, key, sizeof(ctk_arch_key_t)); + keys_in++; + available++; +} +/*-----------------------------------------------------------------------------------*/ +static void +console_read(void) +{ + int k; + k = getch(); + if (k != ERR) + console_readkey(k); +} +/*-----------------------------------------------------------------------------------*/ +char +ctk_arch_getkey(void) +{ + console_read(); + char k = keys[keys_out++]; + available--; + return k; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_arch_keyavail(void) +{ + console_read(); + return available; +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_init(void) +{ +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_x(void) +{ + console_read(); + return xpos; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_y(void) +{ + console_read(); + return ypos; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_xtoc(unsigned short x) +{ + return x; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_ytoc(unsigned short y) +{ + return y; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_button(void) +{ + console_read(); + return button; +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_hide(void) +{ +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_show(void) +{ +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/native/ctk/ctk-curses.h b/platform/native/ctk/ctk-curses.h new file mode 100644 index 000000000..2661f7f47 --- /dev/null +++ b/platform/native/ctk/ctk-curses.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 file is part of the Contiki operating system. + * + * Author: François Revol + */ +#ifndef __CTK_CONSOLE_H__ +#define __CTK_CONSOLE_H__ + +#include + +#define cputc console_cputc +#define cputs console_cputs + +void console_init(void); +void console_exit(void); +unsigned char console_resize(void); + +unsigned char wherex(void); +unsigned char wherey(void); +void clrscr(void); +void bgcolor(unsigned char c); +void bordercolor(unsigned char c); +void screensize(unsigned char *x, unsigned char *y); +void revers(unsigned char c); +void console_cputc(char c); +void console_cputs(char *str); +void cclear(unsigned char length); +void chline(unsigned char length); +void cvline(unsigned char length); +void gotoxy(unsigned char x, unsigned char y); +void cclearxy(unsigned char x, unsigned char y, unsigned char length); +void chlinexy(unsigned char x, unsigned char y, unsigned char length); +void cvlinexy(unsigned char x, unsigned char y, unsigned char length); +void cputsxy(unsigned char x, unsigned char y, char *str); +void cputcxy(unsigned char x, unsigned char y, char c); +void textcolor(unsigned char c); + +char ctk_arch_getkey(void); +unsigned char ctk_arch_keyavail(void); + +#endif /* __CTK_CONSOLE_H__ */