* alloc.c, bytecode.c, ccl.c, coding.c, composite.c, data.c, dosfns.c:
[bpt/emacs.git] / src / dosfns.c
CommitLineData
1b94449f
RS
1/* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991.
2 Major changes May-July 1993 Morten Welinder (only 10% original code left)
acaf905b 3 Copyright (C) 1991, 1993, 1996-1998, 2001-2012 Free Software Foundation, Inc.
1b94449f
RS
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
1b94449f 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
1b94449f
RS
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
1b94449f 19
48984716 20#include <config.h>
1b94449f
RS
21
22#ifdef MSDOS
23/* The entire file is within this conditional */
24
25#include <stdio.h>
26#include <dos.h>
d7306fe6 27#include <setjmp.h>
1b94449f 28#include "lisp.h"
e5560ff7 29#include "character.h"
1b94449f
RS
30#include "buffer.h"
31#include "termchar.h"
1b94449f 32#include "frame.h"
c06981c0 33#include "termhooks.h"
838a94b8
EZ
34#include "blockinput.h"
35#include "window.h"
1b94449f
RS
36#include "dosfns.h"
37#include "msdos.h"
e4441df0 38#include "dispextern.h"
76a76a57 39#include "coding.h"
e5c9f94c 40#include "process.h"
838a94b8 41#include <dpmi.h>
5f08dc78 42#include <go32.h>
50666766 43#include <dirent.h>
76a76a57 44#include <sys/vfs.h>
e5c9f94c
EZ
45#include <unistd.h>
46#include <grp.h>
47#include <crt0.h>
1b94449f 48
1b94449f 49DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
8fc29035 50 doc: /* Call specific MS-DOS interrupt number INTERRUPT with REGISTERS.
7363986a
PJ
51Return the updated REGISTER vector.
52
53INTERRUPT should be an integer in the range 0 to 255.
54REGISTERS should be a vector produced by `make-register' and
55`set-register-value'. */)
5842a27b 56 (Lisp_Object interrupt, Lisp_Object registers)
1b94449f
RS
57{
58 register int i;
59 int no;
60 union REGS inregs, outregs;
1b94449f 61
b7826503 62 CHECK_NUMBER (interrupt);
e20104ba 63 no = (unsigned long) XINT (interrupt);
b7826503 64 CHECK_VECTOR (registers);
8db90b73 65 if (no < 0 || no > 0xff || ASIZE (registers) != 8)
1b94449f
RS
66 return Qnil;
67 for (i = 0; i < 8; i++)
28be1ada 68 CHECK_NUMBER (AREF (registers, i));
1b94449f 69
28be1ada
DA
70 inregs.x.ax = (unsigned long) XFASTINT (AREF (registers, 0));
71 inregs.x.bx = (unsigned long) XFASTINT (AREF (registers, 1));
72 inregs.x.cx = (unsigned long) XFASTINT (AREF (registers, 2));
73 inregs.x.dx = (unsigned long) XFASTINT (AREF (registers, 3));
74 inregs.x.si = (unsigned long) XFASTINT (AREF (registers, 4));
75 inregs.x.di = (unsigned long) XFASTINT (AREF (registers, 5));
76 inregs.x.cflag = (unsigned long) XFASTINT (AREF (registers, 6));
77 inregs.x.flags = (unsigned long) XFASTINT (AREF (registers, 7));
1b94449f
RS
78
79 int86 (no, &inregs, &outregs);
80
28be1ada
DA
81 ASET (registers, 0, make_number (outregs.x.ax));
82 ASET (registers, 1, make_number (outregs.x.bx));
83 ASET (registers, 2, make_number (outregs.x.cx));
84 ASET (registers, 3, make_number (outregs.x.dx));
85 ASET (registers, 4, make_number (outregs.x.si));
86 ASET (registers, 5, make_number (outregs.x.di));
87 ASET (registers, 6, make_number (outregs.x.cflag));
88 ASET (registers, 7, make_number (outregs.x.flags));
1b94449f 89
e20104ba 90 return registers;
1b94449f
RS
91}
92
5f08dc78 93DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
7363986a
PJ
94 doc: /* Read DOS memory at offset ADDRESS into VECTOR.
95Return the updated VECTOR. */)
5842a27b 96 (Lisp_Object address, Lisp_Object vector)
5f08dc78
KS
97{
98 register int i;
99 int offs, len;
100 char *buf;
5f08dc78 101
b7826503 102 CHECK_NUMBER (address);
e20104ba 103 offs = (unsigned long) XINT (address);
b7826503 104 CHECK_VECTOR (vector);
8db90b73 105 len = ASIZE (vector);
238a44a8 106 if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
5f08dc78
KS
107 return Qnil;
108 buf = alloca (len);
109 dosmemget (offs, len, buf);
b058cb36 110
5f08dc78 111 for (i = 0; i < len; i++)
28be1ada 112 ASET (vector, i, make_number (buf[i]));
5f08dc78 113
e20104ba 114 return vector;
5f08dc78
KS
115}
116
117DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
7363986a 118 doc: /* Write DOS memory at offset ADDRESS from VECTOR. */)
5842a27b 119 (Lisp_Object address, Lisp_Object vector)
5f08dc78
KS
120{
121 register int i;
122 int offs, len;
123 char *buf;
5f08dc78 124
b7826503 125 CHECK_NUMBER (address);
e20104ba 126 offs = (unsigned long) XINT (address);
b7826503 127 CHECK_VECTOR (vector);
8db90b73 128 len = ASIZE (vector);
238a44a8 129 if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
5f08dc78
KS
130 return Qnil;
131 buf = alloca (len);
132
133 for (i = 0; i < len; i++)
134 {
28be1ada
DA
135 CHECK_NUMBER (AREF (vector, i));
136 buf[i] = (unsigned char) XFASTINT (AREF (vector, i)) & 0xFF;
5f08dc78
KS
137 }
138
139 dosmemput (buf, len, offs);
140 return Qt;
141}
142
143DEFUN ("msdos-set-keyboard", Fmsdos_set_keyboard, Smsdos_set_keyboard, 1, 2, 0,
7363986a
PJ
144 doc: /* Set keyboard layout according to COUNTRY-CODE.
145If the optional argument ALLKEYS is non-nil, the keyboard is mapped for
146all keys; otherwise it is only used when the ALT key is pressed.
147The current keyboard layout is available in dos-keyboard-code. */)
5842a27b 148 (Lisp_Object country_code, Lisp_Object allkeys)
5f08dc78 149{
b7826503 150 CHECK_NUMBER (country_code);
5f08dc78
KS
151 if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
152 return Qnil;
153 return Qt;
154}
155
87485d6f
MW
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. */
159
7363986a
PJ
160DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
161 doc: /* Report whether a mouse is present. */)
5842a27b 162 (void)
87485d6f
MW
163{
164 if (have_mouse)
165 return Qt;
166 else
167 return Qnil;
168}
87485d6f
MW
169#endif
170
ac3b0279 171DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
7363986a 172 doc: /* Initialize and enable mouse if available. */)
5842a27b 173 (void)
ac3b0279 174{
5f08dc78
KS
175 if (have_mouse)
176 {
177 have_mouse = 1;
178 mouse_init ();
179 return Qt;
180 }
ac3b0279
RS
181 return Qnil;
182}
183
184DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
7363986a 185 doc: /* Enable mouse if available. */)
5842a27b 186 (void)
ac3b0279
RS
187{
188 if (have_mouse)
189 {
5f08dc78
KS
190 have_mouse = 1;
191 mouse_on ();
ac3b0279
RS
192 }
193 return have_mouse ? Qt : Qnil;
194}
195
196DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
7363986a 197 doc: /* Disable mouse if available. */)
5842a27b 198 (void)
ac3b0279
RS
199{
200 mouse_off ();
201 if (have_mouse) have_mouse = -1;
202 return Qnil;
203}
204
7363986a 205DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "",
cd53fb50 206 doc: /* Insert copy of screen contents prior to starting Emacs.
7363986a 207Return nil if startup screen is not available. */)
5842a27b 208 (void)
5f08dc78
KS
209{
210 char *s;
b058cb36
EZ
211 int rows, cols, i, j;
212
5f08dc78
KS
213 if (!dos_get_saved_screen (&s, &rows, &cols))
214 return Qnil;
b058cb36 215
5f08dc78
KS
216 for (i = 0; i < rows; i++)
217 {
218 for (j = 0; j < cols; j++)
219 {
65788bc2 220 insert_char (*s);
5f08dc78
KS
221 s += 2;
222 }
65788bc2 223 insert_char ('\n');
5f08dc78
KS
224 }
225
226 return Qt;
227}
87485d6f 228\f
5f08dc78 229unsigned char dos_country_info[DOS_COUNTRY_INFO];
e089dc62
RS
230static 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 */
243};
5f08dc78 244
838a94b8
EZ
245#ifndef HAVE_X_WINDOWS
246static unsigned dos_windows_version;
838a94b8
EZ
247char parent_vm_title[50]; /* Ralf Brown says 30 is enough */
248int w95_set_virtual_machine_title (const char *);
249
250void
251restore_parent_vm_title (void)
252{
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);
258}
259#endif /* !HAVE_X_WINDOWS */
b058cb36 260
1b94449f 261void
3a8ce822 262init_dosfns (void)
1b94449f
RS
263{
264 union REGS regs;
1b94449f 265 _go32_dpmi_registers dpmiregs;
e089dc62 266 unsigned long xbuf = _go32_info_block.linear_address_of_transfer_buffer;
1b94449f 267
87485d6f 268#ifndef SYSTEM_MALLOC
891ef8f7
EZ
269 extern void get_lim_data (void);
270
1b94449f 271 get_lim_data (); /* why the hell isn't this called elsewhere? */
87485d6f 272#endif
1b94449f
RS
273
274 regs.x.ax = 0x3000;
275 intdos (&regs, &regs);
276 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
277
e089dc62
RS
278 /* Obtain the country code via DPMI, use DJGPP transfer buffer. */
279 dpmiregs.x.ax = 0x3800;
7a2fd369 280 dpmiregs.x.ds = xbuf >> 4;
e089dc62
RS
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)
285 {
286 dos_country_code = 1; /* assume USA if 213800 failed */
287 memcpy (dos_country_info, usa_country_info, DOS_COUNTRY_INFO);
288 }
1b94449f
RS
289 else
290 {
1b94449f 291 dos_country_code = dpmiregs.x.bx;
e089dc62 292 dosmemget (xbuf, DOS_COUNTRY_INFO, dos_country_info);
1b94449f 293 }
e089dc62 294
5f08dc78 295 dos_set_keyboard (dos_country_code, 0);
1b94449f
RS
296
297 regs.x.ax = 0x6601;
298 intdos (&regs, &regs);
299 if (regs.x.cflag)
300 /* Estimate code page from country code */
b058cb36 301 switch (dos_country_code)
1b94449f
RS
302 {
303 case 45: /* Denmark */
304 case 47: /* Norway */
305 dos_codepage = 865;
306 break;
307 default:
308 /* US */
309 dos_codepage = 437;
310 }
311 else
312 dos_codepage = regs.x.bx & 0xffff;
50666766 313
838a94b8
EZ
314#ifndef HAVE_X_WINDOWS
315 parent_vm_title[0] = '\0';
316
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.
323
324 Int 2Fh/AX=1600h returns:
325
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
330
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))
334 {
335 dos_windows_version = dpmiregs.x.ax;
336 Vdos_windows_version =
337 Fcons (make_number (dpmiregs.h.al), make_number (dpmiregs.h.ah));
338
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)
343 {
344 dpmiregs.x.ax = 0x168e;
345 dpmiregs.x.dx = 3; /* get VM title */
5e617bc2 346 dpmiregs.x.cx = sizeof (parent_vm_title) - 1;
838a94b8
EZ
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)
5e617bc2 352 dosmemget (__tb, sizeof (parent_vm_title), parent_vm_title);
838a94b8
EZ
353 }
354 }
355 else
356 {
357 dos_windows_version = 0;
358 Vdos_windows_version = Qnil;
359 }
360#endif /* !HAVE_X_WINDOWS */
361
459f4042
RS
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;
366
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). */
50666766
RS
370 if (!NILP (Fmsdos_long_file_names ()))
371 __opendir_flags |= __OPENDIR_PRESERVE_CASE;
459f4042 372#endif /* __DJGPP_MINOR__ == 0 */
1b94449f
RS
373}
374\f
838a94b8 375#ifndef HAVE_X_WINDOWS
e4441df0
EZ
376
377/* Emulation of some X window features from xfns.c and xfaces.c. */
378
379/* Standard VGA colors, in the order of their standard numbering
380 in the default VGA palette. */
381static char *vga_colors[16] = {
382 "black", "blue", "green", "cyan", "red", "magenta", "brown",
383 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
384 "lightred", "lightmagenta", "yellow", "white"
385};
386
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
2d764c78
EZ
391 equivalents, call the Lisp function Qtty_color_desc (defined
392 on lisp/term/tty-colors.el). */
e4441df0
EZ
393int
394msdos_stdcolor_idx (const char *name)
395{
396 int i;
397
398 for (i = 0; i < sizeof (vga_colors) / sizeof (vga_colors[0]); i++)
05131107 399 if (xstrcasecmp (name, vga_colors[i]) == 0)
e4441df0
EZ
400 return i;
401
f9d2fdc4 402 return
24480d5b
EZ
403 strcmp (name, unspecified_fg) == 0 ? FACE_TTY_DEFAULT_FG_COLOR
404 : strcmp (name, unspecified_bg) == 0 ? FACE_TTY_DEFAULT_BG_COLOR
f9d2fdc4 405 : FACE_TTY_DEFAULT_COLOR;
e4441df0
EZ
406}
407
408/* Given a color index, return its standard name. */
2d764c78 409Lisp_Object
e4441df0
EZ
410msdos_stdcolor_name (int idx)
411{
24480d5b
EZ
412 extern Lisp_Object Qunspecified;
413
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 */
e4441df0
EZ
422}
423
838a94b8
EZ
424/* Support for features that are available when we run in a DOS box
425 on MS-Windows. */
426int
427ms_windows_version (void)
428{
429 return dos_windows_version;
430}
431
432/* Set the title of the current virtual machine, to appear on
433 the caption bar of that machine's window. */
434
435int
436w95_set_virtual_machine_title (const char *title_string)
437{
438 /* Only Windows 9X (version 4 and higher) support this function. */
439 if (!NILP (Vdos_windows_version)
440 && (dos_windows_version & 0xff) >= 4)
441 {
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;
451 }
452 return 0;
453}
454
455/* Change the title of frame F to NAME.
456 If NAME is nil, use the frame name as the title.
457
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. */
460
461void
3a8ce822 462x_set_title (struct frame *f, Lisp_Object name)
838a94b8
EZ
463{
464 /* Don't change the title if it's already NAME. */
465 if (EQ (name, f->title))
466 return;
467
468 update_mode_lines = 1;
469
470 f->title = name;
471
472 if (NILP (name))
473 name = f->name;
474
475 if (FRAME_MSDOS_P (f))
476 {
477 BLOCK_INPUT;
d5db4077 478 w95_set_virtual_machine_title (SDATA (name));
838a94b8
EZ
479 UNBLOCK_INPUT;
480 }
481}
482#endif /* !HAVE_X_WINDOWS */
483\f
76a76a57 484DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
7363986a
PJ
485 doc: /* Return storage information about the file system FILENAME is on.
486Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
487storage of the file system, FREE is the free storage, and AVAIL is the
488storage available to a non-superuser. All 3 numbers are in bytes.
489If the underlying system call fails, value is nil. */)
5842a27b 490 (Lisp_Object filename)
76a76a57
EZ
491{
492 struct statfs stfs;
493 Lisp_Object encoded, value;
494
b7826503 495 CHECK_STRING (filename);
76a76a57
EZ
496 filename = Fexpand_file_name (filename, Qnil);
497 encoded = ENCODE_FILE (filename);
498
d5db4077 499 if (statfs (SDATA (encoded), &stfs))
76a76a57
EZ
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));
505
506 return value;
507}
508\f
e5c9f94c
EZ
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?) */
512
513Lisp_Object
3a8ce822 514list_system_processes (void)
e5c9f94c
EZ
515{
516 Lisp_Object proclist = Qnil;
517
518 proclist = Fcons (make_fixnum_or_float (getpid ()), proclist);
519
520 return proclist;
521}
522
523Lisp_Object
524system_process_attributes (Lisp_Object pid)
525{
526 int proc_id;
527 Lisp_Object attrs = Qnil;
528
529 CHECK_NUMBER_OR_FLOAT (pid);
530 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
531
532 if (proc_id == getpid ())
533 {
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;
891ef8f7 543 EXFUN (Fget_internal_run_time, 0);
693a2698 544#ifndef SYSTEM_MALLOC
e5c9f94c 545 extern unsigned long ret_lim_data ();
693a2698 546#endif
e5c9f94c
EZ
547
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,
5e617bc2 576 make_fixnum_or_float ((unsigned long)sbrk (0)/1024)),
e5c9f94c
EZ
577 attrs);
578 attrs = Fcons (Fcons (Qetime, tem), attrs);
693a2698
EZ
579#ifndef SYSTEM_MALLOC
580 /* ret_lim_data is on vm-limit.c, which is not compiled in under
581 SYSTEM_MALLOC. */
e5c9f94c
EZ
582 pmem = (double)((unsigned long) sbrk (0)) / ret_lim_data () * 100.0;
583 if (pmem > 100)
693a2698 584#endif
e5c9f94c
EZ
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++)
589 {
590 cmdline_size += strlen (__crt0_argv[i]) + 1; /* +1 for blank delim */
591 if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
592 {
593 cmdline_size += 2;
594 for (p = __crt0_argv[i]; *p; p++)
595 {
596 if (*p == '"')
597 cmdline_size++;
598 }
599 }
600 }
601 /* Pass 2: Allocate storage and concatenate argv[]. */
602 cmdline = xmalloc (cmdline_size + 1);
603 for (i = 0, q = cmdline; i < __crt0_argc; i++)
604 {
605 if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
606 {
607 *q++ = '"';
608 for (p = __crt0_argv[i]; *p; p++)
609 {
610 if (*p == '\"')
611 *q++ = '\\';
612 *q++ = *p;
613 }
614 *q++ = '"';
615 }
616 else
617 {
618 strcpy (q, __crt0_argv[i]);
619 q += strlen (__crt0_argv[i]);
620 }
621 *q++ = ' ';
622 }
623 /* Remove the trailing blank. */
624 if (q > cmdline)
625 q[-1] = '\0';
626
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);
633 }
634
635 return attrs;
636}
637\f
838a94b8
EZ
638void
639dos_cleanup (void)
640{
c06981c0
EZ
641 struct tty_display_info *tty;
642
838a94b8
EZ
643#ifndef HAVE_X_WINDOWS
644 restore_parent_vm_title ();
645#endif
6f855d64
EZ
646 /* Make sure the termscript file is committed, in case we are
647 crashing and some vital info was written there. */
c06981c0 648 if (FRAMEP (selected_frame))
6f855d64 649 {
c06981c0
EZ
650 struct frame *sf = XFRAME (selected_frame);
651
652 if (FRAME_LIVE_P (sf)
653 && (FRAME_MSDOS_P (sf) || FRAME_TERMCAP_P (sf)))
654 {
655 tty = CURTTY ();
656 if (tty->termscript)
657 {
658 fflush (tty->termscript);
659 fsync (fileno (tty->termscript));
660 }
661 }
6f855d64 662 }
838a94b8
EZ
663}
664
1b94449f
RS
665/*
666 * Define everything
667 */
3a8ce822
EZ
668void
669syms_of_dosfns (void)
1b94449f 670{
1b94449f 671 defsubr (&Sint86);
5f08dc78
KS
672 defsubr (&Sdos_memget);
673 defsubr (&Sdos_memput);
ac3b0279
RS
674 defsubr (&Smsdos_mouse_init);
675 defsubr (&Smsdos_mouse_enable);
5f08dc78
KS
676 defsubr (&Smsdos_set_keyboard);
677 defsubr (&Sinsert_startup_screen);
ac3b0279 678 defsubr (&Smsdos_mouse_disable);
76a76a57 679 defsubr (&Sfile_system_info);
87485d6f
MW
680#ifndef HAVE_X_WINDOWS
681 defsubr (&Smsdos_mouse_p);
87485d6f 682#endif
1b94449f 683
29208e82 684 DEFVAR_INT ("dos-country-code", dos_country_code,
7363986a
PJ
685 doc: /* The country code returned by Dos when Emacs was started.
686Usually this is the international telephone prefix. */);
1b94449f 687
29208e82 688 DEFVAR_INT ("dos-codepage", dos_codepage,
7363986a
PJ
689 doc: /* The codepage active when Emacs was started.
690The 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 */);
1b94449f 699
29208e82 700 DEFVAR_INT ("dos-timezone-offset", dos_timezone_offset,
7363986a
PJ
701 doc: /* The current timezone offset to UTC in minutes.
702Implicitly modified when the TZ variable is changed. */);
b058cb36 703
29208e82 704 DEFVAR_LISP ("dos-version", Vdos_version,
7363986a 705 doc: /* The (MAJOR . MINOR) Dos version (subject to modification with setver). */);
5f08dc78 706
838a94b8 707#ifndef HAVE_X_WINDOWS
29208e82 708 DEFVAR_LISP ("dos-windows-version", Vdos_windows_version,
7363986a 709 doc: /* The (MAJOR . MINOR) Windows version for DOS session on MS-Windows. */);
838a94b8
EZ
710#endif
711
29208e82 712 DEFVAR_LISP ("dos-display-scancodes", Vdos_display_scancodes,
fb7ada5f 713 doc: /* Whether DOS raw keyboard events are displayed as you type.
7363986a
PJ
714When non-nil, the keyboard scan-codes are displayed at the bottom right
715corner of the display (typically at the end of the mode line).
716The output format is: scan code:char code*modifiers. */);
717
5f08dc78 718 Vdos_display_scancodes = Qnil;
b058cb36 719
29208e82 720 DEFVAR_INT ("dos-hyper-key", dos_hyper_key,
fb7ada5f 721 doc: /* If set to 1, use right ALT key as hyper key.
7363986a 722If set to 2, use right CTRL key as hyper key. */);
5f08dc78 723 dos_hyper_key = 0;
b058cb36 724
29208e82 725 DEFVAR_INT ("dos-super-key", dos_super_key,
fb7ada5f 726 doc: /* If set to 1, use right ALT key as super key.
7363986a 727If set to 2, use right CTRL key as super key. */);
5f08dc78 728 dos_super_key = 0;
b058cb36 729
29208e82 730 DEFVAR_INT ("dos-keypad-mode", dos_keypad_mode,
fb7ada5f 731 doc: /* Controls what key code is returned by a key in the numeric keypad.
7363986a
PJ
732The `numlock ON' action is only taken if no modifier keys are pressed.
733The value is an integer constructed by adding the following bits together:
734
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)
739
740 0x00 Grey key returns char (if numlock ON)
741 0x04 Grey key returns kp-key (if numlock ON)
742
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)
747
748 0x00 Grey key returns char (if numlock OFF)
749 0x40 Grey key returns kp-key (if numlock OFF)
750
751 0x200 ALT-0..ALT-9 in top-row produces shifted codes. */);
b3d5621c 752 dos_keypad_mode = 0x75;
b058cb36 753
29208e82 754 DEFVAR_INT ("dos-keyboard-layout", dos_keyboard_layout,
7363986a
PJ
755 doc: /* Contains the country code for the current keyboard layout.
756Use msdos-set-keyboard to select another keyboard layout. */);
5f08dc78 757 dos_keyboard_layout = 1; /* US */
b058cb36 758
29208e82 759 DEFVAR_INT ("dos-decimal-point", dos_decimal_point,
7363986a
PJ
760 doc: /* The character to produce when kp-decimal key is pressed.
761If non-zero, this variable contains the character to be returned when the
762decimal point key in the numeric keypad is pressed when Num Lock is on.
763If zero, the decimal point key returns the country code specific value. */);
5f08dc78 764 dos_decimal_point = 0;
1b94449f
RS
765}
766#endif /* MSDOS */
6b61353c 767