294 lines
7.2 KiB
C
294 lines
7.2 KiB
C
/*
|
|
* $Id$
|
|
*
|
|
Copyright (c) 2014-2017 Chung, Hyung-Hwan. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
|
|
#include "_con.h"
|
|
#include <moo-utl.h>
|
|
|
|
#include <string.h>
|
|
|
|
#if defined(_WIN32)
|
|
# include <windows.h>
|
|
#elif defined(__DOS__)
|
|
|
|
#else
|
|
# include <unistd.h>
|
|
# include <fcntl.h>
|
|
# include <stdlib.h> /* getenv */
|
|
# include <curses.h>
|
|
# include <term.h>
|
|
# include <sys/ioctl.h>
|
|
#endif
|
|
|
|
typedef struct console_t console_t;
|
|
struct console_t
|
|
{
|
|
int fd;
|
|
int fd_opened;
|
|
char* cup;
|
|
char* clear;
|
|
};
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static moo_pfrc_t pf_open (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|
{
|
|
#if defined(_WIN32)
|
|
HANDLE h;
|
|
moo_ooi_t immv;
|
|
|
|
h = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
if (h == INVALID_HANDLE_VALUE) return 0;
|
|
if (h == NULL)
|
|
{
|
|
/* the program doens't have an associated handle for stdin. is it a service? */
|
|
}
|
|
|
|
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(h));
|
|
|
|
#elif defined(__DOS__)
|
|
moo->errnum = MOO_ENOIMPL;
|
|
return -1;
|
|
#else
|
|
|
|
console_t* con;
|
|
int err;
|
|
char* term;
|
|
|
|
con = (console_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
|
|
if (isatty(1))
|
|
{
|
|
con->fd = 1;
|
|
}
|
|
else
|
|
{
|
|
con->fd = open("/dev/tty", O_RDWR, 0);
|
|
if (con->fd == -1)
|
|
{
|
|
/* TODO: failed to open /dev/stdout */
|
|
moo_freemem (moo, con);
|
|
return 0;
|
|
}
|
|
|
|
con->fd_opened = 1;
|
|
}
|
|
|
|
term = getenv("TERM");
|
|
if (term && setupterm(term, con->fd, &err) == OK)
|
|
{
|
|
}
|
|
|
|
con->cup = tigetstr("cup"); /* TODO: error check */
|
|
con->clear = tigetstr("clear");
|
|
|
|
#if 0
|
|
{
|
|
const char* cup, * clear;
|
|
struct winsize wsz;
|
|
|
|
cup = tigetstr ("cup");
|
|
clear = tigetstr ("clear");
|
|
ioctl (fd, TIOCGWINSZ, &wsz);
|
|
|
|
write (fd, clear, strlen(clear));
|
|
/*write (fd, tparm (cup, wsz.ws_row - 1, 0), strlen(tparm (cup, wsz.ws_row - 1, 0)));*/
|
|
/*write (fd, tiparm (cup, 0, 0), strlen(tiparm (cup, 0, 0)));*/
|
|
write (fd, tparm (cup, 0, 0, 0, 0, 0, 0, 0, 0, 0), strlen(tparm (cup, 0, 0, 0, 0, 0, 0, 0, 0, 0)));
|
|
}
|
|
#endif
|
|
|
|
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(con->fd));
|
|
#endif
|
|
return MOO_PF_SUCCESS;
|
|
}
|
|
|
|
static moo_pfrc_t pf_close (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|
{
|
|
#if defined(_WIN32)
|
|
moo_oop_t arg;
|
|
HANDLE h;
|
|
|
|
con = MOO_STACK_GETARG(moo, nargs, 0);
|
|
h = MOO_OOP_TO_SMPTR(con);
|
|
|
|
/*if (h != XXX)
|
|
{
|
|
CloseHandle (h);
|
|
}*/
|
|
#elif defined(__DOS__)
|
|
|
|
/* TODO */
|
|
|
|
#else
|
|
console_t* con;
|
|
|
|
con = (console_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
|
|
if (con->fd_opened) close (con->fd);
|
|
|
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
|
return MOO_PF_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
static moo_pfrc_t pf_write (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|
{
|
|
#if defined(_WIN32)
|
|
/* TODO: */
|
|
#elif defined(__DOS__)
|
|
/* TODO: */
|
|
#else
|
|
console_t* con;
|
|
moo_oop_char_t msg;
|
|
|
|
moo_oow_t ucspos, ucsrem, ucslen, bcslen;
|
|
moo_bch_t bcs[1024];
|
|
int n;
|
|
|
|
con = (console_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
msg = (moo_oop_char_t)MOO_STACK_GETARG (moo, nargs, 0);
|
|
|
|
if (!MOO_OBJ_IS_CHAR_POINTER(msg)) goto einval;
|
|
|
|
#if defined(MOO_OOCH_IS_UCH)
|
|
ucspos = 0;
|
|
ucsrem = MOO_OBJ_GET_SIZE(msg);
|
|
while (ucsrem > 0)
|
|
{
|
|
ucslen = ucsrem;
|
|
bcslen = MOO_COUNTOF(bcs);
|
|
if ((n = moo_convootobchars(moo, &msg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1)
|
|
{
|
|
if (n != -2 || ucslen <= 0) return MOO_PF_HARD_FAILURE;
|
|
}
|
|
|
|
write (con->fd, bcs, bcslen); /* TODO: error handling */
|
|
/* TODO: abort looping for async processing???? */
|
|
ucspos += ucslen;
|
|
ucsrem -= ucslen;
|
|
}
|
|
#else
|
|
write (con->fd, MOO_OBJ_GET_CHAR_SLOT(msg), MOO_OBJ_GET_SIZE(msg)); /* TODO: error handling. incomplete write handling */
|
|
#endif
|
|
|
|
MOO_STACK_SETRETTORCV (moo, nargs); /* TODO: change return code */
|
|
return MOO_PF_SUCCESS;
|
|
|
|
einval:
|
|
MOO_STACK_SETRETTOERRNUM (moo, nargs); /* TODO: be more specific about the error code */
|
|
return MOO_PF_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
static moo_pfrc_t pf_clear (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|
{
|
|
#if defined(_WIN32)
|
|
#elif defined(__DOS__)
|
|
|
|
#else
|
|
console_t* con;
|
|
|
|
con = (console_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
|
|
write (con->fd, con->clear, strlen(con->clear));
|
|
|
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
|
return MOO_PF_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
static moo_pfrc_t pf_setcursor (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|
{
|
|
#if defined(_WIN32)
|
|
#elif defined(__DOS__)
|
|
|
|
#else
|
|
console_t* con;
|
|
moo_oop_t x, y;
|
|
char* cup;
|
|
|
|
con = (console_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
x = MOO_STACK_GETARG(moo, nargs, 0);
|
|
y = MOO_STACK_GETARG(moo, nargs, 1);
|
|
|
|
if (!MOO_OOP_IS_SMOOI(x) || !MOO_OOP_IS_SMOOI(y)) goto einval;
|
|
|
|
/*cup = tiparm (con->cup, MOO_OOP_TO_SMOOI(y), MOO_OOP_TO_SMOOI(x));*/
|
|
cup = tparm (con->cup, MOO_OOP_TO_SMOOI(y), MOO_OOP_TO_SMOOI(x), 0, 0, 0, 0, 0, 0, 0);
|
|
write (con->fd, cup, strlen(cup)); /* TODO: error check */
|
|
|
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
|
return MOO_PF_SUCCESS;
|
|
|
|
einval:
|
|
MOO_STACK_SETRETTOERRNUM (moo, nargs); /* TODO: be more specific about the error code */
|
|
return MOO_PF_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
#define C MOO_METHOD_CLASS
|
|
#define I MOO_METHOD_INSTANCE
|
|
|
|
static moo_pfinfo_t pfinfos[] =
|
|
{
|
|
{ I, "clear", { pf_clear, 0, 0 } },
|
|
{ I, "close", { pf_close, 0, 0 } },
|
|
{ I, "open", { pf_open, 0, 0 } },
|
|
{ I, "setcursor", { pf_setcursor, 2, 2 } },
|
|
{ I, "write", { pf_write, 1, 1 } }
|
|
};
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
|
|
{
|
|
if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(console_t), MOO_NULL) <= -1) return -1;
|
|
return 0;
|
|
}
|
|
|
|
static moo_pfbase_t* querypf (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen)
|
|
{
|
|
return moo_findpfbase(moo, pfinfos, MOO_COUNTOF(pfinfos), name, namelen);
|
|
}
|
|
|
|
|
|
static void unload (moo_t* moo, moo_mod_t* mod)
|
|
{
|
|
/* TODO: close all open handle?? */
|
|
}
|
|
|
|
int moo_mod_con (moo_t* moo, moo_mod_t* mod)
|
|
{
|
|
mod->import = import;
|
|
mod->querypf = querypf;
|
|
mod->querypv = MOO_NULL;
|
|
mod->unload = unload;
|
|
mod->ctx = MOO_NULL;
|
|
return 0;
|
|
}
|