1 /********************************************************************/
2 /* */
3 /* con_emc.c Driver for emcc (JavaScript) console access. */
4 /* Copyright (C) 1989 - 2019 Thomas Mertes */
5 /* */
6 /* This file is part of the Seed7 Runtime Library. */
7 /* */
8 /* The Seed7 Runtime Library is free software; you can */
9 /* redistribute it and/or modify it under the terms of the GNU */
10 /* Lesser General Public License as published by the Free Software */
11 /* Foundation; either version 2.1 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* The Seed7 Runtime Library is distributed in the hope that it */
15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */
16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Lesser General Public License for more */
18 /* details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General */
21 /* Public License along with this program; if not, write to the */
22 /* Free Software Foundation, Inc., 51 Franklin Street, */
23 /* Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* */
25 /* Module: Seed7 Runtime Library */
26 /* File: seed7/src/con_emc.c */
27 /* Changes: 2015, 2019 Thomas Mertes */
28 /* Content: Driver for emcc (JavaScript) console access. */
29 /* */
30 /********************************************************************/
31
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34
35 #include "version.h"
36
37 #include "stdlib.h"
38 #include "stdio.h"
39 #include "string.h"
40 #include "emscripten.h"
41
42 #include "common.h"
43 #include "heaputl.h"
44 #include "fil_rtl.h"
45 #include "ut8_rtl.h"
46
47 #undef EXTERN
48 #define EXTERN
49 #include "kbd_drv.h"
50 #include "con_drv.h"
51
52 #define KEY_BUFFER_SIZE 1024
53
54 static boolType keybd_initialized = FALSE;
55 static int keyBuffer[KEY_BUFFER_SIZE];
56 static int keyBufferReadPos;
57 static int keyBufferWritePos = 0;
58
59
60
kbdShut(void)61 void kbdShut (void)
62
63 { /* kbdShut */
64 } /* kbdShut */
65
66
67
pushKey(int aKey)68 static void pushKey (int aKey)
69
70 { /* pushKey */
71 if (likely(keyBufferReadPos != (keyBufferWritePos + 1) % KEY_BUFFER_SIZE)) {
72 keyBuffer[keyBufferWritePos] = aKey;
73 keyBufferWritePos = (keyBufferWritePos + 1) % KEY_BUFFER_SIZE;
74 } /* if */
75 } /* pushKey */
76
77
78
popKey(void)79 static int popKey (void)
80
81 {
82 int aKey;
83
84 /* popKey */
85 if (likely(keyBufferReadPos != keyBufferWritePos)) {
86 aKey = keyBuffer[keyBufferReadPos];
87 keyBufferReadPos = (keyBufferReadPos + 1) % KEY_BUFFER_SIZE;
88 } else {
89 aKey = EOF;
90 } /* if */
91 return aKey;
92 } /* popKey */
93
94
95
mapKeyByName(char * name,int ctrl,int meta,int shift)96 static int mapKeyByName (char *name, int ctrl, int meta, int shift)
97
98 {
99 int aKey;
100
101 /* mapKeyByName */
102 if (name[0] >= 'a' && name[0] <= 'z' && name[1] == '\0') {
103 if (ctrl) {
104 aKey = K_CTL_A + (name[0] - 'a');
105 } else if (meta) {
106 aKey = K_ALT_A + (name[0] - 'a');
107 } else if (shift) {
108 aKey = 'A' + (name[0] - 'a');
109 } else {
110 aKey = name[0];
111 } /* if */
112 } else if (name[0] >= '0' && name[0] <= '9' && name[1] == '\0') {
113 aKey = name[0];
114 } else if (name[0] == 'f' && name[1] >= '1' && name[1] <= '9' && name[2] == '\0') {
115 if (ctrl) {
116 aKey = K_CTL_F1 + (name[1] - '1');
117 } else if (meta) {
118 aKey = K_ALT_F1 + (name[1] - '1');
119 } else if (shift) {
120 aKey = K_SFT_F1 + (name[1] - '1');
121 } else {
122 aKey = K_F1 + (name[1] - '1');
123 } /* if */
124 } else if (name[0] == 'f' && name[1] == '1' && name[2] >= '0' && name[2] <= '2' && name[3] == '\0') {
125 if (ctrl) {
126 aKey = K_CTL_F10 + (name[2] - '0');
127 } else if (meta) {
128 aKey = K_ALT_F10 + (name[2] - '0');
129 } else if (shift) {
130 aKey = K_SFT_F10 + (name[2] - '0');
131 } else {
132 aKey = K_F10 + (name[2] - '0');
133 } /* if */
134 } else if (strcmp(name, "left") == 0) {
135 if (ctrl) {
136 aKey = K_CTL_LEFT;
137 } else {
138 aKey = K_LEFT;
139 } /* if */
140 } else if (strcmp(name, "right") == 0) {
141 if (ctrl) {
142 aKey = K_CTL_RIGHT;
143 } else {
144 aKey = K_RIGHT;
145 } /* if */
146 } else if (strcmp(name, "up") == 0) {
147 if (ctrl) {
148 aKey = K_CTL_UP;
149 } else {
150 aKey = K_UP;
151 } /* if */
152 } else if (strcmp(name, "down") == 0) {
153 if (ctrl) {
154 aKey = K_CTL_DOWN;
155 } else {
156 aKey = K_DOWN;
157 } /* if */
158 } else if (strcmp(name, "home") == 0) {
159 if (ctrl) {
160 aKey = K_CTL_HOME;
161 } else {
162 aKey = K_HOME;
163 } /* if */
164 } else if (strcmp(name, "end") == 0) {
165 if (ctrl) {
166 aKey = K_CTL_END;
167 } else {
168 aKey = K_END;
169 } /* if */
170 } else if (strcmp(name, "pageup") == 0) {
171 if (ctrl) {
172 aKey = K_CTL_PGUP;
173 } else {
174 aKey = K_PGUP;
175 } /* if */
176 } else if (strcmp(name, "pagedown") == 0) {
177 if (ctrl) {
178 aKey = K_CTL_PGDN;
179 } else {
180 aKey = K_PGDN;
181 } /* if */
182 } else if (strcmp(name, "insert") == 0) {
183 if (ctrl) {
184 aKey = K_CTL_INS;
185 } else {
186 aKey = K_INS;
187 } /* if */
188 } else if (strcmp(name, "delete") == 0) {
189 if (ctrl) {
190 aKey = K_CTL_DEL;
191 } else {
192 aKey = K_DEL;
193 } /* if */
194 } else if (strcmp(name, "tab") == 0) {
195 if (shift) {
196 aKey = K_BACKTAB;
197 } else {
198 aKey = K_TAB;
199 } /* if */
200 } else if (strcmp(name, "backspace") == 0) {
201 aKey = K_BS;
202 } else if (strcmp(name, "enter") == 0 || strcmp(name, "return") == 0) {
203 aKey = K_NL;
204 } else {
205 aKey = '?';
206 } /* if */
207 return aKey;
208 } /* mapKeyByName */
209
210
211
mapKeyBySequence(char * sequence,int ctrl,int meta,int shift)212 static int mapKeyBySequence (char *sequence, int ctrl, int meta, int shift)
213
214 {
215 int aKey;
216
217 /* mapKeyBySequence */
218 printf("mapKeyBySequence: %s\n", sequence);
219 aKey = EOF;
220 return aKey;
221 } /* mapKeyBySequence */
222
223
224
kbd_init(void)225 static void kbd_init (void)
226
227 { /* kbd_init */
228 logFunction(printf("kbd_init\n"););
229 #ifdef OUT_OF_ORDER
230 EM_ASM(
231 const readline = require('readline');
232 readline.emitKeypressEvents(process.stdin);
233 process.stdin.setRawMode(true);
234 process.stdin.on('keypress', (str, key) => {
235 let aKey;
236 if (typeof key.name !== 'undefined') {
237 aKey = Module.ccall('mapKeyByName', // name of C function
238 'number', // return type
239 ['string', 'number', 'number', 'number'], // argument types
240 [key.name, key.ctrl, key.meta, key.shift]); // arguments
241 } else {
242 aKey = Module.ccall('mapKeyBySequence', // name of C function
243 'number', // return type
244 ['string', 'number', 'number', 'number'], // argument types
245 [key.sequence, key.ctrl, key.meta, key.shift]); // arguments
246 }
247 Module.ccall('pushKey', // name of C function
248 null, // return type
249 ['number'], // argument types
250 aKey); // arguments
251 });
252 );
253 #endif
254 keybd_initialized = TRUE;
255 logFunction(printf("kbd_init -->\n"););
256 } /* kbd_init */
257
258
259
kbdKeyPressed(void)260 boolType kbdKeyPressed (void)
261
262 {
263 boolType result;
264
265 /* kbdKeyPressed */
266 logFunction(printf("kbdKeyPressed\n"););
267 if (!keybd_initialized) {
268 kbd_init();
269 } /* if */
270 result = keyBufferReadPos != keyBufferWritePos;
271 logFunction(printf("kbdKeyPressed --> %d\n", result););
272 return result;
273 } /* kbdKeyPressed */
274
275
276
kbdGetc(void)277 charType kbdGetc (void)
278
279 {
280 charType result;
281
282 /* kbdGetc */
283 logFunction(printf("kbdGetc\n"););
284 if (!keybd_initialized) {
285 kbd_init();
286 } /* if */
287 if (kbdKeyPressed()) {
288 result = (charType) popKey();
289 } else {
290 result = (charType) EOF;
291 } /* if */
292 return result;
293 } /* kbdGetc */
294
295
296
kbdRawGetc(void)297 charType kbdRawGetc (void)
298
299 { /* kbdRawRead */
300 logFunction(printf("kbdRawGetc\n"););
301 if (!keybd_initialized) {
302 kbd_init();
303 } /* if */
304 return (charType) EOF;
305 } /* kbdRawRead */
306
307
308
conHeight(void)309 int conHeight (void)
310
311 { /* conHeight */
312 return 0;
313 } /* conHeight */
314
315
316
conWidth(void)317 int conWidth (void)
318
319 { /* conWidth */
320 return 0;
321 } /* conWidth */
322
323
324
conFlush(void)325 void conFlush (void)
326
327 { /* conFlush */
328 } /* conFlush */
329
330
331
conCursor(boolType on)332 void conCursor (boolType on)
333
334 { /* conCursor */
335 } /* conCursor */
336
337
338
conSetCursor(intType line,intType column)339 void conSetCursor (intType line, intType column)
340
341 { /* conSetCursor */
342 } /* conSetCursor */
343
344
345
conColumn(void)346 intType conColumn (void)
347
348 { /* conColumn */
349 return 1;
350 } /* conColumn */
351
352
353
conLine(void)354 intType conLine (void)
355
356 { /* conLine */
357 return 1;
358 } /* conLine */
359
360
361
362 /**
363 * Writes the string stri to the console at the current position.
364 */
conWrite(const const_striType stri)365 void conWrite (const const_striType stri)
366
367 { /* conWrite */
368 ut8Write(&stdoutFileRecord, stri);
369 } /* conWrite */
370
371
372
conClear(intType startlin,intType startcol,intType stoplin,intType stopcol)373 void conClear (intType startlin, intType startcol,
374 intType stoplin, intType stopcol)
375
376 { /* conClear */
377 } /* conClear */
378
379
380
conUpScroll(intType startlin,intType startcol,intType stoplin,intType stopcol,intType count)381 void conUpScroll (intType startlin, intType startcol,
382 intType stoplin, intType stopcol, intType count)
383
384 { /* conUpScroll */
385 } /* conUpScroll */
386
387
388
conDownScroll(intType startlin,intType startcol,intType stoplin,intType stopcol,intType count)389 void conDownScroll (intType startlin, intType startcol,
390 intType stoplin, intType stopcol, intType count)
391
392 { /* conDownScroll */
393 } /* conDownScroll */
394
395
396
conLeftScroll(intType startlin,intType startcol,intType stoplin,intType stopcol,intType count)397 void conLeftScroll (intType startlin, intType startcol,
398 intType stoplin, intType stopcol, intType count)
399
400 { /* conLeftScroll */
401 } /* conLeftScroll */
402
403
404
conRightScroll(intType startlin,intType startcol,intType stoplin,intType stopcol,intType count)405 void conRightScroll (intType startlin, intType startcol,
406 intType stoplin, intType stopcol, intType count)
407
408 { /* conRightScroll */
409 } /* conRightScroll */
410
411
412
conShut(void)413 void conShut (void)
414
415 { /* conShut */
416 } /* conShut */
417
418
419
conOpen(void)420 int conOpen (void)
421
422 { /* conOpen */
423 logFunction(printf("conOpen\n"););
424 logFunction(printf("conOpen -->\n"););
425 return 1;
426 } /* conOpen */
427