This is slcurses.c in view mode; [Download] [Up]
#include "config.h"
#include <stdio.h>
#include <signal.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "slang.h"
#include "_slang.h"
#include "slcurses.h"
/* This file is meant to implement a primitive curses implementation in
* terms of SLsmg calls. The fact is that the interfaces are sufficiently
* different that a 100% emulation is not possible.
*/
int SLcurses_mvprintw (int r, int c, char *fmt, ...)
{
char p[1000];
va_list ap;
SLsmg_gotorc (r, c);
va_start(ap, fmt);
(void) vsprintf(p, fmt, ap);
va_end(ap);
SLsmg_write_string (p);
return 0;
}
int SLcurses_nil (void)
{
return 0;
}
int SLcurses_has_colors(void)
{
return SLtt_Use_Ansi_Colors;
}
static int Delay_Off;
int SLcurses_nodelay (SLcurses_Window_Type *w, int onoff)
{
Delay_Off = onoff;
return 0;
}
int SLcurses_getch (void)
{
SLsmg_refresh ();
if ((Delay_Off == 0) ||
SLang_input_pending (0))
return SLang_getkey ();
return 0xFFFF;
}
/* This is a super hack. That fact is that SLsmg and curses
* are incompatible.
*/
static unsigned char Color_Objects[256];
static unsigned int map_attr_to_object (SLtt_Char_Type attr)
{
unsigned int obj;
SLtt_Char_Type at;
obj = (attr >> 8) & 0xFF;
if (SLtt_Use_Ansi_Colors)
{
if (Color_Objects[obj] != 0) return obj;
at = SLtt_get_color_object (obj & 0xF);
if (attr & A_BOLD) at |= SLTT_BOLD_MASK;
if (attr & A_UNDERLINE) at |= SLTT_ULINE_MASK;
if (attr & A_REVERSE) at |= SLTT_REV_MASK;
SLtt_set_color_object (obj, at);
Color_Objects[obj] = 1;
}
else obj = obj & 0xF0;
return obj;
}
int SLcurses_start_color (void)
{
int f, b;
int obj;
if (SLtt_Use_Ansi_Colors == 0) return -1;
obj = 0;
for (f = 0; f < 8; f++)
{
for (b = 0; b < 8; b++)
{
obj++;
SLtt_set_color_fgbg (obj, f, b);
}
}
return 0;
}
#ifdef SIGINT
static void sigint_handler (int sig)
{
SLang_reset_tty ();
SLsmg_reset_smg ();
exit (sig);
}
#endif
static int TTY_State;
static int init_tty (int suspend_ok)
{
SLang_init_tty (-1, 0, 0);
if (suspend_ok) SLtty_set_suspend_state (1);
return 0;
}
int SLcurses_raw (void)
{
TTY_State = 1;
return init_tty (0);
}
int SLcurses_cbreak (void)
{
TTY_State = 2;
return init_tty (1);
}
#if defined(SIGTSTP) && defined(SIGSTOP)
static void sigtstp_handler (int sig)
{
SLsmg_suspend_smg ();
if (TTY_State)
SLang_reset_tty ();
kill(getpid(),SIGSTOP);
SLsmg_resume_smg ();
if (TTY_State == 1)
SLcurses_raw ();
else if (TTY_State == 2)
SLcurses_cbreak ();
signal (SIGTSTP, sigtstp_handler);
}
#endif
int SLcurses_initscr (void)
{
SLsmg_Newline_Moves = -1;
SLtt_get_terminfo ();
SLsmg_init_smg ();
#ifdef SIGINT
signal (SIGINT, sigint_handler);
#endif
#if defined(SIGTSTP) && defined(SIGSTOP)
signal (SIGTSTP, sigtstp_handler);
#endif
SLtt_set_mono (A_BOLD >> 8, NULL, SLTT_BOLD_MASK);
SLtt_set_mono (A_UNDERLINE >> 8, NULL, SLTT_ULINE_MASK);
SLtt_set_mono (A_REVERSE >> 8, NULL, SLTT_REV_MASK);
/* SLtt_set_mono (A_BLINK >> 8, NULL, SLTT_BLINK_MASK); */
SLtt_set_mono ((A_BOLD|A_UNDERLINE) >> 8, NULL, SLTT_ULINE_MASK|SLTT_BOLD_MASK);
SLtt_set_mono ((A_REVERSE|A_UNDERLINE) >> 8, NULL, SLTT_ULINE_MASK|SLTT_REV_MASK);
return 0;
}
int SLcurses_addch (SLtt_Char_Type attr)
{
unsigned int obj;
unsigned short ch;
if (attr == (attr & 0xFF))
{
SLsmg_write_char (attr & 0xFF);
return 0;
}
obj = map_attr_to_object (attr);
ch = (attr & 0xFF) | (obj << 8);
SLsmg_write_color_chars (&ch, 1);
return 0;
}
int SLcurses_mvaddch (int r, int c, SLtt_Char_Type attr)
{
SLsmg_gotorc (r, c);
return SLcurses_addch (attr);
}
static SLtt_Char_Type Current_Attr;
int SLcurses_attrset (SLtt_Char_Type ch)
{
unsigned int obj;
obj = map_attr_to_object (ch);
SLsmg_set_color (obj);
Current_Attr = ch;
return 0;
}
int SLcurses_attroff (SLtt_Char_Type ch)
{
if (SLtt_Use_Ansi_Colors)
return SLcurses_attrset (0);
Current_Attr &= ~ch;
return SLcurses_attrset (Current_Attr);
}
int SLcurses_attron (SLtt_Char_Type ch)
{
if (SLtt_Use_Ansi_Colors)
return SLcurses_attrset (ch);
Current_Attr |= ch;
return SLcurses_attrset (Current_Attr);
}
SLcurses_Window_Type *SLcurses_newwin (unsigned int nrows, unsigned int ncols,
unsigned int r, unsigned int c)
{
SLcurses_Window_Type *win;
unsigned short *b, *bmax;
unsigned int len;
if (NULL == (win = (SLcurses_Window_Type *) SLMALLOC (sizeof (SLcurses_Window_Type))))
return NULL;
SLMEMSET ((char *) win, 0, sizeof (SLcurses_Window_Type));
len = nrows * ncols;
if (NULL == (b = (unsigned short *) SLMALLOC (len * sizeof (unsigned short))))
{
SLFREE (win);
return NULL;
}
win->b = win->buf = b;
win->bufmax = bmax = b + len;
while (b < bmax) *b++ = ' ';
win->row = r;
win->col = c;
win->nrows = nrows;
win->ncols = ncols;
win->crow = 0;
win->ccol = 0;
win->color = 0;
return win;
}
int SLcurses_wmove (SLcurses_Window_Type *win, unsigned int r, unsigned int c)
{
if (win == NULL) return -1;
win->crow = r;
win->ccol = c;
win->b = win->buf + (r * win->ncols + c);
return 0;
}
int SLcurses_waddch (SLcurses_Window_Type *win, char ch)
{
unsigned short *b;
if (win == NULL) return -1;
b = win->b;
if (b < win->bufmax)
{
*b++ = ch | win->color;
win->b = b;
win->ccol++;
if (win->ccol >= win->ncols)
{
win->ccol = 0;
win->crow++;
}
}
return 0;
}
int SLcurses_delwin (SLcurses_Window_Type *w)
{
if (w != NULL)
{
if (w->buf != NULL)
free (w->buf);
free (w);
}
return 0;
}
int SLcurses_wnoutrefresh (SLcurses_Window_Type *w)
{
unsigned short *b, *bmax;
unsigned int len;
unsigned int r, c;
if (w == NULL)
{
SLsmg_refresh ();
return -1;
}
r = w->row;
c = w->col;
b = w->buf;
bmax = w->bufmax;
len = w->ncols;
while (b < bmax)
{
SLsmg_gotorc (r, c);
SLsmg_write_color_chars (b, len);
r++;
b += len;
}
SLsmg_gotorc (w->row + w->crow, w->col + w->ccol);
return 0;
}
int SLcurses_wrefresh (SLcurses_Window_Type *w)
{
SLcurses_wnoutrefresh (w);
SLsmg_refresh ();
return 0;
}
int SLcurses_wclrtoeol (SLcurses_Window_Type *w)
{
unsigned short *b, *bmax;
unsigned short blank;
if (w == NULL) return -1;
blank = w->color | 0x20;
bmax = w->buf + (w->crow + 1) * w->ncols;
b = w->b;
if (bmax > w->bufmax) bmax = w->bufmax;
while (b < bmax) *b++ = blank;
return 0;
}
int SLcurses_wclrtobot (SLcurses_Window_Type *w)
{
unsigned short *b, *bmax;
unsigned short blank;
if (w == NULL) return -1;
blank = w->color | 0x20;
b = w->b;
bmax = w->bufmax;
while (b < bmax) *b++ = blank;
return 0;
}
int SLcurses_scroll (SLcurses_Window_Type *w)
{
if (w == NULL) return -1;
memcpy ((char *) w->buf, (char *) w->buf + w->ncols,
sizeof (short) * (w->nrows - 1) * w->ncols);
wmove (w, w->nrows - 1, 0);
wclrtobot (w);
return 0;
}
static void update_cursor_position (SLcurses_Window_Type *w)
{
unsigned int offset;
offset = w->b - w->buf;
w->crow = offset / w->ncols;
w->ccol = offset % w->ncols;
}
int SLcurses_waddstr (SLcurses_Window_Type *w, char *str)
{
unsigned short *b, *bmax;
unsigned short color;
unsigned char ch;
if (w == NULL) return -1;
b = w->b;
bmax = w->bufmax;
color = w->color;
while ((b < bmax) && ((ch = (unsigned char) *str) != 0))
{
if (ch == '\n')
{
update_cursor_position (w);
SLcurses_wclrtoeol (w);
SLcurses_wmove (w, w->crow, 0);
}
else *b++ = color | ch;
}
update_cursor_position (w);
return 0;
}
/* This routine IS NOT CORRECT. It needs to compute the proper overlap
* and copy accordingly. Here, I just assume windows are same size.
*/
int SLcurses_overlay (SLcurses_Window_Type *swin, SLcurses_Window_Type *dwin)
{
unsigned short *s, *smax, *d, *dmax;
if ((swin == NULL) || (dwin == NULL))
return -1;
s = swin->buf;
smax = swin->bufmax;
d = dwin->buf;
dmax = dwin->bufmax;
while ((s < smax) && (d < dmax))
{
unsigned short ch = *s++;
if ((ch & 0xFF) != ' ')
*d = ch;
d++;
}
return -1; /* not implemented */
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.