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.