/* Curses.c
**
** Copyright (c) 1994-2000 William Setzer
**
** You may distribute under the terms of either the Artistic License
** or the GNU General Public License, as specified in the README file.
*/
#include "CursesDef.h"
#include "CursesTyp.h"
#include "c-config.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifndef C_PANELSUPPORT
# define PANEL int
#endif
#ifndef C_MENUSUPPORT
# define MENU int
# define ITEM int
#endif
#ifndef C_FORMSUPPORT
# define FORM int
# define FIELD int
#endif
#ifdef __PDCURSES__
#undef SP
#endif
/* What a mess. :( */
#ifndef PERL_VERSION
# define PL_sv_undef sv_undef
# define PL_sv_yes sv_yes
# define PL_na na
#endif
/*
** Begin support variables and functions
*/
static char *c_function;
static int c_win, c_x, c_arg;
static void
c_countargs(fn, nargs, base)
char *fn;
int nargs;
int base;
{
switch (nargs - base)
{
case 0: c_win = 0; c_x = 0; c_arg = 0; break;
case 1: c_win = 1; c_x = 0; c_arg = 1; break;
case 2: c_win = 0; c_x = 1; c_arg = 2; break;
case 3: c_win = 1; c_x = 2; c_arg = 3; break;
default:
croak("Curses function '%s' called with too %s arguments", fn,
nargs < base ? "few" : "many");
}
c_function = fn;
}
static void
c_exactargs(fn, nargs, base)
char *fn;
int nargs;
int base;
{
if (nargs != base)
croak("Curses function '%s' called with too %s arguments", fn,
nargs < base ? "few" : "many" );
c_function = fn;
}
static int
c_domove(win, sv_y, sv_x)
WINDOW *win;
SV *sv_y;
SV *sv_x;
{
int y = (int)SvIV(sv_y);
int x = (int)SvIV(sv_x);
return wmove(win, y, x);
}
static void
c_fun_not_there(fn)
char *fn;
{
croak("Curses function '%s' is not defined by your vendor", fn);
}
static void
c_var_not_there(fn)
char *fn;
{
croak("Curses variable '%s' is not defined by your vendor", fn);
}
static void
c_con_not_there(fn)
char *fn;
{
croak("Curses constant '%s' is not defined by your vendor", fn);
}
/*
** Begin complex type conversion routines
*/
static chtype
c_sv2chtype(sv)
SV *sv;
{
if (SvPOK(sv)) {
char *tmp = SvPV(sv,PL_na);
return (chtype)(unsigned char)tmp[0];
}
return (chtype)SvIV(sv);
}
static void
c_chtype2sv(sv, ch)
SV *sv;
chtype ch;
{
if (ch == ERR || ch > 255) { sv_setiv(sv, (I32)ch); }
else {
char tmp[2];
tmp[0] = (char)ch;
tmp[1] = (char)0;
sv_setpv(sv, tmp);
}
}
static FIELD *
c_sv2field(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Field")) { return (FIELD *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses field",
argnum, c_function);
else
croak("argument is not a Curses field");
}
static void
c_field2sv(sv, val)
SV *sv;
FIELD *val;
{
sv_setref_pv(sv, "Curses::Field", (void*)val);
}
static FORM *
c_sv2form(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Form")) { return (FORM *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses form",
argnum, c_function);
else
croak("argument is not a Curses form");
}
static void
c_form2sv(sv, val)
SV *sv;
FORM *val;
{
sv_setref_pv(sv, "Curses::Form", (void*)val);
}
static ITEM *
c_sv2item(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Item")) { return (ITEM *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses item",
argnum, c_function);
else
croak("argument is not a Curses item");
}
static void
c_item2sv(sv, val)
SV *sv;
ITEM *val;
{
sv_setref_pv(sv, "Curses::Item", (void*)val);
}
static MENU *
c_sv2menu(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Menu")) { return (MENU *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses menu",
argnum, c_function);
else
croak("argument is not a Curses menu");
}
static void
c_menu2sv(sv, val)
SV *sv;
MENU *val;
{
sv_setref_pv(sv, "Curses::Menu", (void*)val);
}
static PANEL *
c_sv2panel(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Panel")) { return (PANEL *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses panel",
argnum, c_function);
else
croak("argument is not a Curses panel");
}
static void
c_panel2sv(sv, val)
SV *sv;
PANEL *val;
{
sv_setref_pv(sv, "Curses::Panel", (void*)val);
}
static SCREEN *
c_sv2screen(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Screen")) { return (SCREEN *)SvIV((SV*)SvRV(sv)); }
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses screen",
argnum, c_function);
else
croak("argument is not a Curses screen");
}
static void
c_screen2sv(sv, val)
SV *sv;
SCREEN *val;
{
sv_setref_pv(sv, "Curses::Screen", (void*)val);
}
static WINDOW *
c_sv2window(sv, argnum)
SV *sv;
int argnum;
{
if (sv_isa(sv, "Curses::Window")) {
WINDOW *ret = (WINDOW *)SvIV((SV*)SvRV(sv));
return ret;
}
if (argnum >= 0)
croak("argument %d to Curses function '%s' is not a Curses window",
argnum, c_function);
else
croak("argument is not a Curses window");
}
static void
c_window2sv(sv, val)
SV *sv;
WINDOW *val;
{
sv_setref_pv(sv, "Curses::Window", (void*)val);
}
static void
c_setchar(sv, name)
SV *sv;
char *name;
{
int len = SvLEN(sv);
if (len > 0) {
name[len - 1] = 0;
SvCUR(sv) = strlen(name);
SvPOK_only(sv);
*SvEND(sv) = 0;
}
}
static void
c_setchtype(sv, name)
SV *sv;
chtype *name;
{
int n = 0;
int rs = sizeof(chtype);
int len = SvLEN(sv);
if (len - len % rs > rs) { /* find even multiple of rs */
name[len - len % rs - rs] = 0;
while (*name++) { n++; }
SvCUR(sv) = n;
SvPOK_only(sv);
*(chtype *)SvEND(sv) = 0;
}
}
static void
c_setmevent(sv)
SV *sv;
{
SvCUR(sv) = sizeof(MEVENT);
SvPOK_only(sv);
}
/*
** Cheesy, I know. But it works.
*/
#include "CursesFun.c"
#include "CursesVar.c"
#include "CursesCon.c"
#include "CursesBoot.c"