Merge from trunk.
[emacs.git] / src / dosfns.c
blob8ef672fb8bb390fd2a3d7c32ef092aea90378e96
1 /* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991.
2 Major changes May-July 1993 Morten Welinder (only 10% original code left)
3 Copyright (C) 1991, 1993, 1996-1998, 2001-2012 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
22 #ifdef MSDOS
23 /* The entire file is within this conditional */
25 #include <stdio.h>
26 #include <dos.h>
27 #include <setjmp.h>
28 #include "lisp.h"
29 #include "buffer.h"
30 #include "termchar.h"
31 #include "frame.h"
32 #include "termhooks.h"
33 #include "blockinput.h"
34 #include "window.h"
35 #include "dosfns.h"
36 #include "msdos.h"
37 #include "dispextern.h"
38 #include "character.h"
39 #include "coding.h"
40 #include "process.h"
41 #include <dpmi.h>
42 #include <go32.h>
43 #include <dirent.h>
44 #include <sys/vfs.h>
45 #include <unistd.h>
46 #include <grp.h>
47 #include <crt0.h>
49 DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
50 doc: /* Call specific MS-DOS interrupt number INTERRUPT with REGISTERS.
51 Return the updated REGISTER vector.
53 INTERRUPT should be an integer in the range 0 to 255.
54 REGISTERS should be a vector produced by `make-register' and
55 `set-register-value'. */)
56 (Lisp_Object interrupt, Lisp_Object registers)
58 register int i;
59 int no;
60 union REGS inregs, outregs;
62 CHECK_NUMBER (interrupt);
63 no = (unsigned long) XINT (interrupt);
64 CHECK_VECTOR (registers);
65 if (no < 0 || no > 0xff || ASIZE (registers) != 8)
66 return Qnil;
67 for (i = 0; i < 8; i++)
68 CHECK_NUMBER (XVECTOR (registers)->contents[i]);
70 inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (registers)->contents[0]);
71 inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[1]);
72 inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[2]);
73 inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[3]);
74 inregs.x.si = (unsigned long) XFASTINT (XVECTOR (registers)->contents[4]);
75 inregs.x.di = (unsigned long) XFASTINT (XVECTOR (registers)->contents[5]);
76 inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (registers)->contents[6]);
77 inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (registers)->contents[7]);
79 int86 (no, &inregs, &outregs);
81 XVECTOR (registers)->contents[0] = make_number (outregs.x.ax);
82 XVECTOR (registers)->contents[1] = make_number (outregs.x.bx);
83 XVECTOR (registers)->contents[2] = make_number (outregs.x.cx);
84 XVECTOR (registers)->contents[3] = make_number (outregs.x.dx);
85 XVECTOR (registers)->contents[4] = make_number (outregs.x.si);
86 XVECTOR (registers)->contents[5] = make_number (outregs.x.di);
87 XVECTOR (registers)->contents[6] = make_number (outregs.x.cflag);
88 XVECTOR (registers)->contents[7] = make_number (outregs.x.flags);
90 return registers;
93 DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
94 doc: /* Read DOS memory at offset ADDRESS into VECTOR.
95 Return the updated VECTOR. */)
96 (Lisp_Object address, Lisp_Object vector)
98 register int i;
99 int offs, len;
100 char *buf;
102 CHECK_NUMBER (address);
103 offs = (unsigned long) XINT (address);
104 CHECK_VECTOR (vector);
105 len = ASIZE (vector);
106 if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
107 return Qnil;
108 buf = alloca (len);
109 dosmemget (offs, len, buf);
111 for (i = 0; i < len; i++)
112 XVECTOR (vector)->contents[i] = make_number (buf[i]);
114 return vector;
117 DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
118 doc: /* Write DOS memory at offset ADDRESS from VECTOR. */)
119 (Lisp_Object address, Lisp_Object vector)
121 register int i;
122 int offs, len;
123 char *buf;
125 CHECK_NUMBER (address);
126 offs = (unsigned long) XINT (address);
127 CHECK_VECTOR (vector);
128 len = ASIZE (vector);
129 if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
130 return Qnil;
131 buf = alloca (len);
133 for (i = 0; i < len; i++)
135 CHECK_NUMBER (XVECTOR (vector)->contents[i]);
136 buf[i] = (unsigned char) XFASTINT (XVECTOR (vector)->contents[i]) & 0xFF;
139 dosmemput (buf, len, offs);
140 return Qt;
143 DEFUN ("msdos-set-keyboard", Fmsdos_set_keyboard, Smsdos_set_keyboard, 1, 2, 0,
144 doc: /* Set keyboard layout according to COUNTRY-CODE.
145 If the optional argument ALLKEYS is non-nil, the keyboard is mapped for
146 all keys; otherwise it is only used when the ALT key is pressed.
147 The current keyboard layout is available in dos-keyboard-code. */)
148 (Lisp_Object country_code, Lisp_Object allkeys)
150 CHECK_NUMBER (country_code);
151 if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
152 return Qnil;
153 return Qt;
156 #ifndef HAVE_X_WINDOWS
157 /* Later we might want to control the mouse interface with this function,
158 e.g., with respect to non-80 column screen modes. */
160 DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
161 doc: /* Report whether a mouse is present. */)
162 (void)
164 if (have_mouse)
165 return Qt;
166 else
167 return Qnil;
169 #endif
171 DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
172 doc: /* Initialize and enable mouse if available. */)
173 (void)
175 if (have_mouse)
177 have_mouse = 1;
178 mouse_init ();
179 return Qt;
181 return Qnil;
184 DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
185 doc: /* Enable mouse if available. */)
186 (void)
188 if (have_mouse)
190 have_mouse = 1;
191 mouse_on ();
193 return have_mouse ? Qt : Qnil;
196 DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
197 doc: /* Disable mouse if available. */)
198 (void)
200 mouse_off ();
201 if (have_mouse) have_mouse = -1;
202 return Qnil;
205 DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "",
206 doc: /* Insert copy of screen contents prior to starting Emacs.
207 Return nil if startup screen is not available. */)
208 (void)
210 char *s;
211 int rows, cols, i, j;
213 if (!dos_get_saved_screen (&s, &rows, &cols))
214 return Qnil;
216 for (i = 0; i < rows; i++)
218 for (j = 0; j < cols; j++)
220 insert_char (*s);
221 s += 2;
223 insert_char ('\n');
226 return Qt;
229 unsigned char dos_country_info[DOS_COUNTRY_INFO];
230 static unsigned char usa_country_info[DOS_COUNTRY_INFO] = {
231 0, 0, /* date format */
232 '$', 0, 0, 0, 0, /* currency string */
233 ',', 0, /* thousands separator */
234 '.', 0, /* decimal separator */
235 '/', 0, /* date separator */
236 ':', 0, /* time separator */
237 0, /* currency format */
238 2, /* digits after decimal in currency */
239 0, /* time format */
240 0, 0, 0, 0, /* address of case map routine, GPF if used */
241 ' ', 0, /* data-list separator (?) */
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* reserved */
245 #ifndef HAVE_X_WINDOWS
246 static unsigned dos_windows_version;
247 char parent_vm_title[50]; /* Ralf Brown says 30 is enough */
248 int w95_set_virtual_machine_title (const char *);
250 void
251 restore_parent_vm_title (void)
253 if (NILP (Vdos_windows_version))
254 return;
255 if ((dos_windows_version & 0xff) >= 4 && parent_vm_title[0])
256 w95_set_virtual_machine_title (parent_vm_title);
257 delay (50);
259 #endif /* !HAVE_X_WINDOWS */
261 void
262 init_dosfns (void)
264 union REGS regs;
265 _go32_dpmi_registers dpmiregs;
266 unsigned long xbuf = _go32_info_block.linear_address_of_transfer_buffer;
268 #ifndef SYSTEM_MALLOC
269 extern void get_lim_data (void);
271 get_lim_data (); /* why the hell isn't this called elsewhere? */
272 #endif
274 regs.x.ax = 0x3000;
275 intdos (&regs, &regs);
276 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
278 /* Obtain the country code via DPMI, use DJGPP transfer buffer. */
279 dpmiregs.x.ax = 0x3800;
280 dpmiregs.x.ds = xbuf >> 4;
281 dpmiregs.x.dx = 0;
282 dpmiregs.x.ss = dpmiregs.x.sp = dpmiregs.x.flags = 0;
283 _go32_dpmi_simulate_int (0x21, &dpmiregs);
284 if (dpmiregs.x.flags & 1)
286 dos_country_code = 1; /* assume USA if 213800 failed */
287 memcpy (dos_country_info, usa_country_info, DOS_COUNTRY_INFO);
289 else
291 dos_country_code = dpmiregs.x.bx;
292 dosmemget (xbuf, DOS_COUNTRY_INFO, dos_country_info);
295 dos_set_keyboard (dos_country_code, 0);
297 regs.x.ax = 0x6601;
298 intdos (&regs, &regs);
299 if (regs.x.cflag)
300 /* Estimate code page from country code */
301 switch (dos_country_code)
303 case 45: /* Denmark */
304 case 47: /* Norway */
305 dos_codepage = 865;
306 break;
307 default:
308 /* US */
309 dos_codepage = 437;
311 else
312 dos_codepage = regs.x.bx & 0xffff;
314 #ifndef HAVE_X_WINDOWS
315 parent_vm_title[0] = '\0';
317 /* If we are running from DOS box on MS-Windows, get Windows version. */
318 dpmiregs.x.ax = 0x1600; /* enhanced mode installation check */
319 dpmiregs.x.ss = dpmiregs.x.sp = dpmiregs.x.flags = 0;
320 _go32_dpmi_simulate_int (0x2f, &dpmiregs);
321 /* We only support Windows-specific features when we run on Windows 9X
322 or on Windows 3.X/enhanced mode.
324 Int 2Fh/AX=1600h returns:
326 AL = 00: no Windows at all;
327 AL = 01: Windows/386 2.x;
328 AL = 80h: Windows 3.x in mode other than enhanced;
329 AL = FFh: Windows/386 2.x
331 We also check AH > 0 (Windows 3.1 or later), in case AL tricks us. */
332 if (dpmiregs.h.al > 2 && dpmiregs.h.al != 0x80 && dpmiregs.h.al != 0xff
333 && (dpmiregs.h.al > 3 || dpmiregs.h.ah > 0))
335 dos_windows_version = dpmiregs.x.ax;
336 Vdos_windows_version =
337 Fcons (make_number (dpmiregs.h.al), make_number (dpmiregs.h.ah));
339 /* Save the current title of this virtual machine, so we can restore
340 it before exiting. Otherwise, Windows 95 will continue to use
341 the title we set even after we are history, stupido... */
342 if (dpmiregs.h.al >= 4)
344 dpmiregs.x.ax = 0x168e;
345 dpmiregs.x.dx = 3; /* get VM title */
346 dpmiregs.x.cx = sizeof (parent_vm_title) - 1;
347 dpmiregs.x.es = __tb >> 4;
348 dpmiregs.x.di = __tb & 15;
349 dpmiregs.x.sp = dpmiregs.x.ss = dpmiregs.x.flags = 0;
350 _go32_dpmi_simulate_int (0x2f, &dpmiregs);
351 if (dpmiregs.x.ax == 1)
352 dosmemget (__tb, sizeof (parent_vm_title), parent_vm_title);
355 else
357 dos_windows_version = 0;
358 Vdos_windows_version = Qnil;
360 #endif /* !HAVE_X_WINDOWS */
362 /* Without this, we never see hidden files.
363 Don't OR it with the previous value, so the value recorded at dump
364 time, possibly with `preserve-case' flags set, won't get through. */
365 __opendir_flags = __OPENDIR_FIND_HIDDEN;
367 #if __DJGPP_MINOR__ == 0
368 /* Under LFN, preserve the case of files as recorded in the directory
369 (in DJGPP 2.01 and later this is automagically done by the library). */
370 if (!NILP (Fmsdos_long_file_names ()))
371 __opendir_flags |= __OPENDIR_PRESERVE_CASE;
372 #endif /* __DJGPP_MINOR__ == 0 */
375 #ifndef HAVE_X_WINDOWS
377 /* Emulation of some X window features from xfns.c and xfaces.c. */
379 /* Standard VGA colors, in the order of their standard numbering
380 in the default VGA palette. */
381 static char *vga_colors[16] = {
382 "black", "blue", "green", "cyan", "red", "magenta", "brown",
383 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
384 "lightred", "lightmagenta", "yellow", "white"
387 /* Given a color name, return its index, or -1 if not found. Note
388 that this only performs case-insensitive comparison against the
389 standard names. For anything more sophisticated, like matching
390 "gray" with "grey" or translating X color names into their MSDOS
391 equivalents, call the Lisp function Qtty_color_desc (defined
392 on lisp/term/tty-colors.el). */
394 msdos_stdcolor_idx (const char *name)
396 int i;
398 for (i = 0; i < sizeof (vga_colors) / sizeof (vga_colors[0]); i++)
399 if (xstrcasecmp (name, vga_colors[i]) == 0)
400 return i;
402 return
403 strcmp (name, unspecified_fg) == 0 ? FACE_TTY_DEFAULT_FG_COLOR
404 : strcmp (name, unspecified_bg) == 0 ? FACE_TTY_DEFAULT_BG_COLOR
405 : FACE_TTY_DEFAULT_COLOR;
408 /* Given a color index, return its standard name. */
409 Lisp_Object
410 msdos_stdcolor_name (int idx)
412 extern Lisp_Object Qunspecified;
414 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
415 return build_string (unspecified_fg);
416 else if (idx == FACE_TTY_DEFAULT_BG_COLOR)
417 return build_string (unspecified_bg);
418 else if (idx >= 0 && idx < sizeof (vga_colors) / sizeof (vga_colors[0]))
419 return build_string (vga_colors[idx]);
420 else
421 return Qunspecified; /* meaning the default */
424 /* Support for features that are available when we run in a DOS box
425 on MS-Windows. */
427 ms_windows_version (void)
429 return dos_windows_version;
432 /* Set the title of the current virtual machine, to appear on
433 the caption bar of that machine's window. */
436 w95_set_virtual_machine_title (const char *title_string)
438 /* Only Windows 9X (version 4 and higher) support this function. */
439 if (!NILP (Vdos_windows_version)
440 && (dos_windows_version & 0xff) >= 4)
442 _go32_dpmi_registers regs;
443 dosmemput (title_string, strlen (title_string) + 1, __tb);
444 regs.x.ax = 0x168e;
445 regs.x.dx = 1;
446 regs.x.es = __tb >> 4;
447 regs.x.di = __tb & 15;
448 regs.x.sp = regs.x.ss = regs.x.flags = 0;
449 _go32_dpmi_simulate_int (0x2f, &regs);
450 return regs.x.ax == 1;
452 return 0;
455 /* Change the title of frame F to NAME.
456 If NAME is nil, use the frame name as the title.
458 If Emacs is not run from a DOS box on Windows 9X, this only
459 sets the name in the frame struct, but has no other effects. */
461 void
462 x_set_title (struct frame *f, Lisp_Object name)
464 /* Don't change the title if it's already NAME. */
465 if (EQ (name, f->title))
466 return;
468 update_mode_lines = 1;
470 f->title = name;
472 if (NILP (name))
473 name = f->name;
475 if (FRAME_MSDOS_P (f))
477 BLOCK_INPUT;
478 w95_set_virtual_machine_title (SDATA (name));
479 UNBLOCK_INPUT;
482 #endif /* !HAVE_X_WINDOWS */
484 DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
485 doc: /* Return storage information about the file system FILENAME is on.
486 Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
487 storage of the file system, FREE is the free storage, and AVAIL is the
488 storage available to a non-superuser. All 3 numbers are in bytes.
489 If the underlying system call fails, value is nil. */)
490 (Lisp_Object filename)
492 struct statfs stfs;
493 Lisp_Object encoded, value;
495 CHECK_STRING (filename);
496 filename = Fexpand_file_name (filename, Qnil);
497 encoded = ENCODE_FILE (filename);
499 if (statfs (SDATA (encoded), &stfs))
500 value = Qnil;
501 else
502 value = list3 (make_float ((double) stfs.f_bsize * stfs.f_blocks),
503 make_float ((double) stfs.f_bsize * stfs.f_bfree),
504 make_float ((double) stfs.f_bsize * stfs.f_bavail));
506 return value;
509 /* System depended enumeration of and access to system processes a-la
510 ps(1). Here, we only return info about the running Emacs process.
511 (There are no other processes on DOS, right?) */
513 Lisp_Object
514 list_system_processes (void)
516 Lisp_Object proclist = Qnil;
518 proclist = Fcons (make_fixnum_or_float (getpid ()), proclist);
520 return proclist;
523 Lisp_Object
524 system_process_attributes (Lisp_Object pid)
526 int proc_id;
527 Lisp_Object attrs = Qnil;
529 CHECK_NUMBER_OR_FLOAT (pid);
530 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
532 if (proc_id == getpid ())
534 EMACS_INT uid, gid;
535 char *usr;
536 struct group *gr;
537 char cmd[FILENAME_MAX];
538 char *cmdline = NULL, *p, *q;
539 size_t cmdline_size = 0;
540 int i;
541 Lisp_Object cmd_str, decoded_cmd, tem;
542 double pmem;
543 EXFUN (Fget_internal_run_time, 0);
544 #ifndef SYSTEM_MALLOC
545 extern unsigned long ret_lim_data ();
546 #endif
548 uid = getuid ();
549 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
550 usr = getlogin ();
551 if (usr)
552 attrs = Fcons (Fcons (Quser, build_string (usr)), attrs);
553 gid = getgid ();
554 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
555 gr = getgrgid (gid);
556 if (gr)
557 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
558 strcpy (cmd, basename (__crt0_argv[0]));
559 /* Command name is encoded in locale-coding-system; decode it. */
560 cmd_str = make_unibyte_string (cmd, strlen (cmd));
561 decoded_cmd = code_convert_string_norecord (cmd_str,
562 Vlocale_coding_system, 0);
563 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
564 /* Pretend we have 0 as PPID. */
565 attrs = Fcons (Fcons (Qppid, make_number (0)), attrs);
566 attrs = Fcons (Fcons (Qpgrp, pid), attrs);
567 attrs = Fcons (Fcons (Qttname, build_string ("/dev/tty")), attrs);
568 /* We are never idle! */
569 tem = Fget_internal_run_time ();
570 attrs = Fcons (Fcons (Qtime, tem), attrs);
571 attrs = Fcons (Fcons (Qthcount, make_number (1)), attrs);
572 attrs = Fcons (Fcons (Qstart,
573 Fsymbol_value (intern ("before-init-time"))),
574 attrs);
575 attrs = Fcons (Fcons (Qvsize,
576 make_fixnum_or_float ((unsigned long)sbrk (0)/1024)),
577 attrs);
578 attrs = Fcons (Fcons (Qetime, tem), attrs);
579 #ifndef SYSTEM_MALLOC
580 /* ret_lim_data is on vm-limit.c, which is not compiled in under
581 SYSTEM_MALLOC. */
582 pmem = (double)((unsigned long) sbrk (0)) / ret_lim_data () * 100.0;
583 if (pmem > 100)
584 #endif
585 pmem = 100;
586 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
587 /* Pass 1: Count how much storage we need. */
588 for (i = 0; i < __crt0_argc; i++)
590 cmdline_size += strlen (__crt0_argv[i]) + 1; /* +1 for blank delim */
591 if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
593 cmdline_size += 2;
594 for (p = __crt0_argv[i]; *p; p++)
596 if (*p == '"')
597 cmdline_size++;
601 /* Pass 2: Allocate storage and concatenate argv[]. */
602 cmdline = xmalloc (cmdline_size + 1);
603 for (i = 0, q = cmdline; i < __crt0_argc; i++)
605 if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
607 *q++ = '"';
608 for (p = __crt0_argv[i]; *p; p++)
610 if (*p == '\"')
611 *q++ = '\\';
612 *q++ = *p;
614 *q++ = '"';
616 else
618 strcpy (q, __crt0_argv[i]);
619 q += strlen (__crt0_argv[i]);
621 *q++ = ' ';
623 /* Remove the trailing blank. */
624 if (q > cmdline)
625 q[-1] = '\0';
627 /* Command line is encoded in locale-coding-system; decode it. */
628 cmd_str = make_unibyte_string (cmdline, strlen (cmdline));
629 decoded_cmd = code_convert_string_norecord (cmd_str,
630 Vlocale_coding_system, 0);
631 xfree (cmdline);
632 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
635 return attrs;
638 void
639 dos_cleanup (void)
641 struct tty_display_info *tty;
643 #ifndef HAVE_X_WINDOWS
644 restore_parent_vm_title ();
645 #endif
646 /* Make sure the termscript file is committed, in case we are
647 crashing and some vital info was written there. */
648 if (FRAMEP (selected_frame))
650 struct frame *sf = XFRAME (selected_frame);
652 if (FRAME_LIVE_P (sf)
653 && (FRAME_MSDOS_P (sf) || FRAME_TERMCAP_P (sf)))
655 tty = CURTTY ();
656 if (tty->termscript)
658 fflush (tty->termscript);
659 fsync (fileno (tty->termscript));
666 * Define everything
668 void
669 syms_of_dosfns (void)
671 defsubr (&Sint86);
672 defsubr (&Sdos_memget);
673 defsubr (&Sdos_memput);
674 defsubr (&Smsdos_mouse_init);
675 defsubr (&Smsdos_mouse_enable);
676 defsubr (&Smsdos_set_keyboard);
677 defsubr (&Sinsert_startup_screen);
678 defsubr (&Smsdos_mouse_disable);
679 defsubr (&Sfile_system_info);
680 #ifndef HAVE_X_WINDOWS
681 defsubr (&Smsdos_mouse_p);
682 #endif
684 DEFVAR_INT ("dos-country-code", dos_country_code,
685 doc: /* The country code returned by Dos when Emacs was started.
686 Usually this is the international telephone prefix. */);
688 DEFVAR_INT ("dos-codepage", dos_codepage,
689 doc: /* The codepage active when Emacs was started.
690 The following are known:
691 437 United States
692 850 Multilingual (Latin I)
693 852 Slavic (Latin II)
694 857 Turkish
695 860 Portugal
696 861 Iceland
697 863 Canada (French)
698 865 Norway/Denmark */);
700 DEFVAR_INT ("dos-timezone-offset", dos_timezone_offset,
701 doc: /* The current timezone offset to UTC in minutes.
702 Implicitly modified when the TZ variable is changed. */);
704 DEFVAR_LISP ("dos-version", Vdos_version,
705 doc: /* The (MAJOR . MINOR) Dos version (subject to modification with setver). */);
707 #ifndef HAVE_X_WINDOWS
708 DEFVAR_LISP ("dos-windows-version", Vdos_windows_version,
709 doc: /* The (MAJOR . MINOR) Windows version for DOS session on MS-Windows. */);
710 #endif
712 DEFVAR_LISP ("dos-display-scancodes", Vdos_display_scancodes,
713 doc: /* *Controls whether DOS raw keyboard events are displayed as you type.
714 When non-nil, the keyboard scan-codes are displayed at the bottom right
715 corner of the display (typically at the end of the mode line).
716 The output format is: scan code:char code*modifiers. */);
718 Vdos_display_scancodes = Qnil;
720 DEFVAR_INT ("dos-hyper-key", dos_hyper_key,
721 doc: /* *If set to 1, use right ALT key as hyper key.
722 If set to 2, use right CTRL key as hyper key. */);
723 dos_hyper_key = 0;
725 DEFVAR_INT ("dos-super-key", dos_super_key,
726 doc: /* *If set to 1, use right ALT key as super key.
727 If set to 2, use right CTRL key as super key. */);
728 dos_super_key = 0;
730 DEFVAR_INT ("dos-keypad-mode", dos_keypad_mode,
731 doc: /* *Controls what key code is returned by a key in the numeric keypad.
732 The `numlock ON' action is only taken if no modifier keys are pressed.
733 The value is an integer constructed by adding the following bits together:
735 0x00 Digit key returns digit (if numlock ON)
736 0x01 Digit key returns kp-digit (if numlock ON)
737 0x02 Digit key returns M-digit (if numlock ON)
738 0x03 Digit key returns edit key (if numlock ON)
740 0x00 Grey key returns char (if numlock ON)
741 0x04 Grey key returns kp-key (if numlock ON)
743 0x00 Digit key returns digit (if numlock OFF)
744 0x10 Digit key returns kp-digit (if numlock OFF)
745 0x20 Digit key returns M-digit (if numlock OFF)
746 0x30 Digit key returns edit key (if numlock OFF)
748 0x00 Grey key returns char (if numlock OFF)
749 0x40 Grey key returns kp-key (if numlock OFF)
751 0x200 ALT-0..ALT-9 in top-row produces shifted codes. */);
752 dos_keypad_mode = 0x75;
754 DEFVAR_INT ("dos-keyboard-layout", dos_keyboard_layout,
755 doc: /* Contains the country code for the current keyboard layout.
756 Use msdos-set-keyboard to select another keyboard layout. */);
757 dos_keyboard_layout = 1; /* US */
759 DEFVAR_INT ("dos-decimal-point", dos_decimal_point,
760 doc: /* The character to produce when kp-decimal key is pressed.
761 If non-zero, this variable contains the character to be returned when the
762 decimal point key in the numeric keypad is pressed when Num Lock is on.
763 If zero, the decimal point key returns the country code specific value. */);
764 dos_decimal_point = 0;
766 #endif /* MSDOS */