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