(font-lock-make-faces): Add special code for ms-dos.
[bpt/emacs.git] / src / msdos.c
CommitLineData
9da6e765
RS
1/* MS-DOS specific C utilities.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
1b94449f
RS
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
edfc0d45 8the Free Software Foundation; either version 2, or (at your option)
1b94449f
RS
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
9da6e765 20/* Contributed by Morten Welinder */
f32d4091 21/* New display, keyboard, and mouse control by Kim F. Storm */
9da6e765 22
1b94449f
RS
23/* Note: some of the stuff here was taken from end of sysdep.c in demacs. */
24
48984716 25#include <config.h>
1b94449f
RS
26
27#ifdef MSDOS
28#include "lisp.h"
29#include <stdio.h>
30#include <stdlib.h>
31#include <sys/param.h>
32#include <sys/time.h>
33#include <dos.h>
34#include "dosfns.h"
35#include "msdos.h"
36#include "systime.h"
37#include "termhooks.h"
87485d6f
MW
38#include "dispextern.h"
39#include "termopts.h"
1b94449f 40#include "frame.h"
87485d6f 41#include "window.h"
1b94449f
RS
42#include <go32.h>
43#include <pc.h>
44#include <ctype.h>
45/* #include <process.h> */
46/* Damn that local process.h! Instead we can define P_WAIT ourselves. */
47#define P_WAIT 1
48
aee81730
RS
49
50static unsigned long
51event_timestamp ()
52{
53 struct time t;
54 unsigned long s;
f32d4091 55
aee81730
RS
56 gettime (&t);
57 s = t.ti_min;
58 s *= 60;
59 s += t.ti_sec;
60 s *= 1000;
61 s += t.ti_hund * 10;
f32d4091 62
aee81730
RS
63 return s;
64}
65
f32d4091
KS
66\f
67/* ------------------------ Mouse control ---------------------------
68 *
69 * Coordinates are in screen positions and zero based.
70 * Mouse buttons are numbered from left to right and also zero based.
71 */
1b94449f 72
f32d4091
KS
73int have_mouse; /* 0: no, 1: enabled, -1: disabled */
74static int mouse_visible;
1b94449f 75
f32d4091
KS
76static int mouse_last_x;
77static int mouse_last_y;
1b94449f 78
f32d4091
KS
79static int mouse_button_translate[NUM_MOUSE_BUTTONS];
80static int mouse_button_count;
1b94449f 81
f32d4091
KS
82void
83mouse_on ()
1b94449f 84{
1b94449f 85 union REGS regs;
1b94449f 86
f32d4091 87 if (have_mouse > 0 && !mouse_visible)
1b94449f 88 {
f32d4091
KS
89 if (termscript)
90 fprintf (termscript, "<M_ON>");
91 regs.x.ax = 0x0001;
92 int86 (0x33, &regs, &regs);
93 mouse_visible = 1;
1b94449f 94 }
1b94449f
RS
95}
96
f32d4091
KS
97void
98mouse_off ()
1b94449f 99{
f32d4091 100 union REGS regs;
1b94449f 101
f32d4091 102 if (have_mouse > 0 && mouse_visible)
1b94449f 103 {
f32d4091
KS
104 if (termscript)
105 fprintf (termscript, "<M_OFF>");
106 regs.x.ax = 0x0002;
107 int86 (0x33, &regs, &regs);
108 mouse_visible = 0;
1b94449f 109 }
1b94449f
RS
110}
111
f32d4091
KS
112void
113mouse_moveto (x, y)
114 int x, y;
1b94449f 115{
f32d4091 116 union REGS regs;
1b94449f 117
f32d4091
KS
118 if (termscript)
119 fprintf (termscript, "<M_XY=%dx%d>", x, y);
120 regs.x.ax = 0x0004;
121 mouse_last_x = regs.x.cx = x * 8;
122 mouse_last_y = regs.x.dx = y * 8;
123 int86 (0x33, &regs, &regs);
1b94449f
RS
124}
125
f32d4091
KS
126static int
127mouse_pressed (b, xp, yp)
128 int b, *xp, *yp;
1b94449f 129{
f32d4091 130 union REGS regs;
1b94449f 131
f32d4091
KS
132 if (b >= mouse_button_count)
133 return 0;
134 regs.x.ax = 0x0005;
135 regs.x.bx = mouse_button_translate[b];
136 int86 (0x33, &regs, &regs);
137 if (regs.x.bx)
138 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
139 return (regs.x.bx != 0);
1b94449f
RS
140}
141
f32d4091
KS
142static int
143mouse_released (b, xp, yp)
144 int b, *xp, *yp;
1b94449f
RS
145{
146 union REGS regs;
147
f32d4091
KS
148 if (b >= mouse_button_count)
149 return 0;
150 regs.x.ax = 0x0006;
151 regs.x.bx = mouse_button_translate[b];
152 int86 (0x33, &regs, &regs);
153 if (regs.x.bx)
154 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
155 return (regs.x.bx != 0);
1b94449f
RS
156}
157
f32d4091
KS
158static void
159mouse_get_xy (int *x, int *y)
1b94449f 160{
f32d4091 161 union REGS regs;
1b94449f 162
f32d4091
KS
163 regs.x.ax = 0x0003;
164 int86 (0x33, &regs, &regs);
165 *x = regs.x.cx / 8;
166 *y = regs.x.dx / 8;
1b94449f
RS
167}
168
f32d4091
KS
169void
170mouse_get_pos (f, insist, bar_window, part, x, y, time)
171 FRAME_PTR *f;
172 int insist;
173 Lisp_Object *bar_window, *x, *y;
174 enum scroll_bar_part *part;
175 unsigned long *time;
176{
177 int ix, iy;
178 union REGS regs;
179
180 regs.x.ax = 0x0003;
181 int86 (0x33, &regs, &regs);
182 *f = selected_frame;
183 *bar_window = Qnil;
184 mouse_get_xy (&ix, &iy);
185 selected_frame->mouse_moved = 0;
186 *x = make_number (ix);
187 *y = make_number (iy);
188 *time = event_timestamp ();
189}
1b94449f 190
f32d4091
KS
191static void
192mouse_check_moved ()
1b94449f 193{
aee81730 194 int x, y;
1b94449f 195
f32d4091
KS
196 mouse_get_xy (&x, &y);
197 selected_frame->mouse_moved |= (x != mouse_last_x || y != mouse_last_y);
198 mouse_last_x = x;
199 mouse_last_y = y;
200}
1b94449f 201
f32d4091
KS
202void
203mouse_init ()
204{
205 union REGS regs;
647c32eb 206
f32d4091
KS
207 if (termscript)
208 fprintf (termscript, "<M_INIT>");
1b94449f 209
f32d4091
KS
210 regs.x.ax = 0x0021;
211 int86 (0x33, &regs, &regs);
091d0bdf 212
f32d4091
KS
213 regs.x.ax = 0x0007;
214 regs.x.cx = 0;
215 regs.x.dx = 8 * (ScreenCols () - 1);
216 int86 (0x33, &regs, &regs);
1b94449f 217
f32d4091
KS
218 regs.x.ax = 0x0008;
219 regs.x.cx = 0;
220 regs.x.dx = 8 * (ScreenRows () - 1);
221 int86 (0x33, &regs, &regs);
1b94449f 222
f32d4091
KS
223 mouse_moveto (0, 0);
224 mouse_visible = 0;
225}
aee81730 226
f32d4091
KS
227/* ------------------------- Screen control ----------------------
228 *
229 */
aee81730 230
f32d4091 231static int internal_terminal = 0;
aee81730 232
f32d4091
KS
233#ifndef HAVE_X_WINDOWS
234extern unsigned char ScreenAttrib;
235static int screen_face;
236static int highlight;
aee81730 237
f32d4091
KS
238static int screen_size_X;
239static int screen_size_Y;
240static int screen_size;
1b94449f 241
f32d4091
KS
242static int current_pos_X;
243static int current_pos_Y;
244static int new_pos_X;
245static int new_pos_Y;
1b94449f 246
f32d4091
KS
247static void *startup_screen_buffer;
248static int startup_screen_size_X;
249static int startup_screen_size_Y;
250static int startup_pos_X;
251static int startup_pos_Y;
1b94449f 252
f32d4091 253static int term_setup_done;
1b94449f 254
f32d4091 255/* Similar to the_only_frame. */
f6816f88 256struct x_output the_only_x_display;
1b94449f 257
f32d4091
KS
258/* This is never dereferenced. */
259Display *x_current_display;
1b94449f 260
1b94449f 261
f32d4091
KS
262#define SCREEN_SET_CURSOR() \
263 if (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y) \
264 ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X)
aee81730 265
f32d4091
KS
266static
267dos_direct_output (y, x, buf, len)
268 int y;
269 int x;
270 char *buf;
271 int len;
1b94449f 272{
f32d4091 273 int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X);
aee81730 274
f32d4091
KS
275 while (--len >= 0) {
276 dosmemput (buf++, 1, t);
277 t += 2;
278 }
1b94449f 279}
aee81730 280#endif
1b94449f 281
1b94449f
RS
282/* Flash the screen as a substitute for BEEPs. */
283
f32d4091 284#if (__DJGPP__ < 2)
49a09c76 285static void
fcea9cd4 286do_visible_bell (xorattr)
1b94449f
RS
287 unsigned char xorattr;
288{
49a09c76 289 asm volatile
ca986694 290 (" movb $1,%%dl
1b94449f 291visible_bell_0:
ca986694 292 movl _ScreenPrimary,%%eax
49a09c76 293 call dosmemsetup
ca986694
RS
294 movl %%eax,%%ebx
295 movl %1,%%ecx
296 movb %0,%%al
297 incl %%ebx
1b94449f 298visible_bell_1:
ca986694
RS
299 xorb %%al,%%gs:(%%ebx)
300 addl $2,%%ebx
301 decl %%ecx
49a09c76 302 jne visible_bell_1
ca986694 303 decb %%dl
49a09c76 304 jne visible_bell_3
1b94449f 305visible_bell_2:
ca986694
RS
306 movzwl %%ax,%%eax
307 movzwl %%ax,%%eax
308 movzwl %%ax,%%eax
309 movzwl %%ax,%%eax
310 decw %%cx
49a09c76
RS
311 jne visible_bell_2
312 jmp visible_bell_0
ca986694
RS
313visible_bell_3:"
314 : /* no output */
f32d4091 315 : "m" (xorattr), "g" (screen_size)
ca986694 316 : "%eax", "%ebx", /* "%gs",*/ "%ecx", "%edx");
1b94449f
RS
317}
318
f32d4091
KS
319static void
320ScreenVisualBell (void)
321{
322 /* This creates an xor-mask that will swap the default fore- and
323 background colors. */
324 do_visible_bell (((the_only_x_display.foreground_pixel
325 ^ the_only_x_display.background_pixel)
326 * 0x11) & 0x7f);
327}
328#endif
329
330#ifndef HAVE_X_WINDOWS
331
332/*
333 * If we write a character in the position where the mouse is,
334 * the mouse cursor may need to be refreshed.
335 */
09e2ac30
RS
336
337static void
f32d4091 338mouse_off_maybe ()
09e2ac30 339{
f32d4091
KS
340 int x, y;
341
342 if (!mouse_visible)
343 return;
344
345 mouse_get_xy (&x, &y);
346 if (y != new_pos_Y || x < new_pos_X)
347 return;
348
349 mouse_off ();
350}
351
352static
353IT_ring_bell ()
354{
355 if (visible_bell)
aee81730 356 {
f32d4091
KS
357 mouse_off ();
358 ScreenVisualBell ();
aee81730 359 }
f32d4091 360 else
3635be47
RS
361 {
362 union REGS inregs, outregs;
363 inregs.h.ah = 2;
364 inregs.h.dl = 7;
365 intdos (&inregs, &outregs);
366 }
09e2ac30
RS
367}
368
f32d4091
KS
369static void
370IT_set_face (int face)
371{
372 struct face *fp;
373 extern struct face *intern_face (/* FRAME_PTR, struct face * */);
374
375 if (face == 1 || (face == 0 && highlight))
376 fp = FRAME_MODE_LINE_FACE (foo);
377 else if (face <= 0 || face >= FRAME_N_COMPUTED_FACES (foo))
378 fp = FRAME_DEFAULT_FACE (foo);
379 else
380 fp = intern_face (selected_frame, FRAME_COMPUTED_FACES (foo)[face]);
381 if (termscript)
382 fprintf (termscript, "<FACE:%d:%d>", FACE_FOREGROUND (fp), FACE_BACKGROUND (fp));
383 screen_face = face;
384 ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp);
385}
386
387static
388IT_write_glyphs (GLYPH *str, int len)
389{
390 int newface;
391 int ch, l = len;
392 unsigned char *buf, *bp;
87485d6f 393
f32d4091 394 if (len == 0) return;
aee81730 395
f32d4091 396 buf = bp = alloca (len * 2);
aee81730 397
f32d4091 398 while (--l >= 0)
aee81730 399 {
f32d4091
KS
400 newface = FAST_GLYPH_FACE (*str);
401 if (newface != screen_face)
402 IT_set_face (newface);
403 ch = FAST_GLYPH_CHAR (*str);
404 *bp++ = (unsigned char)ch;
405 *bp++ = ScreenAttrib;
406
407 if (termscript)
408 fputc (ch, termscript);
409 str++;
aee81730
RS
410 }
411
f32d4091
KS
412 mouse_off_maybe ();
413 dosmemput (buf, 2 * len,
414 (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y));
415 new_pos_X += len;
416}
aee81730 417
f32d4091
KS
418static
419IT_clear_end_of_line (first_unused)
420{
421 char *spaces, *sp;
422 int i, j;
423
424 IT_set_face (0);
425 if (termscript)
426 fprintf (termscript, "<CLR:EOL>");
427 i = (j = screen_size_X - new_pos_X) * 2;
428 spaces = sp = alloca (i);
aee81730 429
f32d4091 430 while (--j >= 0)
aee81730 431 {
f32d4091
KS
432 *sp++ = ' ';
433 *sp++ = ScreenAttrib;
aee81730
RS
434 }
435
f32d4091
KS
436 mouse_off_maybe ();
437 dosmemput (spaces, i,
438 (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y));
aee81730
RS
439}
440
f32d4091
KS
441static
442IT_clear_screen (void)
443{
444 if (termscript)
445 fprintf (termscript, "<CLR:SCR>");
446 IT_set_face (0);
447 mouse_off ();
448 ScreenClear ();
449 new_pos_X = new_pos_Y = 0;
450}
451
452static
453IT_clear_to_end (void)
454{
455 if (termscript)
456 fprintf (termscript, "<CLR:EOS>");
457
458 while (new_pos_Y < screen_size_Y) {
459 new_pos_X = 0;
460 IT_clear_end_of_line (0);
461 new_pos_Y++;
462 }
463}
464
465static
466IT_cursor_to (int y, int x)
467{
468 if (termscript)
469 fprintf (termscript, "\n<XY=%dx%d>", x, y);
470 new_pos_X = x;
471 new_pos_Y = y;
472}
473
474static
475IT_reassert_line_highlight (new, vpos)
476 int new, vpos;
477{
478 highlight = new;
479 IT_set_face (0); /* To possibly clear the highlighting. */
480}
481
482static
483IT_change_line_highlight (new_highlight, vpos, first_unused_hpos)
1b94449f 484{
f32d4091
KS
485 highlight = new_highlight;
486 IT_set_face (0); /* To possibly clear the highlighting. */
487 IT_cursor_to (vpos, 0);
488 IT_clear_end_of_line (first_unused_hpos);
489}
490
491static
492IT_update_begin ()
493{
494 highlight = 0;
495 IT_set_face (0); /* To possibly clear the highlighting. */
496 screen_face = -1;
497}
498
499static
500IT_update_end ()
501{
502}
1b94449f 503
f32d4091
KS
504/* This was more or less copied from xterm.c */
505static void
506IT_set_menu_bar_lines (window, n)
507 Lisp_Object window;
508 int n;
509{
510 struct window *w = XWINDOW (window);
511
512 XSETFASTINT (w->top, XFASTINT (w->top) + n);
513 XSETFASTINT (w->height, XFASTINT (w->height) - n);
514
515 /* Handle just the top child in a vertical split. */
516 if (!NILP (w->vchild))
517 IT_set_menu_bar_lines (w->vchild, n);
518
519 /* Adjust all children in a horizontal split. */
520 for (window = w->hchild; !NILP (window); window = w->next)
1b94449f 521 {
f32d4091
KS
522 w = XWINDOW (window);
523 IT_set_menu_bar_lines (window, n);
aee81730 524 }
f32d4091
KS
525}
526
527/*
528 * IT_set_terminal_modes is called when emacs is started,
529 * resumed, and whenever the screen is redrawn!
530 */
531
532static
533IT_set_terminal_modes (void)
534{
535 char *colors;
536 FRAME_PTR f;
537 struct face *fp;
aee81730 538
aee81730 539 if (termscript)
f32d4091
KS
540 fprintf (termscript, "\n<SET_TERM>");
541 highlight = 0;
542
543 screen_size_X = ScreenCols ();
544 screen_size_Y = ScreenRows ();
545 screen_size = screen_size_X * screen_size_Y;
aee81730 546
f32d4091
KS
547 new_pos_X = new_pos_Y = 0;
548 current_pos_X = current_pos_Y = -1;
549
550 if (term_setup_done)
551 return;
552 term_setup_done = 1;
aee81730 553
f32d4091
KS
554 startup_screen_size_X = screen_size_X;
555 startup_screen_size_Y = screen_size_Y;
556
557 ScreenGetCursor (&startup_pos_Y, &startup_pos_X);
558 ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2));
559
560 if (termscript)
561 fprintf (termscript, "<SCREEN SAVED>\n");
562}
563
564/*
565 * IT_reset_terminal_modes is called when emacs is
566 * suspended or killed.
567 */
568
569static
570IT_reset_terminal_modes (void)
571{
572 if (termscript)
5063b150 573 fprintf (termscript, "\n<RESET_TERM>");
f32d4091
KS
574
575 highlight = 0;
576
577 if (!term_setup_done)
578 return;
579
580 ScreenUpdate (startup_screen_buffer);
581 ScreenSetCursor (startup_pos_Y, startup_pos_X);
582 xfree (startup_screen_buffer);
583
584 if (termscript)
585 fprintf (termscript, "<SCREEN RESTORED>\n");
586
587 term_setup_done = 0;
588}
589
590static
591IT_set_terminal_window (void)
592{
593}
594
595void
596IT_set_frame_parameters (frame, alist)
597 FRAME_PTR frame;
598 Lisp_Object alist;
599{
600 Lisp_Object tail;
601 int redraw;
602 extern unsigned long load_color ();
603 FRAME_PTR f = (FRAME_PTR) &the_only_frame;
604
605 redraw = 0;
606 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
607 {
608 Lisp_Object elt, prop, val;
609
610 elt = Fcar (tail);
611 prop = Fcar (elt);
612 val = Fcdr (elt);
613 CHECK_SYMBOL (prop, 1);
614
615 if (EQ (prop, intern ("foreground-color")))
616 {
617 unsigned long new_color = load_color (f, val);
618 if (new_color != ~0)
619 {
620 FRAME_FOREGROUND_PIXEL (f) = new_color;
621 redraw = 1;
622 }
623 }
624 else if (EQ (prop, intern ("background-color")))
625 {
626 unsigned long new_color = load_color (f, val);
627 if (new_color != ~0)
628 {
629 FRAME_BACKGROUND_PIXEL (f) = new_color & ~8;
630 redraw = 1;
631 }
632 }
633 else if (EQ (prop, intern ("menu-bar-lines")))
634 {
635 int new;
636 int old = FRAME_MENU_BAR_LINES (the_only_frame);
637
638 if (INTEGERP (val))
639 new = XINT (val);
640 else
641 new = 0;
642 FRAME_MENU_BAR_LINES (f) = new;
643 IT_set_menu_bar_lines (the_only_frame.root_window, new - old);
644 }
645 }
646
647 if (redraw)
648 {
649 recompute_basic_faces (f);
650 Fredraw_frame (Fselected_frame ());
651 }
652}
653
654#endif /* !HAVE_X_WINDOWS */
655
656
657/* Do we need the internal terminal? */
658void
659internal_terminal_init ()
660{
661 char *term = getenv ("TERM");
662 char *colors;
663
664#ifdef HAVE_X_WINDOWS
665 if (!inhibit_window_system)
666 return;
667#endif
668
669 internal_terminal
670 = (!noninteractive) && term && !strcmp (term, "internal");
671
672 if (getenv ("EMACSTEST"))
5063b150 673 termscript = fopen (getenv ("EMACSTEST"), "wt");
f32d4091
KS
674
675#ifndef HAVE_X_WINDOWS
676 if (!internal_terminal || inhibit_window_system)
677 {
678 the_only_frame.output_method = output_termcap;
679 return;
680 }
681
682 Vwindow_system = intern ("pc");
683 Vwindow_system_version = make_number (1);
684
685 bzero (&the_only_x_display, sizeof the_only_x_display);
686 the_only_x_display.background_pixel = 7; /* White */
687 the_only_x_display.foreground_pixel = 0; /* Black */
5063b150 688 colors = getenv ("EMACSCOLORS");
f32d4091
KS
689 if (colors && strlen (colors) >= 2)
690 {
691 the_only_x_display.foreground_pixel = colors[0] & 0x07;
692 the_only_x_display.background_pixel = colors[1] & 0x07;
693 }
694 the_only_x_display.line_height = 1;
f6816f88 695 the_only_frame.output_data.x = &the_only_x_display;
f32d4091 696 the_only_frame.output_method = output_msdos_raw;
64ec6a02 697 the_only_x_display.font = (XFontStruct *)1; /* must *not* be zero */
f32d4091
KS
698
699 init_frame_faces ((FRAME_PTR) &the_only_frame);
700
701 ring_bell_hook = IT_ring_bell;
702 write_glyphs_hook = IT_write_glyphs;
703 cursor_to_hook = raw_cursor_to_hook = IT_cursor_to;
704 clear_to_end_hook = IT_clear_to_end;
705 clear_end_of_line_hook = IT_clear_end_of_line;
706 clear_frame_hook = IT_clear_screen;
707 change_line_highlight_hook = IT_change_line_highlight;
708 update_begin_hook = IT_update_begin;
709 update_end_hook = IT_update_end;
710 reassert_line_highlight_hook = IT_reassert_line_highlight;
711
712 /* These hooks are called by term.c without being checked. */
713 set_terminal_modes_hook = IT_set_terminal_modes;
714 reset_terminal_modes_hook = IT_reset_terminal_modes;
715 set_terminal_window_hook = IT_set_terminal_window;
716#endif
717}
718
719dos_get_saved_screen (screen, rows, cols)
720 char **screen;
721 int *rows;
722 int *cols;
723{
724#ifndef HAVE_X_WINDOWS
725 *screen = startup_screen_buffer;
726 *cols = startup_screen_size_X;
727 *rows = startup_screen_size_Y;
728 return 1;
729#else
730 return 0;
731#endif
732}
733
734
5063b150 735\f
f32d4091
KS
736/* ----------------------- Keyboard control ----------------------
737 *
738 * Keymaps reflect the following keyboard layout:
739 *
740 * 0 1 2 3 4 5 6 7 8 9 10 11 12 BS
741 * TAB 15 16 17 18 19 20 21 22 23 24 25 26 (41)
742 * CLOK 30 31 32 33 34 35 36 37 38 39 40 (41) RET
743 * SH () 45 46 47 48 49 50 51 52 53 54 SHIFT
744 * SPACE
745 */
746
747static int extended_kbd; /* 101 (102) keyboard present. */
748
749struct dos_keyboard_map
750{
751 char *unshifted;
752 char *shifted;
753 char *alt_gr;
754};
755
756
757static struct dos_keyboard_map us_keyboard = {
758/* 0 1 2 3 4 5 */
759/* 01234567890123456789012345678901234567890 12345678901234 */
760 "`1234567890-= qwertyuiop[] asdfghjkl;'\\ zxcvbnm,./ ",
761/* 0123456789012345678901234567890123456789 012345678901234 */
762 "~!@#$%^&*()_+ QWERTYUIOP{} ASDFGHJKL:\"| ZXCVBNM<>? ",
763 0 /* no Alt-Gr key */
764};
765
766static struct dos_keyboard_map fr_keyboard = {
767/* 0 1 2 3 4 5 */
768/* 012 3456789012345678901234567890123456789012345678901234 */
769