/* 
 *     XaoS, a fast portable realtime fractal zoomer 
 *                  Copyright (C) 1996,1997 by
 *
 *      Jan Hubicka          (hubicka@paru.cas.cz)
 *      Thomas Marsh         (tmarsh@austin.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include "aconfig.h"
#ifdef CURSES_DRIVER
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef USE_NCURSES
#include <ncurses.h>
#else
#include <curses.h>
#endif
#include <setjmp.h>
#include <ctype.h>
#include <config.h>
#include "mktable.h"
#include <param.h>
#include <ui.h>
static int width = 640, height = 480;
static int currentbuff = 0;
static int ncolors = 0;
static int buttons, mousex, mousey, keys;
static int supportedon[NATTRS], supportedoff[NATTRS];
static char *buffers[4];
static int palette;
static int resized, iswaiting;
static int fontwidth;
static int rotation;
static jmp_buf buf;
#define NPALETTES 5;
static void 
curses_print (int x, int y, char *text)
{

  mvprintw (y / 2, x / 2, text);

}

static void 
curses_refresh (void)
{
  refresh ();
}

const char *tags[NATTRS - 1] =
{
  "<FONT COLOR=\"808080\">",
  "<B><FONT COLOR=\"ffffff\">",
  "<A HREF=A>",
  "<B>",
};
const char *endtags[NATTRS - 1] =
{
  "</FONT>",
  "</FONT></B>",
  "</A>",
  "</B>",
};
char *
writetxt (void)
{
  static char name[256];
  static int nimage = 0;
  int x, y, c;
#ifdef _plan9_
  char edir[DIRLEN];
#else
  struct stat sb;
#endif
  FILE *f;
  do
    {
      sprintf (name, "fract%i.txt", nimage++);
#ifndef _plan9_
    }
  while (stat (name, &sb) != -1);
#else
    }
  while (stat (name, edir) != -1);
#endif
  f = fopen (name, "wt");
  nodelay (stdscr, FALSE);
  mvprintw (0, 0, "Select attribute encoding:          ");
  mvprintw (1, 0, "1 - for more and less               ");
  mvprintw (2, 0, "2 - html                            ");
  mvprintw (3, 0, "3 - ansi escape sequences           ");
  refresh ();
  while ((c = tolower (getch ())) < '1' || c > '3');
  switch (c)
    {
    case '1':

      for (y = 0; y < height; y++)
	{
	  for (x = 0; x < width; x++)
	    {
	      if (buffers[3][y * width + x] == BOLD || buffers[3][y * width + x] == BOLDFONT)
		{
		  putc (buffers[2][y * width + x], f);
		  if (buffers[2][y * width + x] != ' ')
		    {
		      putc (8, f);
		      putc (buffers[2][y * width + x], f);
		    }
		}
	      else
		putc (buffers[2][y * width + x], f);
	    }
	  putc ('\n', f);
	}
      break;
    case '3':
      {
	int lastmode = NORMAL, mode;
	for (y = 0; y < height; y++)
	  {
	    for (x = 0; x < width; x++)
	      {
		mode = buffers[3][y * width + x];
		if (mode != lastmode)
		  {
		    if (lastmode != NORMAL)
		      fprintf (f, "%c[0;10m", 27);
		    switch (mode)
		      {
		      case BOLD:
		      case BOLDFONT:
			fprintf (f, "%c[1m", 27);
			break;
		      case REVERSE:
			fprintf (f, "%c[7m", 27);
			break;
		      case DIM:
			fprintf (f, "%c[8m", 27);
			break;

		      }
		    lastmode = mode;
		  }
		putc (buffers[2][y * width + x], f);
	      }
	    putc ('\n', f);
	  }
	if (lastmode != NORMAL)
	  fprintf (f, "%c[0;10m", 27);
      }
      break;
    case '2':
      {
	int lasttag = -1;
	fprintf (f, "<HTML>\n <HEAD> <TITLE>Fractal generated by XaoS</TITLE>\n</HEAD>\n<BODY BGCOLOR=\"#000000\" TEXT=\"#dddddd\" LINK=\"#FFFFFF\">\n<FONT SIZE=2><PRE>\n");
	for (y = 0; y < height; y++)
	  {
	    for (x = 0; x < width; x++)
	      {
		char cc;
		if ((char) buffers[3][y * width + x] - 1 != lasttag)
		  {
		    if (lasttag >= 0)
		      fprintf (f, "%s", endtags[lasttag]);
		    lasttag = (char) buffers[3][y * width + x] - 1;
		    if (lasttag >= 0)
		      fprintf (f, "%s", tags[lasttag]);
		  }
		cc = buffers[2][y * width + x];
		switch (cc)
		  {
		  case '<':
		    fprintf (f, "&lt;");
		    break;
		  case '>':
		    fprintf (f, "&gt;");
		    break;
		  case '&':
		    fprintf (f, "&amp;");
		    break;
		  default:
		    putc (buffers[2][y * width + x], f);
		  }
	      }
	    putc ('\n', f);
	  }
	fprintf (f, "</PRE></FONT></BODY>\n</HTML>\n");
	break;
      }
    }
  curses_print (0, 0, "Saved.\n");
  fclose (f);
  return name;
}
#define min(x,y) ((x)<(y)?(x):(y))
static void 
curses_display (void)
{
  int x, y;
  int nattrs = 0;
  for (y = 0; y < NATTRS; y++)
    nattrs += supported[y];
  for (y = 0; y < height; y++)
    {
      for (x = 0; x < width; x++)
	{
	  int c1, c2, c3, c4, c = 0;
	  int pos = x * 2 + width * 4 * y;
#if 0
	  c1 = ((unsigned char) (buffers[currentbuff][((x) * 2 + 1 + width * 2 * (y) * 2)]));
	  c2 = ((unsigned char) (buffers[currentbuff][((x) * 2 + width * 2 * (y * 2))]));
	  c3 = ((unsigned char) (buffers[currentbuff][((x) * 2 + 1 + width * 2 * (y * 2 + 1))]));
	  c4 = ((unsigned char) (buffers[currentbuff][((x) * 2 + width * 2 * (y * 2 + 1))]));
#endif

	  c1 = (unsigned char) (buffers[currentbuff][pos + 1]);
	  c2 = (unsigned char) (buffers[currentbuff][pos]);
	  c3 = (unsigned char) (buffers[currentbuff][pos + 1 + width + width]);
	  c4 = (unsigned char) (buffers[currentbuff][pos + width + width]);
	  if (c1)
	    c1 = (unsigned char) ((int) c1 + rotation);
	  if (c2)
	    c2 = (unsigned char) ((int) c2 + rotation);
	  if (c3)
	    c3 = (unsigned char) ((int) c3 + rotation);
	  if (c4)
	    c4 = (unsigned char) ((int) c4 + rotation);
	  switch (palette)
	    {
	    case 0:
	      c = ((int) c1 & 15) * 16 * 16 * 16 + ((int) c2 & 15) * 16 * 16 + ((int) c3 & 15) * 16 + ((int) c4 & 15);
	      break;
	    case 1:
	      c = ((int) c1 & 1) * 16 * 16 * 16 * 15 + ((int) c2 & 1) * 16 * 16 * 15 + ((int) c3 & 1) * 16 * 15 + ((int) c4 & 1) * 15;
	      break;
	    case 2:
	      c = min (((int) c1 % 5) * 16 * 16 * 16 * 4, 16 * 16 * 16 * 15) + min (((int) c2 % 5) * 16 * 16 * 4, 16 * 16 * 15) + min (((int) c3 % 5) * 16 * 4, 16 * 15) + min (((int) c4 % 5) * 4, 15);
	      break;
	    case 3:
	      c = ((int) c1 & ~15) * 16 * 16 + ((int) c2 & ~15) * 16 + ((int) c3 & ~15) + ((int) c4 & ~15) / 16;
	      break;
	    case 4:
	      c = ((int) c1 != 0) * 16 * 16 * 16 * 15 + ((int) c2 != 0) * 16 * 16 * 15 + ((int) c3 != 0) * 16 * 15 + ((int) c4 != 0) * 15;
	      break;
	    }
	  if (c >= 65534)
	    c = 65534;
	  if (c < 0)
	    c = 0;
	  c = table[c];
	  /*buffers[2][x+y*width]=table[c]; */
	  if (nattrs != 1)
	    {
	      switch (c / 128)
		{
		case NORMAL:
		  attrset (A_NORMAL);
		  break;
		case REVERSE:
		  attrset (A_REVERSE);
		  break;
		case DIM:
		  attrset (A_DIM);
		  break;
		case BOLD:
		  attrset (A_BOLD);
		  break;
		case BOLDFONT:
		  attrset (A_BOLD);
		  break;
		}
	      mvaddch (y, x, c % 128);
	    }
	  buffers[2][x + y * width] = c % 128;
	  buffers[3][x + y * width] = c / 128;
	}
      if (nattrs == 1)
	{
	  buffers[2][(y + 1) * width] = 0;
	  switch (buffers[3][0])
	    {
	    case NORMAL:
	      attrset (A_NORMAL);
	      break;
	    case REVERSE:
	      attrset (A_REVERSE);
	      break;
	    case DIM:
	      attrset (A_DIM);
	      break;
	    case BOLD:
	      attrset (A_BOLD);
	      break;
	    case BOLDFONT:
	      attrset (A_BOLD);
	      break;
	    }
	  mvaddstr (y, 0, buffers[2] + y * width);
	}
    }
  attrset (A_NORMAL);
  move (mousey / 2, mousex / 2);

}
static int 
curses_set_color (int r, int g, int b, int init)
{

  if (init)
    ncolors = 0;
  if (ncolors >= 256)
    return (-1);
  rotation = 0;
  return (ncolors++);

}
#ifdef NCURSESMOUSE
void 
handlemouse (void)
{
  MEVENT mouse;
  getmouse (&mouse);
  mousex = mouse.x * 2;
  mousey = mouse.y * 2;
  if (BUTTON_RELEASE (mouse.bstate, 1))
    buttons &= ~BUTTON1;
  if (BUTTON_RELEASE (mouse.bstate, 2))
    buttons &= ~BUTTON2;
  if (BUTTON_RELEASE (mouse.bstate, 3))
    buttons &= ~BUTTON3;
  if (BUTTON_PRESS (mouse.bstate, 1))
    buttons |= BUTTON1;
  if (BUTTON_PRESS (mouse.bstate, 2))
    buttons |= BUTTON2;
  if (BUTTON_PRESS (mouse.bstate, 3))
    buttons |= BUTTON3;
}
#endif
#if 0
static void 
curses_rotate (int direction)
{
  rotation += direction;
  curses_display ();
}
#endif
static int 
getkey (void)
{
  int key = getch ();
  if (mousey < 0)
    mousey = 0;
  if (mousey > 2 * height - 1)
    mousey = 2 * height - 1;
  if (mousex < 0)
    mousex = 0;
  if (mousex > 2 * width - 1)
    mousex = 2 * width - 1;
  move (mousey / 2, mousex / 2);
  refresh ();
  /*mvprintw(0,0,"%i",key);
     refresh(); */
  if (resized)
    ui_resize ();
  if (key == 1)
    mousex -= 2;
  else if (key == 4)
    mousex += 2;
  else if (key == 23)
    mousey -= 2;
  else if (key == 24)
    mousey += 2;
  else if (key == 18)
    buttons ^= BUTTON1;
  else if (key == 20)
    buttons ^= BUTTON2;
  else if (key == 25)
    buttons ^= BUTTON3;
  else if (key == 'E')
    {
      ui_tbreak ();
      nodelay (stdscr, FALSE);
      echo ();
      nocbreak ();
      mvprintw (0, 0, "Resolution is:%ix%i. Your coordinates sir:", width * 2, height * 2);
      scanw ("%i,%i", &mousex, &mousey);
      mvprintw (0, 0, "Button 1:%i,2:%i,3:%i. Your button mask sir:", BUTTON1, BUTTON2, BUTTON3);
      scanw ("%i,%i", &buttons);
      cbreak ();
      noecho ();
      nodelay (stdscr, TRUE);
    }
  else if (key == 'G')
    {
      char c;
      int nones = 0;
      ui_tbreak ();
      nodelay (stdscr, FALSE);
      mvprintw (0, 0, "May I use normal text?          ");
      refresh ();
      while ((c = tolower (getch ())) != 'y' && c != 'n');
      nones += (supported[0] = c == 'y');
      mvprintw (1, 0, "May I use half bright(dim)?     ");
      refresh ();
      while ((c = tolower (getch ())) != 'y' && c != 'n');
      nones += (supported[1] = c == 'y');
      mvprintw (2, 0, "May I use bold as double bright?");
      refresh ();
      while ((c = tolower (getch ())) != 'y' && c != 'n');
      nones += (supported[2] = c == 'y');
      mvprintw (3, 0, "May I use bold as bold font?    ");
      refresh ();
      while ((c = tolower (getch ())) != 'y' && c != 'n');
      nones += (supported[4] = c == 'y');
      mvprintw (4, 0, "May I use reversed text?        ");
      refresh ();
      while ((c = tolower (getch ())) != 'y' && c != 'n');
      nones += (supported[3] = c == 'y');
      mvprintw (5, 0, "1=8x16font 2=8x8font            ");
      refresh ();
      while ((c = tolower (getch ())) != '1' && c != '2');
      if (c == '1')
	setheight (16);
      else
	setheight (8);
      if (!nones)
	supported[0] = 1;
      if (supported[2] && supported[4])
	supported[4] = 0;
      mvprintw (6, 0, "rendering aproximation tables   ");
      refresh ();
      mktable ();
      curses_display ();
      nodelay (stdscr, TRUE);
      refresh ();
    }
  else if (key == KEY_LEFT)
    keys ^= 1;
  else if (key == KEY_RIGHT)
    keys ^= 2;
  else if (key == KEY_UP)
    keys ^= 4;
  else if (key == KEY_DOWN)
    keys ^= 8;
  else if (key == 12)
    {
      wclear (stdscr);
      refresh ();
#ifdef HAVE_REDRAWWIN
      redrawwin (stdscr);
#else
#ifdef redrawwin
      redrawwin (stdscr);
#else
#ifdef redrawln
      wredrawln (stdscr, 0, height + 1);
#endif
#endif
#endif
      curses_display ();
    }
  else
#ifdef NCURSESMOUSE
  if (key == KEY_MOUSE)
    handlemouse ();
  else
#endif
  if (tolower (key) == 'T')
    writetxt ();
  else if (tolower (key) == 'p')
    {
      palette = (palette + 1) % NPALETTES;
      curses_display ();
    }
  else
    return (key);
  return (0);
}
static void 
curses_clear (void)
{
  wclear (stdscr);
}

static void 
curses_flip_buffers (void)
{
  currentbuff ^= 1;
}

void 
curses_free (char *b1, char *b2)
{
  free (buffers[0]);
  free (buffers[1]);
  free (buffers[2]);
  free (buffers[3]);
}

int 
curses_alloc (char **b1, char **b2)
{
  buffers[0] = (char *) malloc (width * height * 4);
  buffers[1] = (char *) malloc (width * height * 4);
  buffers[2] = (char *) malloc (width * height + 1);
  buffers[3] = (char *) malloc (width * height + 1);
  currentbuff = 0;
  *b1 = buffers[0];
  *b2 = buffers[1];
  return width * 2;
}
static void 
curses_processevents (volatile int wait, volatile int *x, volatile int *y, volatile int *b, volatile int *k)
{
  volatile int c;
  if (wait)
    {
      nodelay (stdscr, FALSE);
      setjmp (buf);
      iswaiting = 1;
      if (resized)
	ui_resize ();
    }
  else
    nodelay (stdscr, TRUE);
  while ((c = getkey ()) != ERR)
    {
      if (wait)
	nodelay (stdscr, TRUE), wait = 0, iswaiting = 0;
      if (ui_key (c) == 2)
	return;
    }
  if (wait)
    nodelay (stdscr, TRUE), wait = 0;
  *x = 0, *y = 0, *b = 0, *k = 0;
  *x = mousex;
  *y = mousey;
  *b = buttons;
  *k = keys;
}
static void 
curses_getmouse (int *x, int *y, int *b)
{
  *x = 0, *y = 0, *b = 0;
  *x = mousex;
  *y = mousey;
  *b = buttons;
}
void 
handler (int i)
{
  resized = 1;
  if (iswaiting)
    longjmp (buf, 1);
}
int 
curses_init (void)
{
  fflush (stdout);
  if (initscr () == NULL)
    return 0;
  if (table == NULL)
    {
      int i;
#ifdef HAVE_TERMATTRS
      int na = termattrs ();
#endif
      for (i = 0; i < NATTRS; i++)
	{
	  if (supportedon[i])
	    supported[i] = 1;
	  else if (supportedoff[i])
	    supported[i] = 0;
	  else
	    {
	      int a = 0;
	      if (i == NORMAL)
		continue;
	      switch (i)
		{
		case DIM:
		  a = A_DIM;
		  break;
		case BOLD:
		  a = A_BOLD;
		  break;
		case BOLDFONT:
		  a = A_BOLD;
		  break;
		case REVERSE:
		  a = A_REVERSE;
		  break;
		}
#ifdef HAVE_TERMATTRS
	      if (!(a & na))
#else
	      if (!(a))
#endif
		supported[i] = 0;
	    }
	}
      if (fontwidth == 8)
	setheight (8);
      if (fontwidth == 16)
	setheight (16);
      printf ("Please wait..rendering aproximation table..");
      mktable ();
      printf ("ok\n");
    }
  cbreak ();
  nodelay (stdscr, TRUE);
  noecho ();
  nonl ();
  intrflush (stdscr, FALSE);
  keypad (stdscr, TRUE);
  signal (SIGFPE, SIG_IGN);
#ifdef SIGWINCH
  signal (SIGWINCH, handler);	/*this line may cause problem...
				   sumply uncoment it */
#endif
#ifdef NCURSESMOUSE
  mousemask (ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
#endif
  return (1);
}


static void 
curses_uninitialise (void)
{
  wclear (stdscr);
  intrflush (stdscr, TRUE);
  keypad (stdscr, FALSE);
  nodelay (stdscr, FALSE);
#ifdef SIGWINCH
  signal (SIGWINCH, SIG_IGN);	/*this line may cause problem... */
#endif
  nocbreak ();
  echo ();
  nl ();
  refresh ();
  endwin ();
}

static void 
curses_get_size (int *wi, int *he)
{
  if (resized)
    curses_uninitialise (), curses_init (), resized = 0;
  /*getmaxyx(stdscr, *he, *wi); */
  *wi = stdscr->_maxx;
  *he = stdscr->_maxy;
  width = *wi;
  height = *he;
  *wi *= 2;
  *he *= 2;
}
static char *helptext[] =
{
  "(N)CURSES DRIVER VERSION 1.1           ",
  "============================           ",
  " This driver used to be one of the     ",
  " most powerfull drivers for XaoS       ",
  " It supports all XaoS features:        ",
  "  o 256 colors                         ",
  "  o smooth animations                  ",
  "  o much more                          ",
  " But currently it is obsoletted by new ",
  " AA driver. If you like text mode,     ",
  " please update to AA driver. You should",
  " download AA-lib from AA-project       ",
  " homepage at http://www.ta.jcu.cz/aa   ",
  " Recompiling of XaoS with AAlib        ",
  " installed will automatically enable   ",
  " AA driver (if it is not already in -  ",
  " try xaos -driver aa)                  ",
  "                                       ",
  " This driver was left in XaoS because  ",
  " there is still many user's without    ",
  " AAlib installed, but once it will be  ",
  " removed. It is no longer maitained and",
  " updated so it does not conforms latest",
  " XaoS driver coding standards (Xdcs)   ",
  " and should not be fully functional    ",
  " in recent releases of XaoS.           ",
  "                                       ",
  " Use it at your own's risk!            ",
  "                                       ",
  " And has also many extended features   ",
  "  o Doubling of resolution with        ",
  "     anti-aliasing                     ",
  "  o Mouse emulation                    ",
  "     because mouse is still not        ",
  "     standard in terminals XaoS uses   ",
  "     its emulation with is yet more    ",
  "     powerfull than normal mouse.      ",
  "     Press shift+'E' to try it!        ",
  "     Also you may move mouse by keys:  ",
  "      C-w = up                         ",
  "      C-a = left                       ",
  "      C-d = right                      ",
  "      C-x = down                       ",
  "      C-r = button1 (first pres presses",
  "             button, second releases it",
  "             Same behaviour is used for",
  "             arrows keys, because text ",
  "             terminals does not sends  ",
  "             informations about        ",
  "             releasing of keys.)       ",
  "      C-t = button2                    ",
  "      C-y = button3                    ",
  "  o Special handling of attributes.    ",
  "     can be configured by shift+'G'    ",
  "     It will ask you following         ",
  "     questions:                        ",
  "     May I use normal text             ",
  "      Many terminals supports various  ",
  "      attributes. Using this questions ",
  "      you may configure XaoS to use    ",
  "      them. Normal text is text w/o any",
  "      special attributes.              ",
  "     May I use half bright(dim)        ",
  "      Some terminals supports          ",
  "      atribute dim for half bright.    ",
  "      this is untested, because no     ",
  "      xterm nor linux console does this",
  "     May I use bold as double bright   ",
  "      some terminals(like linux console",
  "      makes bold character by lighter  ",
  "      color.                           ",
  "     May I use bold as bold font?      ",
  "      other terminals uses another font",
  "      for bold characters(like rvxt)   ",
  "     May I use reversed text           ",
  "      This produces good results just  ",
  "      really hi-res terminals(more than",
  "      100x40) Nice with fullscreen     ",
  "      xterm and tiny font.             ",
  "     1=8x16font 2=8x8font              ",
  "      most terminals uses 8x16 font.   ",
  "      But some terminals with square   ",
  "      letters(ie vga with 80x50 mode or",
  "      xterm with tiny font) uses 8x8   ",
  "      one. You may try both of them and",
  "      use better one.                  ",
  "  o Mouse support                      ",
  "     driver also supports mouse        ",
  "     interface included in ncurses.    ",
  "     but it is bit buggy, and have some",
  "     limitations.                      ",
  "  o Ascii-art images saving.           ",
  "     normally XaoS does not support    ",
  "     saving of ascii arted images and  ",
  "     uses poor gif file instead.       ",
  "     press shift+'T' to save images.   ",
  "  o Uses 65535 bytes long lookup table ",
  "     to make ultra fast aproximation   ",
  "     by letters                        ",
  "  o Specialized palettes for text mode ",
  "  o Special top speed aproximation     ",
  "     table renderer that takes         ",
  "     advantage of attributes and       ",
  "     supports dithering, antialiasing  ",
  "     8x8 or 8x16 vga font.             ",
  "  o Handles resizing on the fly        ",
  "                                       ",
  "                                       ",
  " NCURSES driver was done by Jan Hubicka",
  "              (C) 1997                 ",
};
#define UGLYTEXTSIZE (sizeof(helptext)/sizeof(char *))
static struct params params[] =
{
  {"-normal", P_SWITCH, supportedon + NORMAL, "Enable use of normal text"},
{"-nonormal", P_SWITCH, supportedoff + NORMAL, "Disable use of normal text"},
  {"-dim", P_SWITCH, supportedon + DIM, "Enable use of dim attribute(hlaf bright)"},
  {"-nodim", P_SWITCH, supportedon + DIM, "Disable use of dim attribute(hlaf bright)"},
  {"-bold", P_SWITCH, supportedon + BOLD, "Enable use of bold attribute(double bright)"},
  {"-nobold", P_SWITCH, supportedon + BOLD, "Disable use of bold attribute(double bright)"},
  {"-boldfont", P_SWITCH, supportedon + BOLDFONT, "Enable use of bold attribute(bold font)"},
  {"-noboldfont", P_SWITCH, supportedon + BOLDFONT, "Disable use of bold attribute(bold font)"},
{"-reverse", P_SWITCH, supportedon + REVERSE, "Enable use of reversed text"},
  {"-noreverse", P_SWITCH, supportedoff + REVERSE, "Disable use of reversed text"},
  {"-fontheight", P_NUMBER, &fontwidth, "Set font height(8 or 16)"},
  {NULL, 0, NULL, NULL}
};
struct ui_driver curses_driver =
{
  "curses",
  curses_init,
  curses_get_size,
  (void (*)(int, int *, int *, int *, int *)) curses_processevents,
  curses_getmouse,
  curses_uninitialise,
  curses_set_color,
  NULL,
  curses_print,
  curses_display,
  curses_alloc,
  curses_free,
  curses_flip_buffers,
  curses_clear,
  NULL,
  NULL,
  curses_refresh,
  2,
  2,
  helptext,
  UGLYTEXTSIZE,
  params,
  FULLSCREEN | UPDATE_AFTER_RESIZE | PALETTE_ROTATION | PALETTE_REDISPLAYS,
  0.0, 0.0,
  0, 0,
  UI_C256,
  1, 254, 253
};
#endif
