mirror of https://gitlab.com/rnger/amath
295 lines
7.6 KiB
C++
Executable File
295 lines
7.6 KiB
C++
Executable File
/*
|
|
* Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
|
|
* 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 "clib.h"
|
|
#include "lib/aengine.h"
|
|
#include "localize/start.h"
|
|
#include "main/evaluator.h"
|
|
#include "system/window_amiga.h"
|
|
#include "system/base/io.h"
|
|
|
|
#ifdef AMIGA
|
|
|
|
AmigaWindow::AmigaWindow(const char *prompt, CharValidator *validator) :
|
|
ConsoleBase(prompt)
|
|
{
|
|
proc = new AnsiConoleEngine(prompt, validator);
|
|
window = NULL;
|
|
//menu = NULL;
|
|
writereq.st = NULL;
|
|
writeport = NULL;
|
|
readreq.st = NULL;
|
|
readport = NULL;
|
|
succeed = false;
|
|
openconsole = false;
|
|
}
|
|
|
|
AmigaWindow::~AmigaWindow()
|
|
{
|
|
Cleanup();
|
|
delete proc;
|
|
}
|
|
|
|
int AmigaWindow::GetStackSize()
|
|
{
|
|
return 100000;
|
|
}
|
|
|
|
void AmigaWindow::Create()
|
|
{
|
|
NewWindow nw = {
|
|
10, 20, // left, top
|
|
WWIDTH, WHEIGHT, // width, height
|
|
(UBYTE)-1, (UBYTE)-1, // detailpen, blockpen
|
|
IDCMP_CLOSEWINDOW |
|
|
IDCMP_MENUPICK,
|
|
WFLG_SIZEGADGET |
|
|
WFLG_DRAGBAR |
|
|
WFLG_DEPTHGADGET |
|
|
WFLG_CLOSEGADGET |
|
|
WFLG_ACTIVATE |
|
|
WFLG_SIMPLE_REFRESH,
|
|
NULL, NULL, // user gadgets, user checkmark
|
|
(UBYTE*) TXTTITLE, // title
|
|
NULL, NULL, // window screen, super bitmap
|
|
400, 75, // min width, height
|
|
1600, 1050, // max width, height
|
|
WBENCHSCREEN // open on workbench screen
|
|
};
|
|
|
|
succeed = true;
|
|
succeed = succeed && (writeport = CreatePort(PORTCR, 0)) != 0;
|
|
succeed = succeed && (readport = CreatePort(PORTCW, 0)) != 0;
|
|
succeed = succeed && (writereq.st = CreateExtIO(writeport, sizeof(IOStdReq))) != 0;
|
|
succeed = succeed && (readreq.st = CreateExtIO(readport, sizeof(IOStdReq))) != 0;
|
|
succeed = succeed && (window = OpenWindow(&nw)) != 0;
|
|
if (!succeed) return;
|
|
|
|
windowsig = 1 << window->UserPort->mp_SigBit;
|
|
writereq.io->io_Data = (APTR) window;
|
|
writereq.io->io_Length = sizeof(Window);
|
|
|
|
openconsole = OpenDevice(DEVCONSOLE, CONU_SNIPMAP, writereq.st, CONFLAG_DEFAULT) == 0;
|
|
succeed = openconsole;
|
|
if (!openconsole) return;
|
|
|
|
readreq.st->io_Device = writereq.st->io_Device;
|
|
readreq.st->io_Unit = writereq.st->io_Unit;
|
|
|
|
// Queue input
|
|
ReadChar(readreq);
|
|
|
|
// Do GUI stuff
|
|
//menu = new AmigaMenu(window);
|
|
//menu->Attach();
|
|
}
|
|
|
|
void AmigaWindow::Cleanup()
|
|
{
|
|
if(openconsole) {
|
|
if (readreq.st) {
|
|
AbortIO(readreq.st);
|
|
WaitIO(readreq.st);
|
|
}
|
|
|
|
CloseDevice(writereq.st);
|
|
openconsole = false;
|
|
}
|
|
|
|
if(readreq.st) {
|
|
DeleteExtIO(readreq.st);
|
|
readreq.st = NULL;
|
|
}
|
|
|
|
if(readport) {
|
|
DeletePort(readport);
|
|
readport = NULL;
|
|
}
|
|
|
|
if(writereq.st) {
|
|
DeleteExtIO(writereq.st);
|
|
writereq.st = NULL;
|
|
}
|
|
|
|
if(writeport) {
|
|
DeletePort(writeport);
|
|
writeport = NULL;
|
|
}
|
|
|
|
//if (menu) {
|
|
// delete menu;
|
|
// menu = NULL;
|
|
//}
|
|
|
|
if(window) {
|
|
CloseWindow(window);
|
|
window = NULL;
|
|
}
|
|
}
|
|
|
|
void AmigaWindow::Run()
|
|
{
|
|
Create();
|
|
StartMessage();
|
|
exit = false;
|
|
|
|
while(!exit) {
|
|
Prompt();
|
|
ReadLine();
|
|
Evaluator *evaluator = new Evaluator(line);
|
|
evaluator->Evaluate();
|
|
const char *out = evaluator->GetResult();
|
|
WriteString(out, StrLen(out));
|
|
delete evaluator;
|
|
}
|
|
|
|
Cleanup();
|
|
}
|
|
|
|
void AmigaWindow::Exit()
|
|
{
|
|
exit = true;
|
|
}
|
|
|
|
void AmigaWindow::ReadLine()
|
|
{
|
|
unsigned long conreadsig = 1L << readport->mp_SigBit;
|
|
proc->StartInput();
|
|
|
|
while(!proc->InputDone() && !exit)
|
|
{
|
|
unsigned long signals = Wait(conreadsig | windowsig);
|
|
|
|
if (signals & conreadsig)
|
|
{
|
|
unsigned char ch = TryGetChar(readport);
|
|
if (ch != 0)
|
|
{
|
|
const char *out = proc->ProcessChar(ch);
|
|
WriteString(out);
|
|
}
|
|
}
|
|
|
|
if (signals & windowsig)
|
|
{
|
|
STMessage w;
|
|
while ((w.msg = GetMsg(window->UserPort)))
|
|
{
|
|
switch(w.imsg->Class)
|
|
{
|
|
case IDCMP_CLOSEWINDOW:
|
|
exit = true;
|
|
break;
|
|
//case IDCMP_MENUPICK:
|
|
// menu->Process();
|
|
// break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ReplyMsg(w.msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
line = proc->GetLine();
|
|
}
|
|
|
|
void AmigaWindow::WriteChar(const char character)
|
|
{
|
|
writereq.io->io_Command = CMD_WRITE;
|
|
writereq.io->io_Data = (APTR)&character;
|
|
writereq.io->io_Length = 1;
|
|
DoIO(writereq.st);
|
|
}
|
|
|
|
void AmigaWindow::WriteString(const char *string)
|
|
{
|
|
writereq.io->io_Command = CMD_WRITE;
|
|
writereq.io->io_Data = (APTR)string;
|
|
writereq.io->io_Length = (ULONG)-1;
|
|
DoIO(writereq.st);
|
|
}
|
|
|
|
void AmigaWindow::WriteString(const char *string, unsigned int length)
|
|
{
|
|
writereq.io->io_Command = CMD_WRITE;
|
|
writereq.io->io_Data = (APTR)string;
|
|
writereq.io->io_Length = (LONG)length;
|
|
DoIO(writereq.st);
|
|
}
|
|
|
|
unsigned char AmigaWindow::ReadChar(STRequest request)
|
|
{
|
|
unsigned char result = inputbuf;
|
|
request.io->io_Command = CMD_READ;
|
|
request.io->io_Data = (APTR)&inputbuf;
|
|
request.io->io_Length = 1;
|
|
SendIO(request.st);
|
|
return result;
|
|
}
|
|
|
|
unsigned char AmigaWindow::TryGetChar(MsgPort *msgport)
|
|
{
|
|
STRequest readreq;
|
|
readreq.msg = GetMsg(msgport);
|
|
return readreq.msg == 0 ? '\0' : ReadChar(readreq);
|
|
}
|
|
|
|
void AmigaWindow::SetPrompt(const char* string)
|
|
{
|
|
ConsoleBase::SetPrompt(string);
|
|
proc->SetPrompt(string);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node046C.html#line6
|
|
|
|
//#include <devices/keymap.h>
|
|
//
|
|
//BOOL AskKeyMap(struct IOStdReq *request, struct KeyMap *keymap)
|
|
//{
|
|
// request->io_Command = CD_ASKKEYMAP;
|
|
// request->io_Length = sizeof(struct KeyMap);
|
|
// request->io_Data = (APTR)keymap; /* where to put it */
|
|
// DoIO(request);
|
|
// if(request->io_Error) return(FALSE);
|
|
// else return(TRUE); /* if no error, it worked. */
|
|
//}
|
|
|
|
//BOOL SetKeyMap(struct IOStdReq *request,struct KeyMap *keymap)
|
|
//{
|
|
// request->io_Command = CD_SETKEYMAP;
|
|
// request->io_Length = sizeof(struct KeyMap);
|
|
// request->io_Data = (APTR)keymap; /* where to get it */
|
|
// DoIO(request);
|
|
// if(request->io_Error) return(FALSE);
|
|
// else return(TRUE); /* if no error, it worked. */
|
|
//}
|