amath  1.8.5
Simple command line calculator
window_amiga.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 #include "amath.h"
31 #include "amathc.h"
32 #include "window_amiga.h"
33 #include "lib/aengine.h"
34 #include "main/evaluator.h"
35 
36 #if defined(AMIGA)
37 
38 #include <clib/exec_protos.h>
39 #include <clib/alib_protos.h>
40 #include <clib/dos_protos.h>
41 #include <clib/intuition_protos.h>
42 #include <clib/locale_protos.h>
43 #include <libraries/dos.h>
44 #include <graphics/gfxbase.h>
45 #include <intuition/intuition.h>
46 #include <intuition/intuitionbase.h>
47 #include <devices/conunit.h>
48 #include <devices/console.h>
49 
50 AmigaWindow::AmigaWindow(const char *prompt, CharValidator *validator) :
51  ConsoleBase(prompt)
52 {
53  proc = new AnsiConoleEngine(prompt, validator);
54  window = nullptr;
55  //menu = nullptr;
56  writereq.st = nullptr;
57  writeport = nullptr;
58  readreq.st = nullptr;
59  readport = nullptr;
60  succeed = false;
61  openconsole = false;
62 }
63 
64 AmigaWindow::~AmigaWindow()
65 {
66  Cleanup();
67  delete proc;
68 }
69 
70 void AmigaWindow::Create()
71 {
72  NewWindow nw = {
73  10, 20, // left, top
74  WWIDTH, WHEIGHT, // width, height
75  (UBYTE)-1, (UBYTE)-1, // detailpen, blockpen
76  IDCMP_CLOSEWINDOW |
77  IDCMP_MENUPICK,
78  WFLG_SIZEGADGET |
79  WFLG_DRAGBAR |
80  WFLG_DEPTHGADGET |
81  WFLG_CLOSEGADGET |
82  WFLG_ACTIVATE |
83  WFLG_SIMPLE_REFRESH,
84  nullptr, nullptr, // user gadgets, user checkmark
85  (UBYTE*) TXTTITLE, // title
86  nullptr, nullptr, // window screen, super bitmap
87  400, 75, // min width, height
88  1600, 1050, // max width, height
89  WBENCHSCREEN // open on workbench screen
90  };
91 
92  succeed = true;
93  succeed = succeed && (writeport = CreatePort((char*)PORTCR, 0)) != 0;
94  succeed = succeed && (readport = CreatePort((char*)PORTCW, 0)) != 0;
95  succeed = succeed && (writereq.st = CreateExtIO(writeport, sizeof(IOStdReq))) != 0;
96  succeed = succeed && (readreq.st = CreateExtIO(readport, sizeof(IOStdReq))) != 0;
97  succeed = succeed && (window = OpenWindow(&nw)) != 0;
98  if (!succeed) return;
99 
100  windowsig = 1 << window->UserPort->mp_SigBit;
101  writereq.io->io_Data = (APTR) window;
102  writereq.io->io_Length = sizeof(Window);
103 
104  openconsole = OpenDevice(DEVCONSOLE, CONU_SNIPMAP, writereq.st, CONFLAG_DEFAULT) == 0;
105  succeed = openconsole;
106  if (!openconsole) return;
107 
108  readreq.st->io_Device = writereq.st->io_Device;
109  readreq.st->io_Unit = writereq.st->io_Unit;
110 
111  // Queue input
112  ReadChar(readreq);
113 
114  // Do GUI stuff
115  //menu = new AmigaMenu(window);
116  //menu->Attach();
117 }
118 
119 void AmigaWindow::Cleanup()
120 {
121  if(openconsole) {
122  if (readreq.st) {
123  AbortIO(readreq.st);
124  WaitIO(readreq.st);
125  }
126 
127  CloseDevice(writereq.st);
128  openconsole = false;
129  }
130 
131  if(readreq.st) {
132  DeleteExtIO(readreq.st);
133  readreq.st = nullptr;
134  }
135 
136  if(readport) {
137  DeletePort(readport);
138  readport = nullptr;
139  }
140 
141  if(writereq.st) {
142  DeleteExtIO(writereq.st);
143  writereq.st = nullptr;
144  }
145 
146  if(writeport) {
147  DeletePort(writeport);
148  writeport = nullptr;
149  }
150 
151  //if (menu) {
152  // delete menu;
153  // menu = nullptr;
154  //}
155 
156  if(window) {
157  CloseWindow(window);
158  window = nullptr;
159  }
160 }
161 
162 void AmigaWindow::Start()
163 {
164  Create();
165  StartMessage();
166  exit = false;
167 
168  while(!exit) {
169  Prompt();
170  ReadLine();
171  Evaluator *evaluator = new Evaluator(line);
172  evaluator->Evaluate();
173  const char *out = evaluator->GetResult();
174  WriteString(out, StrLen(out));
175  delete evaluator;
176  }
177 
178  Cleanup();
179 }
180 
181 void AmigaWindow::Exit()
182 {
183  exit = true;
184 }
185 
186 void AmigaWindow::ReadLine()
187 {
188  unsigned long conreadsig = 1L << readport->mp_SigBit;
189  proc->StartInput();
190 
191  while(!proc->InputDone() && !exit)
192  {
193  unsigned long signals = Wait(conreadsig | windowsig);
194 
195  if (signals & conreadsig)
196  {
197  unsigned char ch = TryGetChar(readport);
198  if (ch != 0)
199  {
200  const char *out = proc->ProcessChar(ch);
201  WriteString(out);
202  }
203  }
204 
205  if (signals & windowsig)
206  {
207  STMessage w;
208  while ((w.msg = GetMsg(window->UserPort)))
209  {
210  switch(w.imsg->Class)
211  {
212  case IDCMP_CLOSEWINDOW:
213  exit = true;
214  break;
215  //case IDCMP_MENUPICK:
216  // menu->Process();
217  // break;
218  default:
219  break;
220  }
221 
222  ReplyMsg(w.msg);
223  }
224  }
225  }
226 
227  line = proc->GetLine();
228 }
229 
230 void AmigaWindow::WriteChar(const char character)
231 {
232  writereq.io->io_Command = CMD_WRITE;
233  writereq.io->io_Data = (APTR)&character;
234  writereq.io->io_Length = 1;
235  DoIO(writereq.st);
236 }
237 
238 void AmigaWindow::WriteString(const char *string)
239 {
240  writereq.io->io_Command = CMD_WRITE;
241  writereq.io->io_Data = (APTR)string;
242  writereq.io->io_Length = (ULONG)-1;
243  DoIO(writereq.st);
244 }
245 
246 void AmigaWindow::WriteString(const char *string, unsigned int length)
247 {
248  writereq.io->io_Command = CMD_WRITE;
249  writereq.io->io_Data = (APTR)string;
250  writereq.io->io_Length = (LONG)length;
251  DoIO(writereq.st);
252 }
253 
254 unsigned char AmigaWindow::ReadChar(STRequest request)
255 {
256  unsigned char result = inputbuf;
257  request.io->io_Command = CMD_READ;
258  request.io->io_Data = (APTR)&inputbuf;
259  request.io->io_Length = 1;
260  SendIO(request.st);
261  return result;
262 }
263 
264 unsigned char AmigaWindow::TryGetChar(MsgPort *msgport)
265 {
266  STRequest readreq;
267  readreq.msg = GetMsg(msgport);
268  return readreq.msg == 0 ? '\0' : ReadChar(readreq);
269 }
270 
271 void AmigaWindow::SetPrompt(const char* string)
272 {
273  ConsoleBase::SetPrompt(string);
274  proc->SetPrompt(string);
275 }
276 
277 #endif