/*
 *   This is a curses implementation for Python.
 *
 *   Based on a prior work by Lance Ellinghaus
 *   (version 1.2 of this module
 *    Copyright 1994 by Lance Ellinghouse,
 *    Cathedral City, California Republic, United States of America.)
 *   Updated, fixed and heavily extended by Oliver Andrich
 *
 *   Copyright 1996 by Oliver Andrich,
 *   Koblenz, Germany
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this source file to use, copy, modify, merge, or publish it
 *   subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included
 *   in all copies or in any new file that contains a substantial portion of
 *   this file.
 *
 *   THE  AUTHOR  MAKES  NO  REPRESENTATIONS ABOUT  THE  SUITABILITY  OF
 *   THE  SOFTWARE FOR  ANY  PURPOSE.  IT IS  PROVIDED  "AS IS"  WITHOUT
 *   EXPRESS OR  IMPLIED WARRANTY.  THE AUTHOR DISCLAIMS  ALL WARRANTIES
 *   WITH  REGARD TO  THIS  SOFTWARE, INCLUDING  ALL IMPLIED  WARRANTIES
 *   OF   MERCHANTABILITY,  FITNESS   FOR  A   PARTICULAR  PURPOSE   AND
 *   NON-INFRINGEMENT  OF THIRD  PARTY  RIGHTS. IN  NO  EVENT SHALL  THE
 *   AUTHOR  BE LIABLE  TO  YOU  OR ANY  OTHER  PARTY  FOR ANY  SPECIAL,
 *   INDIRECT,  OR  CONSEQUENTIAL  DAMAGES  OR  ANY  DAMAGES  WHATSOEVER
 *   WHETHER IN AN  ACTION OF CONTRACT, NEGLIGENCE,  STRICT LIABILITY OR
 *   ANY OTHER  ACTION ARISING OUT OF  OR IN CONNECTION WITH  THE USE OR
 *   PERFORMANCE OF THIS SOFTWARE.
 */

/******************************************************************
This is a curses implementation. I have tried to be as complete
as possible. If there are functions you need that are not included,
please let me know and/or send me some diffs.

And for all of you who like to include there own functions; attr_t and 
chtype are types of curses.h and are defined as unsigned long, and please
use them as this, cause not everybody uses curses under *unix. :-)

There is 1 basic type exported by this module:
   Window - This is the basic type. This is equivalent to "WINDOW *".

Most of the routines can be looked up using the curses man page. But some
of the return values may differ from the return values of the curses 
functions. But all the return values are listed below. 

Description of the various argument types

bool:   a standard Python Int with value 1 or 0
ch:     a standard Python 1-element string (for intuitive use of the methods)
int:    a attributet character (= a Python int) 
        in order to get an "a" with a blink attribute you have to assign
        ord("a") | curses.A_BLINK to the parameter
        (more intuitive calls are also supported, look at addch("a",
        curses.A_BLINK). That means the same as addch(ord("a") | 
	curses.A_BLINK).
attr:   a Python int representing attributes
        to get a blinking reversed attribute assign 
	curses.A_BLINK | curses.A_REVERSE to the parameter
y,x:    Python ints representing coordinates
str:    a standard Python string

Here is a list of the currently supported methods and attributes
in the curses module:

Return Value      Func/Attr            Description/Manpage
--------------------------------------------------------------------------
IntObject         baudrate()           curs_termattrs
None              beep()               curs_beep
True/FalseObject  can_change_colors()  curs_color
None              cbreak()             curs_inopts
                  cbreak(bool)
(r,g,b)           color_content(int)   curs_color
                                       returns the RGB values of the color
                                       int
IntObject         COLORS               number of available colors
                                       (only available after start_color())
IntObject         COLOR_PAIR(int)      curs_color
                                       returns the value of the color pair
                                       int compiled from the values of for-
                                       and backgroundcolor
IntObject         COLOR_PAIRS          number of available color pairs
                                       (only available aftert start_color())
IntObject         curs_set(int)        curs_kernel
                                       sets the cursor visibility to value int
                                       allowed values 0, 1 and 2
                                       returns old value
None              def_prog_mode()      curs_kernel
None              def_shell_mode()     curs_kernel
None              doupdate()           curs_refresh
None              echo()               curs_inopts
                  echo(bool)            
None              endwin()             curs_initscr
StringObject      erasechar()          curs_termattrs
None              filter()             curs_util
None              flash()              curs_beep
None              flushinp()           curs_util
WindowObject      getwin(fileobj)      curs_util
True/FalseObject  has_colors()         curs_color
True/FalseObject  has_ic()             curs_termattrs
True/FalseOBject  has_il()             curs_termattrs
None              halfdelay(int)       curs_inopts (read manpage)
None              init_color(color, r, g, b) curs_color (read manpage)
None              init_pair(pair, fg, bg) curs_color (read manpage)
WindowObject      initscr()            curs_initscr
None              intrflush(bool)       curs_inopts
True/FalseObject  isendwin()           curs_initscr
StringObject      keyname(int)         curs_util
                                       return the text representation
                                       of a key_ value. (see below)
None              meta(bool)            curs_inopts
WindowObject      newpad(lines, cols)  curs_pad
WindowObject      newwin(lines,cols,y,x) curs_window
                  newwin(lines,cols)   curs_pad
		                       newwin/2 creates a pad, so that newwin
                                       similar to newpad
None              nl()                 curs_outopts
                  nl(bool)
None              nocbreak()           curs_inopts
None              noecho()             curs_inopts
None              nonl()               curs_outpots
None              noqiflush()         curs_inopts
None              noraw()              curs_inopts
(fg, bg)          pair_content(int)    curs_color
                                       returns fore- and backgroundcolor of
                                       color pair int
IntObject         PAIR_NUMBER(int)     curs_color
                                       returns the number of the colorpair with
                                       the value int
None              putp(str)            curs_terminfo
None              qiflush()            curs_inopts
                  qiflush(bool)
None              raw()                curs_inopts
                  raw(bool)
None              reset_prog_mode()    curs_kernel
None              reset_shell_mode()   curs_kernel
None              slk_attron(attr)     curs_slk
None              slk_attroff(attr)    curs_slk
None              slk_attrset(attr)    curs_slk
None              slk_clear()          curs_slk
None              slk_init(int)        curs_slk
StringObject      slk_label(int)       curs_slk
None              slk_noutrefresh()    curs_slk
None              slk_refresh()        curs_slk
None              slk_restore()        curs_slk
None              slk_set(int,str,int) curs_slk
None              slk_touch()          curs_slk
None              start_color()        curs_color
                                       initializes color support
IntObject         termattrs()          curs_termattrs
StringObject      termname()           curs_termattrs
StringObject      unctrl(ch)           curs_util
                  unctrl(int)
None              ungetch(int)         curs_getch
                                       Push the int back so next getch()
                                       will return it.
		  ungetch(ch)          Now also for chars.
None              use_env(bool)        curs_util
StringObject      version              A string representing the current
                                       version of this module.

Here is a list of the currently supported methods and attributes
in the WindowObject:

Return Value      Func/Attr            Description/Manpage
--------------------------------------------------------------------------
None              addch(y,x,int,attr)   curs_addch
                  addch(y,x,ch,attr)
		  addch(y,x,int)
                  addch(y,x,ch)
		  addch(int,attr)
		  addch(ch,attr)
		  addch(int)
		  addch(ch)
None              addnstr(y,x,str,n,attr) curs_addstr
                  addnstr(y,x,str,n)
		  addnstr(str,n,attr)
		  addnstr(str,n)
None              addstr(y,x,str,attr)  curs_addstr
                  addstr(y,x,str)
                  addstr(str,attr)
                  addstr(str)
None              attron(attr)         curs_attr
None              attroff(attr)        curs_attr
None              attrset(sttr)        curs_attr
None              bkgd(int)            curs_bkgd
                  bkgd(ch)
                  bkgd(int, attr)
		  bkgd(ch, attr)
None              bkgdset(int)            curs_bkgd
                  bkgdset(ch)
                  bkgdset(int, attr)
		  bkgdset(ch, attr)
None              border(ls,rs,ts,bs,tl,tr,bl,br) curs_border
                                       (accepts 0-8 int args)
None              box(vertch,horch)    curs_border
                                       vertch and horch are INTS
                  box()
None              clear()              curs_clear
None              clearok(bool)         curs_outopts
None              clrtobot()           curs_clear
None              clrtoeol()           curs_clear
None              cursyncup()          curs_window
None              delch(y,x)           curs_delch
                  delch()
None              deleteln()           curs_deleteln
WindowObject      derwin(nlines,ncols,begin_y,begin_x) curs_window
                  derwin(begin_y,begin_x)
None              echochar(ch,attr)    curs_addch
                  echochar(int,attr)
                  echochar(ch)
		  echochar(int)
None              erase()              curs_clear
(y,x)             getbegyx()           curs_getyx
IntObject         getbkgd()            curs_bkgd
IntObject         getch(y,x)           curs_getch
                  getch()
StringObject      getkey(y,x)          similar to getch, but returns a char
                  getkey()             or the keyname pressed
(y,x)             getmaxyx()           curs_getyx
(y,x)             getparyx()           curs_getyx
StringObject      getstr(y,x,n)        curs_getstr
                  getstr(y,x)          
                  getstr(n)            n is an int, max chars read
                  getstr()
(y,x)             getyx()              curs_getyx
None              hline(y,x,ch,n,attr) curs_border
                  hline(y,x,int,n,attr)
                  hline(y,x,ch,n)
		  hline(y,x,int,n)
		  hline(ch,n,attr)
		  hline(int,n,attr)
                  hline(ch,n)
		  hline(int,n)
None              idlok(bool)           curs_outopts
None              idcok(bool)           curs_outopts
None              immedok(bool)         curs_outopts
IntObject         inch(y,x)            curs_inch
                  inch()
None              insch(y,x,ch,attr)   curs_insch
                  insch(y,x,int,attr)
                  insch(y,x,ch)
		  insch(y,x,int)
                  insch(ch,attr)
		  insch(int, attr)
                  insch(ch)
		  insch(int)
None              insdelln(int)        curs_deleteln
None              insertln()           curs_deleteln
None              insnstr(y,x,str,n,attr) curs_insstr
                  insnstr(y,x,str,n)
		  insnstr(str,n,attr)
		  insnstr(str,n)
None              insstr(y,x,str,attr) curs_insstr
                  insstr(y,x,str)
		  insstr(str,attr)
		  insstr(str)
StringObject      instr(y,x,n)         curs_instr
                  instr(y,x)
		  instr(n)
		  instr()
True/FalseObject  is_linetouched(int)  curs_touch int = line
True/FalseObject  is_winwouched()      curs_touch
None              keypad(bool)          curs_inopts
None              leaveok(bool)         curs_outopts
None              move(new_y,new_x)    curs_move
                                       Move Cursor
None              mvwin(new_y,new_x)   curs_move
                                       Move Window
None              nodelay(bool)         curs_inopts
None              noutrefresh()       curs_refresh
                                       Mark for refresh but wait
None              notimeout(bool)       curs_inopts
None              putwin(fileobject)   curs_util
None              redrawln(beg, cnt)   curs_refresh
None              redrawwin()          curs_refresh
None              refresh()            curs_refresh
None              scroll()             curs_scroll
                  scroll(lines)        
None              scrollok(bool)        curs_outopts
None              setscrreg(top,bottom) curs_outopts
None              standend()           curs_attr
None              standout()           curs_attr    
WindowObject      subpad(nlines,ncols,begin_y,begin_x) curs_pad
WindowObject      subwin(nlines,ncols,begin_y,begin_x) curs_window
None              syncup               curs_window
None              syncdown             curs_window
None              syncok(bool)          curs_window
None              touchline(start,count) curs_touch
                  touchline(start, count, value) (= wtouchln)
None              touchwin()            curs_touch
None              vline(y,x,ch,n,attr) curs_border
                  vline(y,x,int,n,attr)
                  vline(y,x,ch,n)
		  vline(y,x,int,n)
		  vline(ch,n,attr)
		  vline(int,n,attr)
                  vline(ch,n)
		  vline(int,n)
******************************************************************/

/* curses module */

#include "Python.h"

#include <curses.h>

typedef struct {
	PyObject_HEAD
	WINDOW *win;
} PyCursesWindowObject;

/* staticforward PyTypeObject PyCursesWindow_Type; */
PyTypeObject PyCursesWindow_Type;

#define PyCursesWindow_Check(v)	 ((v)->ob_type == &PyCursesWindow_Type)

/* Defines */
static PyObject *PyCursesError;		/* For exception curses.error */

/* Catch-all error messages */
static char *catchall_ERR  = "curses function returned ERR";
static char *catchall_NULL = "curses function returned NULL";

/* Tells whether initscr() has been called to initialise curses  */
static int initialised = FALSE;

/* Tells whether start_color() has been called to initialise colors */
static int initialisedcolors = FALSE;

#define ARG_COUNT(X) \
	(((X) == NULL) ? 0 : (PyTuple_Check(X) ? PyTuple_Size(X) : 1))

/******************************************************************

Change Log:

Version 1.3b1: (Oliver Andrich, Oliver_Andrich@p103.bammbamm.fido.de)
    supports ncurses 1.9.8a
    added color support to ncurses
    add nearly all other functions except termcap/info support
    cleaned up some code
    made addch and so on a lot more flexible
    added pad support

Version 1.2: 95/02/23 (Steve Clift)
    Fixed several potential core-dumping bugs.
    Reworked arg parsing where variable arg lists are used.
    Generate exceptions when ERR or NULL is returned by curses functions.
    Changed return types to match SysV Curses manual descriptions.
    Added keypad() to window method list.
    Added border(), hline() and vline() window methods.

Version 1.1: 94/08/31:
    Minor fixes given by Guido.
    Changed 'ncurses' to 'curses'
    Changed '__version__' to 'version'
    Added PyErr_Clear() where needed
    Moved ACS_* attribute initialization to PyCurses_InitScr() to fix
        crash on SGI

Version 1.0: 94/08/30:
    This is the first release of this software.
    Released to the Internet via python-list@cwi.nl

******************************************************************/

char *PyCursesVersion = "1.3b2";

/*
 * Check the return code from a curses function and return None 
 * or raise an exception as appropriate.
 */

static PyObject *
PyCursesCheckERR(code, fname)
     int code;
     char *fname;
{
  char buf[100];

  if (code != ERR) {
    Py_INCREF(Py_None);
    return Py_None;
  } else {
    if (fname == NULL) {
      PyErr_SetString(PyCursesError, catchall_ERR);
    } else {
      strcpy(buf, fname);
      strcat(buf, "() returned ERR");
      PyErr_SetString(PyCursesError, buf);
    }
    return NULL;
  }
}

static int
PyCursesInitialised()
{
  if (initialised == TRUE)
    return 1;
  else {
    PyErr_SetString(PyCursesError, "must call initscr() first");
    return 0;
  }
}

static int
PyCursesInitialisedColor()
{
  if (initialisedcolors == TRUE)
    return 1;
  else {
    PyErr_SetString(PyCursesError, "must call start_color() first");
    return 0;
  }
}

int 
PyCurses_ConvertToChtype(obj, ch)
        PyObject *obj;
        chtype *ch;
{
  if (PyInt_Check(obj)) {
    *ch = (chtype) PyInt_AsLong(obj);
  } else if(PyString_Check(obj) &
	    (PyString_Size(obj) == 1)) {
    *ch = (chtype) *PyString_AsString(obj);
  } else 
    return 0;
  return 1;
}

/* ------------- WINDOW routines --------------- */

static PyObject *
PyCursesWindow_New(win)
	WINDOW *win;
{
	PyCursesWindowObject *wo;

	wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
	if (wo == NULL)
		return NULL;
	wo->win = win;
	return (PyObject *)wo;
}

static void
PyCursesWindow_Dealloc(wo)
	PyCursesWindowObject *wo;
{
  if (wo->win != stdscr)
    delwin(wo->win);
  PyMem_DEL(wo);
}

/* Addch, Addstr, Addnstr */

static PyObject *
PyCursesWindow_AddCh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn, x, y, use_xy = FALSE;
  PyObject *temp;
  chtype ch = 0;
  attr_t attr = A_NORMAL;
  
  switch (ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg, "O;ch or int", &temp))
      return NULL;
    break;
  case 2:
    if (!PyArg_Parse(arg, "(Ol);ch or int,attr", &temp, &attr))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(iiO);y,x,ch or int", &y, &x, &temp))
      return NULL;
    use_xy = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iiOl);y,x,ch or int, attr", 
		     &y, &x, &temp, &attr))
      return NULL;
    use_xy = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "addch requires 1 or 4 arguments");
    return NULL;
  }

  if (!PyCurses_ConvertToChtype(temp, &ch)) {
    PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
    return NULL;
  }
  
  if (use_xy == TRUE)
    rtn = mvwaddch(self->win,y,x, ch | attr);
  else {
    rtn = waddch(self->win, ch | attr);
  }
  return PyCursesCheckERR(rtn, "addch");
}

static PyObject *
PyCursesWindow_AddStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn;
  int x, y;
  char *str;
  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
  int use_xy = FALSE, use_attr = FALSE;

  switch (ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"s;str", &str))
      return NULL;
    break;
  case 2:
    if (!PyArg_Parse(arg,"(sl);str,attr", &str, &attr))
      return NULL;
    use_attr = TRUE;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(iis);int,int,str", &y, &x, &str))
      return NULL;
    use_xy = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iisl);int,int,str,attr", &y, &x, &str, &attr))
      return NULL;
    use_xy = use_attr = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments");
    return NULL;
  }

  if (use_attr == TRUE) {
    attr_old = getattrs(self->win);
    wattrset(self->win,attr);
  }
  if (use_xy == TRUE)
    rtn = mvwaddstr(self->win,y,x,str);
  else
    rtn = waddstr(self->win,str);
  if (use_attr == TRUE)
    wattrset(self->win,attr_old);
  return PyCursesCheckERR(rtn, "addstr");
}

static PyObject *
PyCursesWindow_AddNStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn, x, y, n;
  char *str;
  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
  int use_xy = FALSE, use_attr = FALSE;

  switch (ARG_COUNT(arg)) {
  case 2:
    if (!PyArg_Parse(arg,"(si);str,n", &str, &n))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(sil);str,n,attr", &str, &n, &attr))
      return NULL;
    use_attr = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iisi);y,x,str,n", &y, &x, &str, &n))
      return NULL;
    use_xy = TRUE;
    break;
  case 5:
    if (!PyArg_Parse(arg,"(iisil);y,x,str,n,attr", &y, &x, &str, &n, &attr))
      return NULL;
    use_xy = use_attr = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments");
    return NULL;
  }

  if (use_attr == TRUE) {
    attr_old = getattrs(self->win);
    wattrset(self->win,attr);
  }
  if (use_xy == TRUE)
    rtn = mvwaddnstr(self->win,y,x,str,n);
  else
    rtn = waddnstr(self->win,str,n);
  if (use_attr == TRUE)
    wattrset(self->win,attr_old);
  return PyCursesCheckERR(rtn, "addnstr");
}

static PyObject *
PyCursesWindow_AttrOn(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  wattron(self->win,attr);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_AttrOff(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  wattroff(self->win,attr);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_AttrSet(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  wattrset(self->win,attr);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_Bkgd(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  PyObject *temp;
  chtype bkgd;
  attr_t attr = A_NORMAL;

  switch (ARG_COUNT(arg)) {
    case 1:
      if (!PyArg_Parse(arg, "O;ch or int", &temp))
        return NULL;
      break;
    case 2:
      if (!PyArg_Parse(arg,"(Ol);ch or int,attr", &temp, &attr))
        return NULL;
      break;
    default:
      PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments");
      return NULL;
  }

  if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
    PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
    return NULL;
  }

  return PyCursesCheckERR(wbkgd(self->win, bkgd | A_NORMAL), "bkgd");
}

static PyObject *
PyCursesWindow_BkgdSet(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  PyObject *temp;
  chtype bkgd;
  attr_t attr = A_NORMAL;

  switch (ARG_COUNT(arg)) {
    case 1:
      if (!PyArg_Parse(arg, "O;ch or int", &temp))
        return NULL;
      break;
    case 2:
      if (!PyArg_Parse(arg,"(Ol);ch or int,attr", &temp, &attr))
        return NULL;
      break;
    default:
      PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments");
      return NULL;
  }

  if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
    PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
    return NULL;
  }

  return PyCursesCheckERR(wbkgdset(self->win, bkgd | attr), "bkgdset");
}

static PyObject *
PyCursesWindow_Border(self, args)
     PyCursesWindowObject *self;
     PyObject *args;
{
  chtype ls, rs, ts, bs, tl, tr, bl, br;
  ls = rs = ts = bs = tl = tr = bl = br = 0;
  if (!PyArg_Parse(args,"|llllllll;ls,rs,ts,bs,tl,tr,bl,br",
                        &ls, &rs, &ts, &bs, &tl, &tr, &bl, &br))
    return NULL;
  wborder(self->win, ls, rs, ts, bs, tl, tr, bl, br);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_Box(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  chtype ch1=0,ch2=0;
  if (!PyArg_NoArgs(arg)) {
    PyErr_Clear();
    if (!PyArg_Parse(arg,"(ll);vertint,horint", &ch1, &ch2))
      return NULL;
  }
  box(self->win,ch1,ch2);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_Clear(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wclear(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_ClearOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  clearok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_ClearToBottom(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wclrtobot(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_ClearToEOL(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wclrtoeol(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_CurSyncUp(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wcursyncup(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_DelCh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn;
  int x, y;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn = wdelch(self->win);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x", &y, &x))
      return NULL;
    rtn = mvwdelch(self->win,y,x);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments");
    return NULL;
  }
  return PyCursesCheckERR(rtn, "[mv]wdelch");
}

static PyObject *
PyCursesWindow_DeleteLine(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(wdeleteln(self->win), "deleteln");
}

static PyObject *
PyCursesWindow_DerWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  WINDOW *win;
  int nlines, ncols, begin_y, begin_x;

  nlines = 0;
  ncols  = 0;
  switch (ARG_COUNT(arg)) {
  case 2:
    if (!PyArg_Parse(arg,"(ii);begin_y,begin_x",&begin_y,&begin_x))
      return NULL;
    break;
  case 4:
    if (!PyArg_Parse(arg, "(iiii);nlines,ncols,begin_y,begin_x",
		   &nlines,&ncols,&begin_y,&begin_x))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments");
    return NULL;
  }

  win = derwin(self->win,nlines,ncols,begin_y,begin_x);

  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }

  return (PyObject *)PyCursesWindow_New(win);
}

static PyObject *
PyCursesWindow_EchoChar(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  PyObject *temp;
  chtype ch;
  attr_t attr = A_NORMAL;

  switch (ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"O;ch or int", &temp))
      return NULL;
    break;
  case 2:
    if (!PyArg_Parse(arg,"(Ol);ch or int,attr", &temp, &attr))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments");
    return NULL;
  }

  if (!PyCurses_ConvertToChtype(temp, &ch)) {
    PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
    return NULL;
  }
  
  if (self->win->_flags & _ISPAD)
    return PyCursesCheckERR(pechochar(self->win, ch | attr), 
			    "echochar");
  else
    return PyCursesCheckERR(wechochar(self->win, ch | attr), 
			    "echochar");
}

static PyObject *
PyCursesWindow_Erase(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  werase(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_GetBkgd(self, arg)
     PyCursesWindowObject *self;
     PyObject *arg;
{
  if (!PyArg_NoArgs(arg))
    return NULL;
  return PyInt_FromLong((long) self->win->_bkgd); /* was: wgetbkgd <chery@s2.org> */
}

static PyObject *
PyCursesWindow_GetYX(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_NoArgs(arg))
      return NULL;
  getyx(self->win,y,x);
  return Py_BuildValue("(ii)", y, x);
}

static PyObject *
PyCursesWindow_GetBegYX(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_NoArgs(arg))
      return NULL;
  getbegyx(self->win,y,x);
  return Py_BuildValue("(ii)", y, x);
}

static PyObject *
PyCursesWindow_GetMaxYX(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_NoArgs(arg))
      return NULL;
  getmaxyx(self->win,y,x);
  return Py_BuildValue("(ii)", y, x);
}

static PyObject *
PyCursesWindow_GetParYX(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_NoArgs(arg))
      return NULL;
  getparyx(self->win,y,x);
  return Py_BuildValue("(ii)", y, x);
}

static PyObject *
PyCursesWindow_GetCh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  chtype rtn;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn = wgetch(self->win);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x",&y,&x))
      return NULL;
    rtn = mvwgetch(self->win,y,x);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
    return NULL;
  }
  return PyInt_FromLong(rtn);
}

static PyObject *
PyCursesWindow_GetKey(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  chtype rtn;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn = wgetch(self->win);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x",&y,&x))
      return NULL;
    rtn = mvwgetch(self->win,y,x);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
    return NULL;
  }
  if (rtn<=255)
    return Py_BuildValue("c", rtn);
  else
    return PyString_FromString((char *)keyname(rtn));
}

static PyObject *
PyCursesWindow_GetStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y, n;
  char rtn[1024]; /* This should be big enough.. I hope */
  int rtn2;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn2 = wgetstr(self->win,rtn);
    break;
  case 1:
    if (!PyArg_Parse(arg,"i;n", &n))
      return NULL;
    rtn2 = wgetnstr(self->win,rtn,n);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x",&y,&x))
      return NULL;
    rtn2 = mvwgetstr(self->win,y,x,rtn);
    break;
  case 3:
    if (!PyArg_Parse(arg,"(iii);y,x,n", &y, &x, &n))
      return NULL;
    rtn2 = mvwgetnstr(self->win, y, x, rtn, n);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 2 arguments");
    return NULL;
  }
  if (rtn2 == ERR)
    rtn[0] = 0;
  return PyString_FromString(rtn);
}

static PyObject *
PyCursesWindow_Hline(self, args)
     PyCursesWindowObject *self;
     PyObject *args;
{
  PyObject *temp;
  chtype ch;
  int n, x, y, code = OK;
  attr_t attr = A_NORMAL;

  switch (ARG_COUNT(args)) {
  case 2:
    if (!PyArg_Parse(args, "(Oi);ch or int,n", &temp, &n))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(args, "(Oil);ch or int,n,attr", &temp, &n, &attr))
      return NULL;
    break;
  case 4:
    if (!PyArg_Parse(args, "(iiOi);y,x,ch o int,n", &y, &x, &temp, &n))
      return NULL;
    code = wmove(self->win, y, x);
    break;
  case 5:
    if (!PyArg_Parse(args, "(iiOil); y,x,ch or int,n,attr", 
		     &y, &x, &temp, &n, &attr))
      return NULL;
    code = wmove(self->win, y, x);
  default:
    PyErr_SetString(PyExc_TypeError, "hline requires 2 or 5 arguments");
    return NULL;
  }

  if (code != ERR) {
    if (!PyCurses_ConvertToChtype(temp, &ch)) {
      PyErr_SetString(PyExc_TypeError, 
		      "argument 1 or 3 must be a ch or an int");
      return NULL;
    }
    return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline");
  } else 
    return PyCursesCheckERR(code, "wmove");
}

static PyObject *
PyCursesWindow_InsCh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn, x, y, use_xy = FALSE;
  PyObject *temp;
  chtype ch = 0;
  attr_t attr = A_NORMAL;
  
  switch (ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg, "O;ch or int", &temp))
      return NULL;
    break;
  case 2:
    if (!PyArg_Parse(arg, "(Ol);ch or int,attr", &temp, &attr))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(iiO);y,x,ch or int", &y, &x, &temp))
      return NULL;
    use_xy = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iiOl);y,x,ch or int, attr", &y, &x, &temp, &attr))
      return NULL;
    use_xy = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "insch requires 1 or 4 arguments");
    return NULL;
  }

  if (!PyCurses_ConvertToChtype(temp, &ch)) {
    PyErr_SetString(PyExc_TypeError, 
		    "argument 1 or 3 must be a ch or an int");
    return NULL;
  }
  
  if (use_xy == TRUE)
    rtn = mvwinsch(self->win,y,x, ch | attr);
  else {
    rtn = winsch(self->win, ch | attr);
  }
  return PyCursesCheckERR(rtn, "insch");
}

static PyObject *
PyCursesWindow_InsDelLn(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int cnt;
  if (!PyArg_Parse(arg,"i;cnt", &cnt))
      return NULL;
  return PyCursesCheckERR(winsdelln(self->win, cnt), "insdelln");
}

static PyObject *
PyCursesWindow_InsertLine(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(winsertln(self->win), "insertln");
}

static PyObject *
PyCursesWindow_InCh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y, rtn;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn = winch(self->win);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x",&y,&x))
      return NULL;
    rtn = mvwinch(self->win,y,x);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments");
    return NULL;
  }
  return PyInt_FromLong((long) rtn);
}

static PyObject *
PyCursesWindow_IdlOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  idlok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_IdcOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  idcok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_ImmedOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  immedok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_InStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y, n;
  char rtn[1024]; /* This should be big enough.. I hope */
  int rtn2;

  switch (ARG_COUNT(arg)) {
  case 0:
    rtn2 = winstr(self->win,rtn);
    break;
  case 1:
    if (!PyArg_Parse(arg,"i;n", &n))
      return NULL;
    rtn2 = winnstr(self->win,rtn,n);
    break;
  case 2:
    if (!PyArg_Parse(arg,"(ii);y,x",&y,&x))
      return NULL;
    rtn2 = mvwinstr(self->win,y,x,rtn);
    break;
  case 3:
    if (!PyArg_Parse(arg, "(iii);y,x,n", &y, &x, &n))
      return NULL;
    rtn2 = mvwinnstr(self->win, y, x, rtn, n);
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
    return NULL;
  }
  if (rtn2 == ERR)
    rtn[0] = 0;
  return PyString_FromString(rtn);
}

static PyObject *
PyCursesWindow_InsStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn;
  int x, y;
  char *str;
  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
  int use_xy = FALSE, use_attr = FALSE;

  switch (ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"s;str", &str))
      return NULL;
    break;
  case 2:
    if (!PyArg_Parse(arg,"(sl);str,attr", &str, &attr))
      return NULL;
    use_attr = TRUE;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(iis);y,x,str", &y, &x, &str))
      return NULL;
    use_xy = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iisl);y,x,str,attr", &y, &x, &str, &attr))
      return NULL;
    use_xy = use_attr = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments");
    return NULL;
  }

  if (use_attr == TRUE) {
    attr_old = getattrs(self->win);
    wattrset(self->win,attr);
  }
  if (use_xy == TRUE)
    rtn = mvwinsstr(self->win,y,x,str);
  else
    rtn = winsstr(self->win,str);
  if (use_attr == TRUE)
    wattrset(self->win,attr_old);
  return PyCursesCheckERR(rtn, "insstr");
}

static PyObject *
PyCursesWindow_InsNStr(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int rtn, x, y, n;
  char *str;
  attr_t attr = A_NORMAL , attr_old = A_NORMAL;
  int use_xy = FALSE, use_attr = FALSE;

  switch (ARG_COUNT(arg)) {
  case 2:
    if (!PyArg_Parse(arg,"(si);str,n", &str, &n))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(arg,"(sil);str,n,attr", &str, &n, &attr))
      return NULL;
    use_attr = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg,"(iisi);y,x,str,n", &y, &x, &str, &n))
      return NULL;
    use_xy = TRUE;
    break;
  case 5:
    if (!PyArg_Parse(arg,"(iisil);y,x,str,n,attr", &y, &x, &str, &n, &attr))
      return NULL;
    use_xy = use_attr = TRUE;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments");
    return NULL;
  }

  if (use_attr == TRUE) {
    attr_old = getattrs(self->win);
    wattrset(self->win,attr);
  }
  if (use_xy == TRUE)
    rtn = mvwinsnstr(self->win,y,x,str,n);
  else
    rtn = winsnstr(self->win,str,n);
  if (use_attr == TRUE)
    wattrset(self->win,attr_old);
  return PyCursesCheckERR(rtn, "insnstr");
}

static PyObject *
PyCursesWindow_Is_LineTouched(self,arg)
     PyCursesWindowObject * self;
     PyObject * arg;
{
  int line, erg;
  if (!PyArg_Parse(arg,"i;line", &line))
    return NULL;
  erg = is_linetouched(self->win, line);
  if (erg == ERR) {
    PyErr_SetString(PyExc_TypeError, 
		    "is_linetouched: line number outside of boundaries");
    return NULL;
  } else 
    if (erg == FALSE) {
      Py_INCREF(Py_False);
      return Py_False;
    } else {
      Py_INCREF(Py_True);
      return Py_True;
    }
}

static PyObject *
PyCursesWindow_Is_WinTouched(self,arg)
     PyCursesWindowObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
    return NULL;
  if (is_wintouched(self->win) == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCursesWindow_KeyPad(self,arg)
     PyCursesWindowObject * self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1), False(0)",&val))
    return NULL;
  keypad(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_LeaveOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  leaveok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_MoveWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_Parse(arg,"(ii);y,x", &y, &x))
    return NULL;
  return PyCursesCheckERR(mvwin(self->win,y,x), "mvwin");
}

static PyObject *
PyCursesWindow_MoveDerWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_Parse(arg,"(ii);y,x", &y, &x))
    return NULL;
  return PyCursesCheckERR(mvderwin(self->win,y,x), "mvderwin");
}

static PyObject *
PyCursesWindow_Move(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_Parse(arg,"(ii);y,x", &y, &x))
    return NULL;
  return PyCursesCheckERR(wmove(self->win,y,x), "wmove");
}

static PyObject *
PyCursesWindow_NoDelay(self,arg)
     PyCursesWindowObject * self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1), False(0)",&val))
    return NULL;
  nodelay(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_NoTimeout(self,arg)
     PyCursesWindowObject * self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1), False(0)",&val))
    return NULL;
  notimeout(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_NoOutRefresh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;

  if (self->win->_flags & _ISPAD) {
    switch(ARG_COUNT(arg)) {
    case 6:
      if (!PyArg_Parse(arg, 
		       "(iiiiii);" \
		       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", 
		       &pminrow, &pmincol, &sminrow, 
		       &smincol, &smaxrow, &smaxcol))
	return NULL;
      return PyCursesCheckERR(prefresh(self->win,
				       pminrow, pmincol, sminrow, 
				       smincol, smaxrow, smaxcol),
			      "pnoutrefresh");
    default:
      PyErr_SetString(PyCursesError, 
		      "noutrefresh was called for a pad;" \
		      "requires 6 arguments");
      return NULL;
    }
  } else {
    if (!PyArg_NoArgs(arg))
      return NULL;    
    return PyCursesCheckERR(wnoutrefresh(self->win), "wnoutrefresh");
  }
}

static PyObject *
PyCursesWindow_PutWin(self, arg)
     PyCursesWindowObject *self;
     PyObject *arg;
{
  PyObject *temp;
  
  if (!PyArg_Parse(arg, "O;fileobj", &temp))
    return NULL;
  if (!PyFile_Check(temp)) {
    PyErr_SetString(PyExc_TypeError, "argument must be a file object");
    return NULL;
  }
  return PyCursesCheckERR(putwin(self->win, PyFile_AsFile(temp)), 
			  "putwin");
}

static PyObject *
PyCursesWindow_RedrawLine(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int beg, num;
  if (!PyArg_Parse(arg,"(ii);beg,num", &beg, &num))
    return NULL;
  return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
}

static PyObject *
PyCursesWindow_RedrawWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(redrawwin(self->win), "redrawwin");
}

static PyObject *
PyCursesWindow_Refresh(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
  
  if (self->win->_flags & _ISPAD) {
    switch(ARG_COUNT(arg)) {
    case 6:
      if (!PyArg_Parse(arg, 
		       "(iiiiii);" \
		       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", 
		       &pminrow, &pmincol, &sminrow, 
		       &smincol, &smaxrow, &smaxcol))
	return NULL;
      return PyCursesCheckERR(prefresh(self->win,
				       pminrow, pmincol, sminrow, 
				       smincol, smaxrow, smaxcol),
			      "prefresh");
    default:
      PyErr_SetString(PyCursesError, 
		      "refresh was called for a pad; requires 6 arguments");
      return NULL;
    }
  } else {
    if (!PyArg_NoArgs(arg))
      return NULL;    
    return PyCursesCheckERR(wrefresh(self->win), "wrefresh");
  }
}

static PyObject *
PyCursesWindow_ScrollOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  scrollok(self->win,val);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_SetScrollRegion(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int x, y;
  if (!PyArg_Parse(arg,"(ii);top, bottom",&y,&x))
    return NULL;
  return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg");
}

static PyObject *
PyCursesWindow_StandEnd(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wstandend(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_StandOut(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wstandout(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_SubWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  WINDOW *win;
  int nlines, ncols, begin_y, begin_x;

  if (!PyArg_Parse(arg, "(iiii);nlines,ncols,begin_y,begin_x",
		   &nlines,&ncols,&begin_y,&begin_x))
    return NULL;

  if (self->win->_flags & _ISPAD)
    win = subpad(self->win, nlines, ncols, begin_y, begin_x);
  else
    win = subwin(self->win,nlines,ncols,begin_y,begin_x);

  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }
  
  return (PyObject *)PyCursesWindow_New(win);
}

static PyObject *
PyCursesWindow_Scroll(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int lines;
  switch(ARG_COUNT(arg)) {
  case 0:
    return PyCursesCheckERR(scroll(self->win), "scroll");
    break;
  case 1:
    if (!PyArg_Parse(arg, "i;lines", &lines))
      return NULL;
    return PyCursesCheckERR(wscrl(self->win, lines), "scroll");
  default:
    PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments");
    return NULL;
  }
}

static PyObject *
PyCursesWindow_SyncUp(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wsyncup(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_SyncDown(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  wsyncdown(self->win);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCursesWindow_SyncOk(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int val;
  if (!PyArg_Parse(arg,"i;True(1) or False(0)",&val))
    return NULL;
  return PyCursesCheckERR(syncok(self->win,val), "syncok");
}

static PyObject *
PyCursesWindow_TouchLine(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  int st, cnt, val;
  switch (ARG_COUNT(arg)) {
  case 2:
    if (!PyArg_Parse(arg,"(ii);start,count",&st,&cnt))
      return NULL;
    return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline");
    break;
  case 3:
    if (!PyArg_Parse(arg, "(iii);start,count,val", &st, &cnt, &val))
      return NULL;
    return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline");
  default:
    PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments");
    return NULL;
  }
}

static PyObject *
PyCursesWindow_TouchWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(touchwin(self->win), "touchwin");
}

static PyObject *
PyCursesWindow_UnTouchWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(untouchwin(self->win), "touchwin");
}

static PyObject *
PyCursesWindow_Vline(self, args)
     PyCursesWindowObject *self;
     PyObject *args;
{
  PyObject *temp;
  chtype ch;
  int n, x, y, code = OK;
  attr_t attr = A_NORMAL;

  switch (ARG_COUNT(args)) {
  case 2:
    if (!PyArg_Parse(args, "(Oi);ch or int,n", &temp, &n))
      return NULL;
    break;
  case 3:
    if (!PyArg_Parse(args, "(Oil);ch or int,n,attr", &temp, &n, &attr))
      return NULL;
    break;
  case 4:
    if (!PyArg_Parse(args, "(iiOi);y,x,ch o int,n", &y, &x, &temp, &n))
      return NULL;
    code = wmove(self->win, y, x);
    break;
  case 5:
    if (!PyArg_Parse(args, "(iiOil); y,x,ch or int,n,attr", 
		     &y, &x, &temp, &n, &attr))
      return NULL;
    code = wmove(self->win, y, x);
  default:
    PyErr_SetString(PyExc_TypeError, "vline requires 2 or 5 arguments");
    return NULL;
  }

  if (code != ERR) {
    if (!PyCurses_ConvertToChtype(temp, &ch)) {
      PyErr_SetString(PyExc_TypeError, 
		      "argument 1 or 3 must be a ch or an int");
      return NULL;
    }
    return PyCursesCheckERR(whline(self->win, ch | attr, n), "vline");
  } else
    return PyCursesCheckERR(code, "wmove");
}

static PyMethodDef PyCursesWindow_Methods[] = {
	{"addch",           (PyCFunction)PyCursesWindow_AddCh},
	{"addnstr",         (PyCFunction)PyCursesWindow_AddNStr},
	{"addstr",          (PyCFunction)PyCursesWindow_AddStr},
	{"attron",          (PyCFunction)PyCursesWindow_AttrOn},
	{"attroff",         (PyCFunction)PyCursesWindow_AttrOff},
	{"attrset",         (PyCFunction)PyCursesWindow_AttrSet},
	{"bkgd",            (PyCFunction)PyCursesWindow_Bkgd},
	{"bkgdset",         (PyCFunction)PyCursesWindow_BkgdSet},
	{"border",          (PyCFunction)PyCursesWindow_Border, METH_VARARGS},
	{"box",             (PyCFunction)PyCursesWindow_Box},
	{"clear",           (PyCFunction)PyCursesWindow_Clear},
	{"clearok",         (PyCFunction)PyCursesWindow_ClearOk},
	{"clrtobot",        (PyCFunction)PyCursesWindow_ClearToBottom},
	{"clrtoeol",        (PyCFunction)PyCursesWindow_ClearToEOL},
	{"cursyncup",       (PyCFunction)PyCursesWindow_CurSyncUp},
	{"delch",           (PyCFunction)PyCursesWindow_DelCh},
	{"deleteln",        (PyCFunction)PyCursesWindow_DeleteLine},
	{"derwin",          (PyCFunction)PyCursesWindow_DerWin},
	{"echochar",        (PyCFunction)PyCursesWindow_EchoChar},
	{"erase",           (PyCFunction)PyCursesWindow_Erase},
	{"getbegyx",        (PyCFunction)PyCursesWindow_GetBegYX},
	{"getbkgd",         (PyCFunction)PyCursesWindow_GetBkgd},
	{"getch",           (PyCFunction)PyCursesWindow_GetCh},
	{"getkey",          (PyCFunction)PyCursesWindow_GetKey},
	{"getmaxyx",        (PyCFunction)PyCursesWindow_GetMaxYX},
	{"getparyx",        (PyCFunction)PyCursesWindow_GetParYX},
	{"getstr",          (PyCFunction)PyCursesWindow_GetStr},
	{"getyx",           (PyCFunction)PyCursesWindow_GetYX},
	{"hline",           (PyCFunction)PyCursesWindow_Hline},
	{"idlok",           (PyCFunction)PyCursesWindow_IdlOk},
	{"idcok",           (PyCFunction)PyCursesWindow_IdcOk},
	{"immedok",         (PyCFunction)PyCursesWindow_ImmedOk},
	{"inch",            (PyCFunction)PyCursesWindow_InCh},
	{"insch",           (PyCFunction)PyCursesWindow_InsCh},
	{"insdelln",        (PyCFunction)PyCursesWindow_InsDelLn},
	{"insertln",        (PyCFunction)PyCursesWindow_InsertLine},
	{"insnstr",         (PyCFunction)PyCursesWindow_InsNStr},
	{"insstr",          (PyCFunction)PyCursesWindow_InsStr},
	{"instr",           (PyCFunction)PyCursesWindow_InStr},
	{"is_linetouched",  (PyCFunction)PyCursesWindow_Is_LineTouched},
	{"is_wintouched",   (PyCFunction)PyCursesWindow_Is_WinTouched},
	{"keypad",          (PyCFunction)PyCursesWindow_KeyPad},
	{"leaveok",         (PyCFunction)PyCursesWindow_LeaveOk},
	{"move",            (PyCFunction)PyCursesWindow_Move},
	{"mvwin",           (PyCFunction)PyCursesWindow_MoveWin},
	{"mvderwin",        (PyCFunction)PyCursesWindow_MoveDerWin},
	{"nodelay",         (PyCFunction)PyCursesWindow_NoDelay},
	{"noutrefresh",     (PyCFunction)PyCursesWindow_NoOutRefresh},
	{"notimeout",       (PyCFunction)PyCursesWindow_NoTimeout},
	{"putwin",          (PyCFunction)PyCursesWindow_PutWin},
	{"redrawwin",       (PyCFunction)PyCursesWindow_RedrawWin},
	{"redrawln",        (PyCFunction)PyCursesWindow_RedrawLine},
	{"refresh",         (PyCFunction)PyCursesWindow_Refresh},
	{"scroll",          (PyCFunction)PyCursesWindow_Scroll},
	{"scrollok",        (PyCFunction)PyCursesWindow_ScrollOk},
	{"setscrreg",       (PyCFunction)PyCursesWindow_SetScrollRegion},
	{"standend",        (PyCFunction)PyCursesWindow_StandEnd},
	{"standout",        (PyCFunction)PyCursesWindow_StandOut},
	{"subpad",          (PyCFunction)PyCursesWindow_SubWin},
	{"subwin",          (PyCFunction)PyCursesWindow_SubWin},
	{"syncdown",        (PyCFunction)PyCursesWindow_SyncDown},
	{"syncok",          (PyCFunction)PyCursesWindow_SyncOk},
	{"syncup",          (PyCFunction)PyCursesWindow_SyncUp},
	{"touchline",       (PyCFunction)PyCursesWindow_TouchLine},
	{"touchwin",        (PyCFunction)PyCursesWindow_TouchWin},
	{"untouchwin",      (PyCFunction)PyCursesWindow_UnTouchWin},
	{"vline",           (PyCFunction)PyCursesWindow_Vline},
	{NULL,		        NULL}   /* sentinel */
};

static PyObject *
PyCursesWindow_GetAttr(self, name)
	PyCursesWindowObject *self;
	char *name;
{
  return Py_FindMethod(PyCursesWindow_Methods, (PyObject *)self, name);
}

/* -------------------------------------------------------*/

PyTypeObject PyCursesWindow_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,			/*ob_size*/
	"curses window",	/*tp_name*/
	sizeof(PyCursesWindowObject),	/*tp_basicsize*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)PyCursesWindow_GetAttr, /*tp_getattr*/
	(setattrfunc)0, /*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};

/* ------------------- SLK Functions -------------------- */
static PyObject *
PyCurses_Slk_AttrOn(self,arg)
     PyObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  return PyCursesCheckERR(slk_attron(attr), "slk_attron");
}

static PyObject *
PyCurses_Slk_AttrOff(self,arg)
     PyObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  return PyCursesCheckERR(slk_attroff(attr), "slk_attroff");
}

static PyObject *
PyCurses_Slk_AttrSet(self,arg)
     PyObject *self;
     PyObject * arg;
{
  attr_t attr;
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"l;attr", &attr))
      return NULL;
  return PyCursesCheckERR(slk_attrset(attr), "slk_attrset");
}

static PyObject *
PyCurses_Slk_Clear(self,arg)
     PyObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  if (!PyArg_NoArgs(arg))
      return NULL;
  return PyCursesCheckERR(slk_clear(), "slk_clear");
}

static PyObject *
PyCurses_Slk_Init(self,arg)
     PyObject *self;
     PyObject * arg;
{
  int fmt;
  if (!PyArg_Parse(arg,"i;int", &fmt))
      return NULL;
#ifndef NO_BOUNDS_CHECK
  if ((fmt=0) || (fmt=1))
#endif
    return PyCursesCheckERR(slk_init(fmt), "slk_init");
#ifndef NO_BOUNDS_CHECK
  else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 was out of range. (0..1)");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Slk_Label(self,arg)
     PyObject *self;
     PyObject * arg;
{
  int labnum;
  char *erg;
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"i;int", &labnum))
      return NULL;
#ifndef NO_BOUNDS_CHECK
  if ((labnum>0) && (labnum<=8)) {
#endif
    erg = slk_label(labnum);
    if (erg != NULL) 
      return PyString_FromString(erg);
    else 
      return PyString_FromString("");
#ifndef NO_BOUNDS_CHECK
  } else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 was out of range. (1..8)");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Slk_NoOutRefresh(self,arg)
     PyObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(slk_noutrefresh(), "slk_noutrefresh");
}

static PyObject *
PyCurses_Slk_Refresh(self,arg)
     PyObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(slk_refresh(), "slk_refresh");
}

static PyObject *
PyCurses_Slk_Restore(self,arg)
     PyObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(slk_restore(), "slk_restore");
}

static PyObject *
PyCurses_Slk_Set(self,arg)
     PyObject *self;
     PyObject * arg;
{
  int labnum, fmt;
  char *label; 
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"(isi);int, str, int", &labnum, &label, &fmt))
    return NULL;
#ifndef NO_BOUNDS_CHECK
  if ((labnum>0) && (labnum<=8)) {
    if ((fmt>=0) && (fmt<=2)) {
#endif
      return PyCursesCheckERR(slk_set(labnum, label, fmt), "slk_set");
#ifndef NO_BOUNDS_CHECK
    } else {
      PyErr_SetString(PyCursesError,
		      "Argument 3 is out of range. (0..2)");
      return NULL;
    }
  } else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 is out of range. (1..8)");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Slk_Touch(self,arg)
     PyObject *self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(slk_touch(), "slk_touch");
}

/* -------------------------------------------------------*/

static PyObject *ModDict;

static PyObject *
PyCurses_BaudRate(self, arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyInt_FromLong((long) baudrate());
}

static PyObject *
PyCurses_Beep(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(beep(), "beep");
}

static PyObject *
PyCurses_CanChangeColor(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  if (can_change_color() == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCurses_CBreak(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int flag = 0;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 0:
    return PyCursesCheckERR(cbreak(), "cbreak");
    break;
  case 1:
    if (!PyArg_Parse(arg, "i;True(1) or False(0)", &flag))
      return NULL;
    if (flag)
      return PyCursesCheckERR(cbreak(), "cbreak");
    else
      return PyCursesCheckERR(nocbreak(), "cbreak");
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "cbreak requires 0 or 1 argument");
    return NULL;
  }
}

static PyObject *
PyCurses_Color_Content(self, arg)
     PyObject * self;
     PyObject * arg;
{
  short color,r,g,b;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  if (ARG_COUNT(arg) == 1) {
    if (!PyArg_Parse(arg, "h;color", &color))
      return NULL;
  } else {
    PyErr_SetString(PyExc_TypeError, 
		    "color_content requires 1 argument");
    return NULL;
  }
  if (color_content(color, &r, &g, &b) != ERR)
    return Py_BuildValue("(iii)", r, g, b);
  else {
    PyErr_SetString(PyCursesError, 
		    "Argument 1 was out of range. Check value of COLORS.");
    return NULL;
  }
}

static PyObject *
PyCurses_COLOR_PAIR(self, arg)
     PyObject * self;
     PyObject * arg;
{
  int n;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  if (ARG_COUNT(arg)==1) {
    if (!PyArg_Parse(arg, "i;number", &n))
      return NULL;
  } else {
    PyErr_SetString(PyExc_TypeError, "COLOR_PAIR requires 1 argument");
    return NULL;
  }
  return PyInt_FromLong((long) (n << 8));
}

static PyObject *
PyCurses_Curs_Set(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int vis, erg;
  if (!PyCursesInitialised())
    return NULL;
  if (ARG_COUNT(arg)==1) {
    if (!PyArg_Parse(arg, "i;int", &vis) || !PyCursesInitialised())
      return NULL;
  } else {
    PyErr_SetString(PyExc_TypeError, "curs_set requires 1 argument");
    return NULL;
  }
#ifndef NO_BOUNDS_CHECK
  if ((vis >= 0) && (vis <= 2)) {
#endif
    erg = curs_set(vis);
    if (erg == ERR)
      return PyCursesCheckERR(erg, "curs_set");
    return PyInt_FromLong((long) erg);
#ifndef NO_BOUNDS_CHECK
  } else {
    PyErr_SetString(PyCursesError, 
		    "Argument 1 was out of range. Must be of 0, 1 or 2.");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Def_Prog_Mode(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(def_prog_mode(), "def_prog_mode");
}

static PyObject *
PyCurses_Def_Shell_Mode(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(def_shell_mode(), "def_shell_mode");
}

static PyObject *
PyCurses_Delay_Output(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int ms;
  if (!PyCursesInitialised())
    return NULL;
  if (ARG_COUNT(arg)==1) {
    if (!PyArg_Parse(arg, "i;ms", &ms))
      return NULL;
  } else {
    PyErr_SetString(PyExc_TypeError, "delay_output requires 1 argument");
    return NULL;
  }
  return PyCursesCheckERR(delay_output(ms), "delay_output");
}

static PyObject *
PyCurses_DoUpdate(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(doupdate(), "doupdate");
}

static PyObject *
PyCurses_Echo(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int flag = 0;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 0:
    return PyCursesCheckERR(echo(), "echo");
    break;
  case 1:
    if (!PyArg_Parse(arg, "i;True(1) or False(0)", &flag))
      return NULL;
    if (flag)
      return PyCursesCheckERR(echo(), "echo");
    else
      return PyCursesCheckERR(noecho(), "echo");
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "echo requires 0 or 1 argument");
    return NULL;
  }
}

static PyObject * 
PyCurses_EndWin(self, args)
     PyObject * self;
     PyObject * args;
{
  if (!PyArg_NoArgs(args) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(endwin(), "endwin");
}

static PyObject *
PyCurses_EraseChar(self,arg)
     PyObject * self;
     PyObject * arg;
{
  char ch;
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  ch = erasechar();
  return PyString_FromString(&ch);
}

static PyObject *
PyCurses_Filter(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  filter();
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCurses_Flash(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(flash(), "flash");
}

static PyObject *
PyCurses_FlushInp(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  flushinp();
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCurses_GetWin(self,arg)
     PyCursesWindowObject *self;
     PyObject * arg;
{
  WINDOW *win;
  PyObject *temp;

  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg, "O;fileobj", &temp))
    return NULL;
  if (!PyFile_Check(temp)) {
    PyErr_SetString(PyExc_TypeError, "argument must be a file object");
    return NULL;
  }
  win = getwin(PyFile_AsFile(temp));
  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }
  return PyCursesWindow_New(win);
}

static PyObject *
PyCurses_Has_Colors(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  if (has_colors() == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCurses_Has_Ic(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  if (has_ic() == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCurses_Has_Il(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  if (has_il() == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCurses_HalfDelay(self,arg)
     PyObject * self;
     PyObject * arg;
{
  unsigned char tenths;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg, "b;tenths", &tenths) || !PyCursesInitialised())
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError,
                    "halfdelay requires 1 argument");
    return NULL;
  }
#ifndef NO_BOUNDS_CHECKS
  if ((tenths>=1) && (tenths<=255))
#endif
    return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
#ifndef NO_BOUNDS_CHECKS
  else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 was out of range. 1 <= tenths <=255");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Init_Color(self, arg)
     PyObject * self;
     PyObject * arg;
{
  short color, r, g, b;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 4:
    if (!PyArg_Parse(arg, "(hhhh);color,r,g,b", &color, &r, &g, &b))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError,
                    "init_color requires 4 arguments");
    return NULL;
  }
#ifndef NO_BOUNDS_CHECK
  if ((color>=0) && (color<=COLORS)) {
    if ((r>=0) && (r<=1000) && (g>=0) && (g<=1000) && (b>=0) && (b<=1000))
#endif
      return PyCursesCheckERR(init_color(color, r, g, b), "init_color");
#ifndef NO_BOUNDS_CHECK
    else {
      PyErr_SetString(PyCursesError, 
		      "One RGB value is out of range. (0..1000)");
      return NULL;
    }
  } else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 is out of range. (0..COLORS)");
    return NULL;
  }
#endif
}

static PyObject *
PyCurses_Init_Pair(self, arg)
     PyObject * self;
     PyObject * arg;
{
  short pair, f, b;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  if (ARG_COUNT(arg) == 3) {
    if (!PyArg_Parse(arg, "(hhh);pair, f, b", &pair, &f, &b))
      return NULL;
  } else {
    PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments");
    return NULL;
  }
#ifndef NO_BOUNDS_CHECK
  if ((pair>=0) && (pair<COLOR_PAIRS)) {
    if ((f>=0) && (f<=COLORS) && (b>=0) && (b<=COLORS))
#endif
      return PyCursesCheckERR(init_pair(pair, f, b), "init_pair");
#ifndef NO_BOUNDS_CHECK
    else {
      PyErr_SetString(PyCursesError, 
		      "One color value is out of range. (0..COLORS)");
      return NULL;
    }
  } else {
    PyErr_SetString(PyCursesError,
		    "Argument 1 is out of range. (0..COLOR_PAIRS-1)");
    return NULL;
  }
#endif
}

static PyObject * 
PyCurses_InitScr(self, args)
     PyObject * self;
     PyObject * args;
{
  WINDOW *win;
  PyObject *lines, *cols;
  if (!PyArg_NoArgs(args))
    return NULL;
  if (initialised == TRUE) {
    wrefresh(stdscr);
    return (PyObject *)PyCursesWindow_New(stdscr);
  }

  win = initscr();
  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }

  initialised = TRUE;

  lines = PyInt_FromLong((long) LINES);
  PyDict_SetItemString(ModDict, "LINES", lines);
  Py_DECREF(lines);
  cols = PyInt_FromLong((long) COLS);
  PyDict_SetItemString(ModDict, "COLS", cols);
  Py_DECREF(cols);

/* This was moved from initcurses() because core dumped on SGI */
/* Also, they are probably not defined until you've called initscr() */
#define SetDictInt(string,ch) \
	PyDict_SetItemString(ModDict,string,PyInt_FromLong((long) (ch)));
 
        SetDictInt("ACS_ULCORNER",(ACS_ULCORNER));
	SetDictInt("ACS_LLCORNER",(ACS_LLCORNER));
	SetDictInt("ACS_URCORNER",(ACS_URCORNER));
	SetDictInt("ACS_LRCORNER",(ACS_LRCORNER));
	SetDictInt("ACS_RTEE",    (ACS_RTEE));
	SetDictInt("ACS_LTEE",    (ACS_LTEE));
	SetDictInt("ACS_BTEE",    (ACS_BTEE));
	SetDictInt("ACS_TTEE",    (ACS_TTEE));
	SetDictInt("ACS_HLINE",   (ACS_HLINE));
	SetDictInt("ACS_VLINE",   (ACS_VLINE));
	SetDictInt("ACS_PLUS",    (ACS_PLUS));
	SetDictInt("ACS_S1",      (ACS_S1));
#ifndef NC194       
	SetDictInt("ACS_S3",      (ACS_S3));
	SetDictInt("ACS_S7",      (ACS_S7));
#endif
	SetDictInt("ACS_S9",      (ACS_S9));
	SetDictInt("ACS_DIAMOND", (ACS_DIAMOND));
	SetDictInt("ACS_CKBOARD", (ACS_CKBOARD));
	SetDictInt("ACS_DEGREE",  (ACS_DEGREE));
	SetDictInt("ACS_PLMINUS", (ACS_PLMINUS));
	SetDictInt("ACS_BULLET",  (ACS_BULLET));
	SetDictInt("ACS_LARROW",  (ACS_LARROW));
	SetDictInt("ACS_RARROW",  (ACS_RARROW));
	SetDictInt("ACS_DARROW",  (ACS_DARROW));
	SetDictInt("ACS_UARROW",  (ACS_UARROW));
	SetDictInt("ACS_BOARD",   (ACS_BOARD));
	SetDictInt("ACS_LANTERN", (ACS_LANTERN));
	SetDictInt("ACS_BLOCK",   (ACS_BLOCK));
#ifndef NC194
	SetDictInt("ACS_LEQUAL",  (ACS_LEQUAL));
	SetDictInt("ACS_GEQUAL",  (ACS_GEQUAL));
	SetDictInt("ACS_PI",      (ACS_PI));
	SetDictInt("ACS_NEQUAL",  (ACS_NEQUAL));
	SetDictInt("ACS_STERLING",(ACS_STERLING));
#endif
  return (PyObject *)PyCursesWindow_New(win);
}

static PyObject *
PyCurses_IntrFlush(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int ch;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"i;True(1), False(0)",&ch)) 
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError,
                    "intrflush requires 1 argument");
    return NULL;
  }
  return PyCursesCheckERR(intrflush(NULL,ch), "intrflush");
}

static PyObject * 
PyCurses_IsEndWin(self, args)
     PyObject * self;
     PyObject * args;
{
  if (!PyArg_NoArgs(args))
    return NULL;
  if (isendwin() == FALSE) {
    Py_INCREF(Py_False);
    return Py_False;
  }
  Py_INCREF(Py_True);
  return Py_True;
}

static PyObject *
PyCurses_KeyName(self,arg)
     PyObject * self;
     PyObject * arg;
{
  const char *knp;
  int ch;
  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"i",&ch))
    return NULL;
  knp = keyname(ch);
  return PyString_FromString((knp == NULL) ? "" : (char *)knp);
}

static PyObject *  
PyCurses_KillChar(self,arg)  
PyObject * self;  
PyObject * arg;  
{  
  char ch;  
  if (!PyArg_NoArgs(arg))  
    return NULL;  
  ch = killchar();  
  return PyString_FromString(&ch);  
}  

static PyObject *  
PyCurses_Longname(self,arg)  
PyObject * self;  
PyObject * arg;  
{  
  if (!PyArg_NoArgs(arg))  
    return NULL;  
  return PyString_FromString(longname());  
}  

static PyObject *
PyCurses_Meta(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int ch;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"i;True(1), False(0)",&ch))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "meta requires 1 argument");
    return NULL;
  }
  return PyCursesCheckERR(meta(stdscr, ch), "meta");
}

static PyObject *
PyCurses_NewPad(self,arg)
     PyObject * self;
     PyObject * arg;
{
  WINDOW *win;
  int nlines, ncols;

  if (!PyCursesInitialised() || 
      !PyArg_Parse(arg,"(ii);nlines,ncols",&nlines,&ncols))
    return NULL;

  win = newpad(nlines, ncols);
  
  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }

  return (PyObject *)PyCursesWindow_New(win);
}

static PyObject *
PyCurses_NewWindow(self,arg)
     PyObject * self;
     PyObject * arg;
{
  WINDOW *win;
  int nlines, ncols, begin_y, begin_x;
  char create_pad = FALSE;

  if (!PyCursesInitialised())
    return NULL;
  switch (ARG_COUNT(arg)) {
  case 2:
    if (!PyArg_Parse(arg,"(ii);nlines,ncols",&nlines,&ncols))
      return NULL;
    create_pad = TRUE;
    break;
  case 4:
    if (!PyArg_Parse(arg, "(iiii);nlines,ncols,begin_y,begin_x",
		   &nlines,&ncols,&begin_y,&begin_x))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments");
    return NULL;
  }

  if (create_pad)
    win = newpad(nlines, ncols);
  else
    win = newwin(nlines,ncols,begin_y,begin_x);

  if (win == NULL) {
    PyErr_SetString(PyCursesError, catchall_NULL);
    return NULL;
  }

  return (PyObject *)PyCursesWindow_New(win);
}

static PyObject *
PyCurses_Nl(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int flag = 0;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 0:
    return PyCursesCheckERR(nl(), "nl");
    break;
  case 1:
    if (!PyArg_Parse(arg, "i;True(1) or False(0)", &flag))
      return NULL;
    if (flag)
      return PyCursesCheckERR(nl(), "nl");
    else
      return PyCursesCheckERR(nonl(), "nl");
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "nl requires 0 or 1 argument");
    return NULL;
  }
}

static PyObject *
PyCurses_NoCBreak(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(nocbreak(), "nocbreak");
}

static PyObject *
PyCurses_NoEcho(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(noecho(), "noecho");
}

static PyObject *
PyCurses_NoNl(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(nonl(), "nonl");
}

static PyObject *
PyCurses_NoQiFlush(self, arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  noqiflush();
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *
PyCurses_NoRaw(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(noraw(), "noraw");
}

static PyObject *
PyCurses_Pair_Content(self, arg)
     PyObject * self;
     PyObject * arg;
{
  short pair,f,b;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg, "h;pair", &pair))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError,
                    "pair_content requires 1 argument");
    return NULL;
  }
  if (!pair_content(pair, &f, &b)) {
    PyErr_SetString(PyCursesError, 
		    "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
    return NULL;
  }
  return Py_BuildValue("(ii)", f, b);
}

static PyObject *
PyCurses_PAIR_NUMBER(self, arg)
     PyObject * self;
     PyObject * arg;
{
  int n;
  if (!PyCursesInitialised() || !PyCursesInitialisedColor())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg, "i;pairvalue", &n))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError,
                    "PAIR_NUMBER requires 1 argument");
    return NULL;
  }
  return PyInt_FromLong((long) ((n & A_COLOR) >> 8));
}

static PyObject *
PyCurses_Putp(self,arg)
     PyObject *self;
     PyObject *arg;
{
  char *str;

  if (!PyArg_Parse(arg,"s;str", &str))
     return NULL;
  return PyCursesCheckERR(putp(str), "putp");
}

static PyObject *
PyCurses_QiFlush(self, arg)
     PyObject * self;
     PyObject * arg;
{
  int flag = 0;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 0:
    qiflush();
    Py_INCREF(Py_None);
    return Py_None;
  case 1:
    if (!PyArg_Parse(arg, "i;True(1) or False(0)", &flag))
      return NULL;
    if (flag) {
      qiflush();
      Py_INCREF(Py_None);
      return Py_None;
    } else {
      noqiflush();
      Py_INCREF(Py_None);
      return Py_None;
    }
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "nl requires 0 or 1 argument");
    return NULL;
  }
}

static PyObject *
PyCurses_Raw(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int flag = 0;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 0:
    return PyCursesCheckERR(raw(), "raw");
    break;
  case 1:
    if (!PyArg_Parse(arg, "i;True(1) or False(0)", &flag))
      return NULL;
    if (flag)
      return PyCursesCheckERR(raw(), "raw");
    else
      return PyCursesCheckERR(noraw(), "raw");
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "raw requires 0 or 1 argument");
    return NULL;
  }
}

static PyObject *
PyCurses_Reset_Prog_Mode(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(reset_prog_mode(), "reset_prog_mode");
}

static PyObject *
PyCurses_Reset_Shell_Mode(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyCursesCheckERR(reset_shell_mode(), "reset_shell_mode");
}

/* Addition by Teemu Kalvas <chery@s2.org> */
static PyObject *
PyCurses_Resizeterm(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int nlines, ncols;

  if (!PyCursesInitialised())
    return NULL;
  if (!PyArg_Parse(arg,"(ii);nlines,ncols",&nlines,&ncols))
    return NULL;
  return Py_BuildValue("i", resizeterm(nlines, ncols));
}

static PyObject *
PyCurses_Start_Color(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int code;
  PyObject *c, *cp;
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  
  code = start_color();
  if (code != ERR) {
    initialisedcolors = TRUE;
    c = PyInt_FromLong((long) COLORS);
    PyDict_SetItemString(ModDict, "COLORS", c);
    Py_DECREF(c);
    cp = PyInt_FromLong((long) COLOR_PAIRS);
    PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp);
    Py_DECREF(cp);
    Py_INCREF(Py_None);
    return Py_None;
  } else {
    PyErr_SetString(PyCursesError, "start_color() returned ERR");
    return NULL;
  }
}

static PyObject *
PyCurses_Termattrs(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyInt_FromLong(termattrs());
}

static PyObject *
PyCurses_Termname(self,arg)
     PyObject * self;
     PyObject * arg;
{
  if (!PyArg_NoArgs(arg) || !PyCursesInitialised())
    return NULL;
  return PyString_FromString(termname());
}

static PyObject *
PyCurses_UnCtrl(self,arg)
     PyObject * self;
     PyObject * arg;
{
  PyObject *temp;
  chtype ch;

  if (!PyArg_Parse(arg,"O;ch or int",&temp) || !PyCursesInitialised())
    return NULL;
  if (PyInt_Check(temp))
    ch = (chtype) PyInt_AsLong(temp);
  else if (PyString_Check(temp))
    ch = (chtype) *PyString_AsString(temp);
  else {
    PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
    return NULL;
  }
  return PyString_FromString(unctrl(ch));
}

static PyObject *
PyCurses_UngetCh(self,arg)
     PyObject * self;
     PyObject * arg;
{
  PyObject *temp;
  chtype ch;

  if (!PyArg_Parse(arg,"O;ch or int",&temp) || !PyCursesInitialised())
    return NULL;
  if (PyInt_Check(temp))
    ch = (chtype) PyInt_AsLong(temp);
  else if (PyString_Check(temp))
    ch = (chtype) *PyString_AsString(temp);
  else {
    PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
    return NULL;
  }
  return PyCursesCheckERR(ungetch(ch), "ungetch");
}

static PyObject *
PyCurses_Use_Env(self,arg)
     PyObject * self;
     PyObject * arg;
{
  int flag;
  if (!PyCursesInitialised())
    return NULL;
  switch(ARG_COUNT(arg)) {
  case 1:
    if (!PyArg_Parse(arg,"i;True(1), False(0)",&flag))
      return NULL;
    break;
  default:
    PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument");
    return NULL;
  }
  use_env(flag);
  Py_INCREF(Py_None);
  return Py_None;
}

/* List of functions defined in the module */

static PyMethodDef PyCurses_methods[] = {
  {"baudrate",            (PyCFunction)PyCurses_BaudRate},
  {"beep",                (PyCFunction)PyCurses_Beep},
  {"can_change_color",    (PyCFunction)PyCurses_CanChangeColor},
  {"cbreak",              (PyCFunction)PyCurses_CBreak},
  {"color_content",       (PyCFunction)PyCurses_Color_Content},
  {"COLOR_PAIR",          (PyCFunction)PyCurses_COLOR_PAIR},
  {"curs_set",            (PyCFunction)PyCurses_Curs_Set},
  {"def_prog_mode",       (PyCFunction)PyCurses_Def_Prog_Mode},
  {"def_shell_mode",      (PyCFunction)PyCurses_Def_Shell_Mode},
  {"delay_output",        (PyCFunction)PyCurses_Delay_Output},
  {"doupdate",            (PyCFunction)PyCurses_DoUpdate},
  {"endwin",              (PyCFunction)PyCurses_EndWin},
  {"echo",                (PyCFunction)PyCurses_Echo},
  {"erasechar",           (PyCFunction)PyCurses_EraseChar},
  {"filter",              (PyCFunction)PyCurses_Filter},
  {"flash",               (PyCFunction)PyCurses_Flash},
  {"flushinp",            (PyCFunction)PyCurses_FlushInp},
  {"getwin",              (PyCFunction)PyCurses_GetWin},
  {"has_colors",          (PyCFunction)PyCurses_Has_Colors},
  {"has_ic",              (PyCFunction)PyCurses_Has_Ic},
  {"has_il",              (PyCFunction)PyCurses_Has_Il},
  {"halfdelay",           (PyCFunction)PyCurses_HalfDelay},
  {"init_color",          (PyCFunction)PyCurses_Init_Color},
  {"init_pair",           (PyCFunction)PyCurses_Init_Pair},
  {"initscr",             (PyCFunction)PyCurses_InitScr},
  {"intrflush",           (PyCFunction)PyCurses_IntrFlush},
  {"isendwin",            (PyCFunction)PyCurses_IsEndWin},
  {"keyname",             (PyCFunction)PyCurses_KeyName},
  {"killchar",            (PyCFunction)PyCurses_KillChar}, 
  {"longname",            (PyCFunction)PyCurses_Longname}, 
  {"meta",                (PyCFunction)PyCurses_Meta},
  {"newpad",              (PyCFunction)PyCurses_NewPad},
  {"newwin",              (PyCFunction)PyCurses_NewWindow},
  {"nl",                  (PyCFunction)PyCurses_Nl},
  {"nocbreak",            (PyCFunction)PyCurses_NoCBreak},
  {"noecho",              (PyCFunction)PyCurses_NoEcho},
  {"nonl",                (PyCFunction)PyCurses_NoNl},
  {"noqiflush",           (PyCFunction)PyCurses_NoQiFlush},
  {"noraw",               (PyCFunction)PyCurses_NoRaw},
  {"pair_content",        (PyCFunction)PyCurses_Pair_Content},
  {"PAIR_NUMBER",         (PyCFunction)PyCurses_PAIR_NUMBER},
  {"putp",                (PyCFunction)PyCurses_Putp},
  {"qiflush",             (PyCFunction)PyCurses_QiFlush},
  {"raw",                 (PyCFunction)PyCurses_Raw},
  {"reset_prog_mode",     (PyCFunction)PyCurses_Reset_Prog_Mode},
  {"reset_shell_mode",    (PyCFunction)PyCurses_Reset_Shell_Mode},
  {"resizeterm",          (PyCFunction)PyCurses_Resizeterm},
  {"slk_attron",          (PyCFunction)PyCurses_Slk_AttrOn},
  {"slk_attroff",         (PyCFunction)PyCurses_Slk_AttrOff},
  {"slk_attrset",         (PyCFunction)PyCurses_Slk_AttrSet},
  {"slk_clear",           (PyCFunction)PyCurses_Slk_Clear},
  {"slk_init",            (PyCFunction)PyCurses_Slk_Init},
  {"slk_label",           (PyCFunction)PyCurses_Slk_Label},
  {"slk_noutrefresh",     (PyCFunction)PyCurses_Slk_NoOutRefresh},
  {"slk_refresh",         (PyCFunction)PyCurses_Slk_Refresh},
  {"slk_restore",         (PyCFunction)PyCurses_Slk_Restore},
  {"slk_set",             (PyCFunction)PyCurses_Slk_Set},
  {"slk_touch",           (PyCFunction)PyCurses_Slk_Touch},
  {"start_color",         (PyCFunction)PyCurses_Start_Color},
  {"termattrs",           (PyCFunction)PyCurses_Termattrs},
  {"termname",            (PyCFunction)PyCurses_Termname},
  {"unctrl",              (PyCFunction)PyCurses_UnCtrl},
  {"ungetch",             (PyCFunction)PyCurses_UngetCh},
  {"use_env",             (PyCFunction)PyCurses_Use_Env},
  {NULL,		NULL}		/* sentinel */
};

/* Initialization function for the module */

void
initcurses()
{
	PyObject *m, *d, *v;

	/* Create the module and add the functions */
	m = Py_InitModule("curses", PyCurses_methods);

	/* Add some symbolic constants to the module */
	d = PyModule_GetDict(m);
	ModDict = d; /* For PyCurses_InitScr */

	/* For exception curses.error */
	PyCursesError = PyString_FromString("curses.error");
	PyDict_SetItemString(d, "error", PyCursesError);

	/* Make the version available */
	v = PyString_FromString(PyCursesVersion);
	PyDict_SetItemString(d, "version", v);
	PyDict_SetItemString(d, "__version__", v);
	Py_DECREF(v);

	/* Here are some attributes you can add to chars to print */
	
	SetDictInt("A_ATTRIBUTES",      A_ATTRIBUTES);
	SetDictInt("A_NORMAL",		A_NORMAL);
	SetDictInt("A_STANDOUT",	A_STANDOUT);
	SetDictInt("A_UNDERLINE",	A_UNDERLINE);
	SetDictInt("A_REVERSE",		A_REVERSE);
	SetDictInt("A_BLINK",		A_BLINK);
	SetDictInt("A_DIM",		A_DIM);
	SetDictInt("A_BOLD",		A_BOLD);
	SetDictInt("A_ALTCHARSET",	A_ALTCHARSET);
	SetDictInt("A_INVIS",           A_INVIS);
	SetDictInt("A_PROTECT",         A_PROTECT);
	SetDictInt("A_HORIZONTAL",      A_HORIZONTAL);
	SetDictInt("A_LEFT",            A_LEFT);
	SetDictInt("A_LOW",             A_LOW);
	SetDictInt("A_RIGHT",           A_RIGHT);
	SetDictInt("A_TOP",             A_TOP);
	SetDictInt("A_VERTICAL",        A_VERTICAL);
	SetDictInt("A_CHARTEXT",        A_CHARTEXT);
	SetDictInt("A_COLOR",           A_COLOR);
	SetDictInt("WA_ATTRIBUTES",     WA_ATTRIBUTES);
	SetDictInt("WA_NORMAL",		WA_NORMAL);
	SetDictInt("WA_STANDOUT",	WA_STANDOUT);
	SetDictInt("WA_UNDERLINE",	WA_UNDERLINE);
	SetDictInt("WA_REVERSE",	WA_REVERSE);
	SetDictInt("WA_BLINK",		WA_BLINK);
	SetDictInt("WA_DIM",		WA_DIM);
	SetDictInt("WA_BOLD",		WA_BOLD);
	SetDictInt("WA_ALTCHARSET",	WA_ALTCHARSET);
	SetDictInt("WA_INVIS",          WA_INVIS);
	SetDictInt("WA_PROTECT",        WA_PROTECT);
	SetDictInt("WA_HORIZONTAL",     WA_HORIZONTAL);
	SetDictInt("WA_LEFT",           WA_LEFT);
	SetDictInt("WA_LOW",            WA_LOW);
	SetDictInt("WA_RIGHT",          WA_RIGHT);
	SetDictInt("WA_TOP",            WA_TOP);
	SetDictInt("WA_VERTICAL",       WA_VERTICAL);
	SetDictInt("COLOR_BLACK",       COLOR_BLACK);
	SetDictInt("COLOR_RED",         COLOR_RED);
	SetDictInt("COLOR_GREEN",       COLOR_GREEN);
	SetDictInt("COLOR_YELLOW",      COLOR_YELLOW);
	SetDictInt("COLOR_BLUE",        COLOR_BLUE);
	SetDictInt("COLOR_MAGENTA",     COLOR_MAGENTA);
	SetDictInt("COLOR_CYAN",        COLOR_CYAN);
	SetDictInt("COLOR_WHITE",       COLOR_WHITE);

	/* Now set everything up for KEY_ variables */
	{
	  int key;
	  char *key_n;
	  char *key_n2;
	  for (key=KEY_MIN;key < KEY_MAX; key++) {
	    key_n = (char *)keyname(key);
	    if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
	      continue;
	    if (strncmp(key_n,"KEY_F(",6)==0) {
	      char *p1, *p2;
	      key_n2 = malloc(strlen(key_n)+1);
	      p1 = key_n;
	      p2 = key_n2;
	      while (*p1) {
		if (*p1 != '(' && *p1 != ')') {
		  *p2 = *p1;
		  p2++;
		}
		p1++;
	      }
	      *p2 = (char)0;
	    } else
	      key_n2 = key_n;
	    PyDict_SetItemString(d,key_n2,PyInt_FromLong((long) key));
	    if (key_n2 != key_n)
	      free(key_n2);
	  }
	  SetDictInt("KEY_MIN", KEY_MIN);
	  SetDictInt("KEY_MAX", KEY_MAX);
	}

	/* Check for errors */
	if (PyErr_Occurred())
		Py_FatalError("can't initialize module curses");
}
