[comp.emacs] curses interface for MicroEMACS

sjg@zen.void.oz.au (Simon J. Gerraty) (03/21/91)

Below is a shar file containing curses.c and a patchfile for the
rest of MicroEMACS so that curses(3X) can be used on systems
that support it.

Ignore the dates on the .old files (I just made them to back out
the changes).  Note that these patches are against my heavily
modified derivative of 3.9a, so you may need to give patch
plenty of slack!  Also note that this never worked with curses
on Microport SysV/AT.

Sorry if this should have gone somewhere else.

#! /bin/sh
echo x - curses.c
sed 's/^X//' >curses.c <<'*-*-END-of-curses.c-*-*'
X/*  NAME:
X *      curses.c - curses interface for uEmacs.
X *
X *
X *  DESCRIPTION:
X *      This module provides terminal I/O for uEmacs, using the 
X *      curses(3X) package. 
X *      The idea is to provide a more portable interface for 
X *      systems that support curses.
X *
X *      This code has been used on various System V machines as 
X *      well as SunOS 4.
X * 
X * AMENDED:
X *      89/05/14 14:59:43 (sjg)
X *
X * RELEASED:
X *      89/05/14 14:59:46 v1.6
X *
X *      Copyright (c) 1989 Simon J. Gerraty.
X *
X *      This is free software.  It comes with NO WARRANTY.
X *      Permission to use, modify and distribute this source code 
X *      is granted subject to the following conditions.
X *      1/ that that the above copyright notice and this notice 
X *      are preserved in all copies and that due credit be given 
X *      to the author.  
X *      2/ that any changes to this code are clearly commented 
X *      as such so that the author does get blamed for bugs 
X *      other than his own.
X *      
X *      Please send copies of changes and bug-fixes to:
X *      sjg@zen.void.oz.au
X *
X */
X#ifndef lint  /* sccs_id */
X  static char sccs_id[] = "@(#) curses.c	1.6 89/05/14 14:59:43 (sjg)";
X#endif  /* sccs_id */
X
X/* some useful #defines */
X#ifndef PUBLIC
X#define PUBLIC 
X#endif
X#ifndef LOCAL
X#define LOCAL static
X#endif
X#ifndef TRUE
X#define TRUE    1
X#endif
X#ifndef FALSE
X#define FALSE   0
X#endif
X#ifndef uchar
X#define uchar unsigned char
X#endif
X#ifndef uint
X#define uint unsigned int
X#endif
X
X#define	termdef	1			/* don't define "term" external */
X
X/* include files */
X#include "estruct.h"
X#include "edef.h"
X
X#if CURSES
X#define CNTRL 0x0100      /* keep curses.h happy */
X#undef  CTRL
X#define	MARGIN	8
X#define	SCRSIZ	64
X#define	NPAUSE	10			/* # times thru update to pause */
X#define BEL     0x07
X#define ESC     0x1B
X
X#include  <stdio.h>
X
X#include <curses.h>
X
X
XPUBLIC int        cs_open(),
X        cs_close(),
X        cs_kopen(),
X        cs_kclose(),
X        cs_getc(),
X        cs_putc(),
X        cs_flush(),
X        cs_move(),
X        cs_eeol(),
X        cs_eeop(),
X        cs_beep(),
X        cs_rev(),
X        cs_cres();
X#if	COLOR
XPUBLIC int 	cs_fcol(), cs_bcol();
X#endif
X
XTERM term = {
X	NULL,	/* these four values are set dynamically at open time */
X	NULL,
X	NULL,
X	NULL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X        cs_open,
X        cs_close,
X        cs_kopen,
X        cs_kclose,
X        cs_getc,
X        cs_putc,
X        cs_flush,
X        cs_move,
X        cs_eeol,
X        cs_eeop,
X        cs_beep,
X        cs_rev,
X        cs_cres
X#if	COLOR
X	, cs_fcol,
X	cs_bcol
X#endif
X};
X
X  
XPUBLIC int
Xcs_init()
X{
X  
X  initscr();
X
X  /* 1989-03-06 0833 (sjg)
X   * allow insert/delete line
X   */
X/*  idlok(stdscr, TRUE); */
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_tidy()
X{
X  endwin();
X  flushinp();
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_open()
X{
X  static int setup;
X  
X  if (setup != 42)
X  {
X    /* 1989-03-06 1505 (sjg)
X     * only save it once!
X     */
X    savetty();
X    setup = 42;
X  }
X  nonl();
X/*  cbreak(); */
X  noecho();
X/*  halfdelay(2); */
X  raw();
X
X  
X#if UNIX
X# ifdef sun
X  /* make the cursor *very* visible */
X  curs_set(2);
X# endif
X  
X  if (isatty(stdin))
X    typeahead(0);     /* allow type ahead for stdin */
X
X#endif
X  keypad(stdscr, TRUE);
X  term.t_mrow = stdscr->_maxy - 1;
X  term.t_nrow = stdscr->_maxy - 1;
X  term.t_mcol = stdscr->_maxx - 1;
X  term.t_ncol = stdscr->_maxx - 1;
X
X  eolexist = TRUE;    /* terminal can do eol (curses will fake it for us if not) */
X  revexist = TRUE;    /* terminal can do inverse video "" */
X  clearok(stdscr, FALSE);
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_close()
X{
X  nocbreak();
X  resetty();
X  endwin();
X  
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_kopen()
X{
X}
X
X  
XPUBLIC int
Xcs_kclose()
X{
X}
X
X
XPUBLIC int
Xcs_get1c()
X{
X  register int c;
X  
X  keypad(stdscr, FALSE);
X  c = wgetch(stdscr);
X  keypad(stdscr, TRUE);
X  return(c);
X}
X  
X
XPUBLIC int
Xcs_getc()
X{
X#if 1
X  register int c = ERR;
X  
X  while (c == ERR || c == 0)
X    c = wgetch(stdscr);
X  
X  return(c);
X#else
X  return(wgetch(stdscr));
X#endif
X}
X  
XPUBLIC int
Xcs_map(c)
X  int c;
X{
X  switch(c)
X  {
X    case KEY_DOWN:
X      c = CNTRL|'N';
X      break;    
X    case KEY_UP:
X      c = CNTRL|'P';
X      break;    
X    case KEY_LEFT:
X      c = CNTRL|'B';
X      break;    
X    case KEY_RIGHT:
X      c = CNTRL|'F';
X      break;    
X    case KEY_HOME:
X      c = META|'<';
X      break;    
X    case KEY_END:
X      c = META|'>';
X      break;    
X    case KEY_NPAGE:
X      c = CNTRL|'V';
X      break;    
X    case KEY_PPAGE:
X      c = META|'V';
X      break;    
X    case KEY_DC:
X      c = CNTRL|'D';
X      break;    
X    default:
X      if (c >= KEY_F0 && c <= KEY_F(9))         /* KEY_F0 - KEY_F9 == FN0 - FN9 */
X        c = SPEC | ((c - KEY_F0) + '0');
X      else
X        if (c >= KEY_F(10) && c <= KEY_F(35))   /* KEY_F10 - KEY_F35 == FNA - FNZ */
X          c = SPEC | ((c - KEY_F(10)) + 'A');
X        else
X          if (c >= KEY_F(36) && c <= KEY_F(63)) /* KEY_F36 - KEY_F63 == FNa - FN{ */
X            c = SPEC | ((c - KEY_F(36)) + 'a');
X      break;
X  }
X  
X  if (c >= 0 && c <= 0x1f)
X    c = CNTRL | (c + '@');
X
X  return(c);
X}
X
X  
XPUBLIC int
Xcs_putc(c)
X  int c;
X{
X  return(waddch(stdscr, c));
X}
X
X
X  
XPUBLIC int
Xcs_flush()
X{
X  wrefresh(stdscr);
X  clearok(stdscr, FALSE);
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_move(nrow, ncol)
X  short nrow, ncol;
X{
X  if (nrow < 0) nrow = 0;
X  if (ncol < 0) ncol = 0;
X  if (nrow > (stdscr->_maxy - 1)) nrow = stdscr->_maxy - 1;
X  if (ncol > (stdscr->_maxx - 1)) ncol = stdscr->_maxx - 1;
X
X  
X  wmove(stdscr, nrow, ncol);
X  return(0);
X}
X
X
XPUBLIC int
Xcs_clear(n)
X  int n;
X{
X  if (n)
X    wclear(stdscr);
X  else
X    clearok(stdscr, TRUE);
X    
X}
X
X  
XPUBLIC int
Xcs_eeol()
X{
X  return(wclrtoeol(stdscr));
X}
X
X  
XPUBLIC int
Xcs_eeop()
X{
X  return(wclrtobot(stdscr));
X}
X
X  
XPUBLIC int
Xcs_beep()
X{
X  beep();
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_rev(state)
X  int state;
X{
X  if (state)
X    wattron(stdscr, A_REVERSE);   /*  wstandout(stdscr); */
X  else
X    wattroff(stdscr, A_REVERSE);  /*  wstandend(stdscr); */
X  return(0);
X}
X
X  
XPUBLIC int
Xcs_cres()
X{
X}
X
X#if COLOR
X
X  
XPUBLIC int
Xcs_fcol()
X{
X}
X
X  
XPUBLIC int
Xcs_bcol()
X{
X}
X#endif
X
X
Xspal()
X{}
X
X
X
X
X#if TYPEAH
XPUBLIC int
Xtypahead()
X{
X#if 0 
X  /* nodelay mode seems to be dangerous
X   */
X  register int c;
X  
X  nodelay(stdscr, TRUE);
X  
X  if ((c = wgetch(stdscr)) != ERR && c != 0)
X  {
X    ungetch(c);
X    c = TRUE;
X  }
X  else
X    c = FALSE;
X  nodelay(stdscr, FALSE);
X  return(c);
X#else
X  return(FALSE);
X#endif
X}
X  
X#endif
X
X
X#endif /* CURSES */
*-*-END-of-curses.c-*-*
echo x - ptch
sed 's/^X//' >ptch <<'*-*-END-of-ptch-*-*'
X*** display.c.old	Thu Mar 21 13:16:19 1991
X--- display.c	Wed Mar  8 15:05:40 1989
X***************
X*** 504,511 ****
X--- 504,515 ----
X  #endif
X  	}
X  
X+ #if CURSES
X+         cs_clear(TRUE);
X+ #else
X  	movecursor(0, 0);		 /* Erase the screen. */
X  	(*term.t_eeop)();
X+ #endif
X  	sgarbf = FALSE;			 /* Erase-page clears */
X  	mpresf = FALSE;			 /* the message area. */
X  #if	COLOR
X*** input.c.old	Thu Mar 21 13:19:06 1991
X--- input.c	Wed Jul 19 15:52:46 1989
X***************
X*** 338,343 ****
X--- 338,347 ----
X  	/* get a keystroke */
X          c = tgetc();
X  
X+ #if  CURSES
X+   return(cs_map(c));
X+ #else
X+ 
X  #if	MSDOS | ST520
X  	if (c == 0) {				/* Apply SPEC prefix	*/
X  	        c = tgetc();
X***************
X*** 380,385 ****
X--- 384,390 ----
X          if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
X                  c = CTRL | (c+'@');
X          return (c);
X+ #endif /* CURSES */
X  }
X  
X  /*	GETCMD:	Get a command from the keyboard. Process all applicable
X***************
X*** 405,411 ****
X  #if	1	/* temporary ESC sequence fix......... */
X  		if (c == '[') {
X  
X! #ifdef sun386
X                          while ((c = get1key()) != 'z' && i < 6)
X                          {
X                            tmp[i++] = c & 127;
X--- 410,416 ----
X  #if	1	/* temporary ESC sequence fix......... */
X  		if (c == '[') {
X  
X! #if 0 /* def sun386 until curses.c works */
X                          while ((c = get1key()) != 'z' && i < 6)
X                          {
X                            tmp[i++] = c & 127;
X***************
X*** 412,417 ****
X--- 417,424 ----
X                            tmp[i] = '\0';
X                          }
X                          c = atoi(tmp) & 127; 
X+ #else
X+ 			c = get1key();
X  #endif
X  			return(SPEC | c);
X  		}
X***************
X*** 648,655 ****
X  	for (;;) 
X  	{
X  		/* get a character from the user */
X  		c = get1key();
X! 
X  		/* If it is a <ret>, change it to a <NL> */
X  		if (c == (CTRL | 0x4d))
X  			c = CTRL | 0x40 | '\n';
X--- 655,665 ----
X  	for (;;) 
X  	{
X  		/* get a character from the user */
X+ #if CURSES
X+                 c = cs_map(cs_get1c());
X+ #else
X  		c = get1key();
X! #endif
X  		/* If it is a <ret>, change it to a <NL> */
X  		if (c == (CTRL | 0x4d))
X  			c = CTRL | 0x40 | '\n';
X*** main.c.old	Thu Mar 21 13:20:12 1991
X--- main.c	Wed Jul 19 15:52:46 1989
X***************
X*** 144,149 ****
X--- 144,152 ----
X          extern char *optarg;
X          
X  	/* initialize the editor */
X+ #if CURSES
X+   cs_init();
X+ #endif
X          vtinit();		/* Display */
X          edinit("main");		/* Buffers, windows */
X  	varinit();		/* user variables */
X***************
X*** 625,630 ****
X--- 628,636 ----
X  #if DEBUG
X                          fcloseall();
X  #endif
X+ #if CURSES
X+                         cs_tidy();
X+ #endif
X  			exit(1);
X  		}
X  #endif
X***************
X*** 631,636 ****
X--- 637,645 ----
X                  vttidy();
X  #if DEBUG
X                  fcloseall();
X+ #endif
X+ #if CURSES
X+                 cs_tidy();
X  #endif
X                  exit(GOOD);
X          }
X*** spawn.c.old	Thu Mar 21 13:20:59 1991
X--- spawn.c	Wed Mar  8 15:05:40 1989
X***************
X*** 411,418 ****
X--- 411,423 ----
X          TTclose();                              /* stty to old modes    */
X          system(line);
X          TTopen();
X+ #if CURSES    
X+         fprintf(stderr, "\r\n[End]");
X+         fflush(stderr);
X+ #else
X          mlputs("[End]");                        /* Pause.               */
X          TTflush();
X+ #endif
X          while ((s = tgetc()) != '\r' && s != ' ')
X                  ;
X          sgarbf = TRUE;
X*** tcap.c.old	Thu Mar 21 13:21:49 1991
X--- tcap.c	Mon Mar  6 19:03:32 1989
X***************
X*** 48,53 ****
X--- 48,55 ----
X  #include	"estruct.h"
X  #include        "edef.h"
X  
X+ #if CURSES
X+ #else
X  
X  #if TERMCAP
X  
X***************
X*** 275,277 ****
X--- 277,280 ----
X  
X  #endif
X  
X+ #endif /* CURSES */
X*** termio.c.old	Thu Mar 21 13:22:37 1991
X--- termio.c	Mon Mar  6 19:03:32 1989
X***************
X*** 51,56 ****
X--- 51,59 ----
X  #include	"estruct.h"
X  #include        "edef.h"
X  
X+ #if  CURSES
X+ #else
X+ 
X  #if   MSDOS & TURBO
X  #include <conio.h>
X  #endif
X***************
X*** 557,560 ****
X--- 560,565 ----
X  #endif
X  	return(FALSE);
X  }
X  #endif
X+ 
X+ #endif /* CURSES */
X*** window.c.old	Thu Mar 21 13:23:07 1991
X--- window.c	Wed Mar  8 15:05:42 1989
X***************
X*** 65,70 ****
X--- 65,73 ----
X  	n = 0;
X      curwp->w_force = n;
X      curwp->w_flag |= WFFORCE;
X+ #if  CURSES 
X+   cs_clear(FALSE);
X+ #endif
X      return (TRUE);
X      }
X  
*-*-END-of-ptch-*-*
exit 0

-- 
Simon J. Gerraty        <sjg@zen.void.oz.au>

#include <disclaimer>   /* imagine something _very_ witty here */