/* * Copyright (c) 2015-2017 Carsten Sonne Larsen * 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) : ConsoleBase(prompt) { proc = new AnsiConoleEngine(prompt); 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 // //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. */ //}