Files
FreeJ/lib/slw/slw_console.cpp
Luca Bigliardi fc3e839fff SLangWidget: do not use jutils
Remove jutils.h references from slw.
Calling 'src' from 'lib' is nonsense.

Signed-off-by: Luca Bigliardi <shammash@artha.org>
2009-09-02 04:44:06 +01:00

287 lines
7.1 KiB
C++

/* S-Lang console functions in C++
*
* (C) Copyright 2004-2006 Denis Rojo <jaromil@dyne.org>
*
* This source code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <slang.h>
#include <slw_console.h>
///////////////////////////////////
// dirty signals
static bool screen_size_changed;
static void sigwinch_handler (int sig) {
screen_size_changed = true;
SLsignal (SIGWINCH, sigwinch_handler);
}
static bool keyboard_quit;
static void sigint_handler (int sig) {
SLsignal_intr (SIGINT, sigint_handler);
keyboard_quit = true;
#if SLANG_VERSION < 20000
if (SLang_Ignore_User_Abort == 0)
SLang_Error = USER_BREAK;
#endif
}
/* non blocking getkey */
static int getkey_handler() {
unsigned int ch = 0;
if(SLang_input_pending(1))
// return SLang_getkey();
ch = SLang_getkey();
if(ch) func("getkey_handler detected char %u",ch);
return ch;
}
// end of dirty signals
/////////////////////////////////////
SLangConsole::SLangConsole() {
w = h = 0;
focused = NULL;
}
SLangConsole::~SLangConsole() { close(); }
bool SLangConsole::init() {
setenv("TERM","xterm-color",0);
SLtt_get_terminfo();
if( -1 == SLkp_init() ) { // keyboard interface
fprintf(stderr, "failure in SLkp_init()");
return false;
}
SLang_init_tty(-1, 0, 0);
SLsmg_init_smg(); // screen manager
// SLutf8_enable(1); // enable UTF8 character set
// this is a mess ...
screen_size_changed = false;
// register signals
SLsignal (SIGWINCH, sigwinch_handler);
SLang_set_abort_signal(sigint_handler);
SLkp_set_getkey_function(getkey_handler);
// SLsmg_Tab_Width = 8;
// SLsmg_Display_Eight_Bit = 1;
// SLtt_Use_Ansi_Colors = 0;
// SLtt_Term_Cannot_Scroll = 0;
// set sizes of the whole console
w = SLtt_Screen_Cols;
h = SLtt_Screen_Rows;
/* setup colors with the palette scheme:
n = normal;
n+10 = highlight;
n+20 = reverse normal;
n+30 = reverse highlight; */
// crazy casting for crazy slang
SLtt_set_color(1,NULL,(char *)"lightgray",(char *)"black");
SLtt_set_color(11,NULL,(char *)"white",(char *)"black");
SLtt_set_color(21,NULL,(char *)"black",(char *)"lightgray");
SLtt_set_color(31,NULL,(char *)"black",(char *)"white");
SLtt_set_color(2,NULL,(char *)"red",(char *)"black");
SLtt_set_color(12,NULL,(char *)"brightred",(char *)"black");
SLtt_set_color(22,NULL,(char *)"black",(char *)"red");
SLtt_set_color(32,NULL,(char *)"black",(char *)"brightred");
SLtt_set_color(3,NULL,(char *)"green",(char *)"black");
SLtt_set_color(13,NULL,(char *)"brightgreen",(char *)"black");
SLtt_set_color(23,NULL,(char *)"black",(char *)"green");
SLtt_set_color(33,NULL,(char *)"black",(char *)"brightgreen");
SLtt_set_color(4,NULL,(char *)"brown",(char *)"black");
SLtt_set_color(14,NULL,(char *)"yellow",(char *)"black");
SLtt_set_color(24,NULL,(char *)"black",(char *)"brown");
SLtt_set_color(34,NULL,(char *)"black",(char *)"yellow");
SLtt_set_color(5,NULL,(char *)"blue",(char *)"black");
SLtt_set_color(15,NULL,(char *)"brightblue",(char *)"black");
SLtt_set_color(25,NULL,(char *)"black",(char *)"blue");
SLtt_set_color(35,NULL,(char *)"black",(char *)"brightblue");
SLtt_set_color(6,NULL,(char *)"magenta",(char *)"black");
SLtt_set_color(16,NULL,(char *)"brightmagenta",(char *)"black");
SLtt_set_color(26,NULL,(char *)"black",(char *)"magenta");
SLtt_set_color(36,NULL,(char *)"black",(char *)"brightmagenta");
SLtt_set_color(7,NULL,(char *)"cyan",(char *)"black");
SLtt_set_color(17,NULL,(char *)"brightcyan",(char *)"black");
SLtt_set_color(27,NULL,(char *)"black",(char *)"cyan");
SLtt_set_color(37,NULL,(char *)"black",(char *)"brightcyan");
refresh();
return true;
}
void SLangConsole::close() {
func("%s",__PRETTY_FUNCTION__);
SLsmg_reset_smg();
SLang_reset_tty();
}
int SLangConsole::getkey() {
// low level
return SLkp_getkey();
}
void SLangConsole::feed(int key) {
/// func("feeding '%c' to widget %s", key, focused->name);
if(focused)
focused->feed(key);
}
bool SLangConsole::place(SLangWidget *wid, int hx, int hy, int lx, int ly) {
wid->orig_x = hx;
wid->orig_y = hy;
// boundaries where lower right coord
// get converted into WxH
if( lx > this->w )
wid->w = this->w - hx;
else
wid->w = lx - hx;
if( ly > this->h )
wid->h = this->h - hy;
else
wid->h = ly - hy;
// save a reference of the console in the widget
wid->console = this;
// append the new widget in our linklist
widgets.append( wid );
func("s-lang widget %s sized %ux%u placed at %u,%u",
wid->name, wid->w, wid->h,
wid->orig_x, wid->orig_y);
// draw border if requested
if(wid->border)
/* S-Lang has a coordinate system which is very
* different from the typical approach in computer graphics;
* the draw_box function works as follows:
SLsmg_draw_box (int r, int c, int dr, int dc);
Draw a box whose right corner is at row r and column c.
The box spans dr rows and dc columns.
The current position will be left at row r and column c.
*/
SLsmg_draw_box(wid->orig_y, wid->orig_x,
wid->h, wid->w);
// wid->refresh();
// focus the first widget
if(!focused) {
func("setting focus on widget %s",wid->name);
focused = wid;
}
return true;
}
bool SLangConsole::refresh() {
/* S-Lang says:
* All well behaved applications should block signals that
* may affect the display while performing screen update. */
SLsig_block_signals ();
if(screen_size_changed && !keyboard_quit) {
SLtt_get_screen_size ();
SLsmg_reinit_smg ();
this->w = SLtt_Screen_Cols;
this->h = SLtt_Screen_Rows;
screen_size_changed = false;
// refresh all widgets
SLangWidget *wid;
wid = (SLangWidget*) widgets.begin();
while(wid) {
wid->refresh();
wid = (SLangWidget*) wid->next;
}
}
// if(focused && !keyboard_quit)
// if(focused->cursor) {
// SLtt_set_cursor_visibility(1);
// focused->gotoxy( focused->cur_x, focused->cur_y);
// } else
// SLtt_set_cursor_visibility(0);
SLsmg_refresh();
SLsig_unblock_signals();
if(keyboard_quit) {
func("keyboard requested forced quit");
return false;
}
return true;
}
////////////////////////
/// messaging interface (TODO)
// void SLangConsole::notice (char *str) { }
// void SLangConsole::act (char *str) { }
// void SLangConsole::warning(char *str) { }
// void SLangConsole::error (char *str) { }
// void SLangConsole::func (char *str) { }
////////////////////////