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