mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-11-19 03:05:14 +00:00
86cb1769f6
It was added to avoid getting garbage keyboard input in some cases, however it seems not to happen very often and might be the cause of hang in OSX. If garbage input happens again we can always try to pump a single event each time instead of looping anyway.
491 lines
11 KiB
C
491 lines
11 KiB
C
/*
|
|
* 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 <revol@free.fr>
|
|
*/
|
|
|
|
#include <curses.h>
|
|
#include <signal.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <term.h>
|
|
#include <unistd.h>
|
|
|
|
#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)
|
|
{
|
|
mmask_t oldmask;
|
|
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();
|
|
|
|
/* don't echo typed characters */
|
|
noecho();
|
|
/*nonl(); */
|
|
|
|
/* hide text cursor, CTK draws its own */
|
|
curs_set(0);
|
|
|
|
intrflush(stdscr, FALSE);
|
|
keypad(stdscr, TRUE);
|
|
|
|
/* done here because ctk_mouse_init() is called before anyway */
|
|
mousemask(ALL_MOUSE_EVENTS, &oldmask);
|
|
|
|
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);
|
|
}
|
|
|
|
/* set window title */
|
|
putp("\033]0;Contiki\a");
|
|
|
|
/* don't block on read, just timeout 1ms */
|
|
timeout(1);
|
|
|
|
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);
|
|
(void)y;
|
|
return (unsigned char)x;
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
unsigned char
|
|
wherey(void)
|
|
{
|
|
int x, y;
|
|
|
|
getyx(stdscr, y, x);
|
|
(void)x;
|
|
return (unsigned char)y;
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
void
|
|
clrscr(void)
|
|
{
|
|
clear();
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
void
|
|
bgcolor(unsigned char c)
|
|
{
|
|
color = ((c << 4) | (color & 0xF0));
|
|
|
|
/* 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_MOUSE:
|
|
{
|
|
MEVENT event;
|
|
|
|
if(getmouse(&event) == OK) {
|
|
xpos = event.x;
|
|
ypos = event.y;
|
|
button = event.bstate & BUTTON1_PRESSED
|
|
|| event.bstate & BUTTON1_CLICKED
|
|
|| event.bstate & BUTTON1_DOUBLE_CLICKED;
|
|
/*fprintf(stderr, "mevent: %d: %d, %d, %d, %lx ; %d\n",
|
|
event.id, event.x, event.y, event.z, event.bstate, button); */
|
|
}
|
|
return;
|
|
}
|
|
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(9): /* Gnome uses F10 as menu trigger now... */
|
|
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)
|
|
{
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|