5503
|
1 /* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991.
|
|
2 Major changes May-July 1993 Morten Welinder (only 10% original code left)
|
36513
|
3 Copyright (C) 1991, 1993, 1996, 1997, 1998, 2001
|
|
4 Free Software Foundation, Inc.
|
5503
|
5
|
|
6 This file is part of GNU Emacs.
|
|
7
|
|
8 GNU Emacs is free software; you can redistribute it and/or modify
|
|
9 it under the terms of the GNU General Public License as published by
|
10504
|
10 the Free Software Foundation; either version 2, or (at your option)
|
5503
|
11 any later version.
|
|
12
|
|
13 GNU Emacs is distributed in the hope that it will be useful,
|
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 GNU General Public License for more details.
|
|
17
|
|
18 You should have received a copy of the GNU General Public License
|
|
19 along with GNU Emacs; see the file COPYING. If not, write to
|
14186
|
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
21 Boston, MA 02111-1307, USA. */
|
5503
|
22
|
|
23
|
5980
|
24 #include <config.h>
|
5503
|
25
|
|
26 #ifdef MSDOS
|
|
27 /* The entire file is within this conditional */
|
|
28
|
|
29 #include <stdio.h>
|
25113
|
30 #include <string.h>
|
5503
|
31 #include <dos.h>
|
|
32 #include "lisp.h"
|
|
33 #include "buffer.h"
|
|
34 #include "termchar.h"
|
|
35 #include "termhooks.h"
|
|
36 #include "frame.h"
|
20034
|
37 #include "blockinput.h"
|
|
38 #include "window.h"
|
5503
|
39 #include "dosfns.h"
|
|
40 #include "msdos.h"
|
25113
|
41 #include "dispextern.h"
|
34348
|
42 #include "charset.h"
|
|
43 #include "coding.h"
|
20034
|
44 #include <dpmi.h>
|
13180
|
45 #include <go32.h>
|
15226
|
46 #include <dirent.h>
|
34348
|
47 #include <sys/vfs.h>
|
5503
|
48
|
20034
|
49 #ifndef __DJGPP_MINOR__
|
|
50 # define __tb _go32_info_block.linear_address_of_transfer_buffer;
|
|
51 #endif
|
|
52
|
5503
|
53 DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
|
41914
|
54 doc: /* Call specific MSDOS interrupt number INTERRUPT with REGISTERS.
|
|
55 Return the updated REGISTER vector.
|
|
56
|
|
57 INTERRUPT should be an integer in the range 0 to 255.
|
|
58 REGISTERS should be a vector produced by `make-register' and
|
|
59 `set-register-value'. */)
|
|
60 (interrupt, registers)
|
|
61 Lisp_Object interrupt, registers;
|
5503
|
62 {
|
|
63 register int i;
|
|
64 int no;
|
|
65 union REGS inregs, outregs;
|
|
66 Lisp_Object val;
|
|
67
|
40656
|
68 CHECK_NUMBER (interrupt);
|
14070
|
69 no = (unsigned long) XINT (interrupt);
|
40656
|
70 CHECK_VECTOR (registers);
|
14070
|
71 if (no < 0 || no > 0xff || XVECTOR (registers)-> size != 8)
|
5503
|
72 return Qnil;
|
|
73 for (i = 0; i < 8; i++)
|
40656
|
74 CHECK_NUMBER (XVECTOR (registers)->contents[i]);
|
5503
|
75
|
14070
|
76 inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (registers)->contents[0]);
|
|
77 inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[1]);
|
|
78 inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[2]);
|
|
79 inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[3]);
|
|
80 inregs.x.si = (unsigned long) XFASTINT (XVECTOR (registers)->contents[4]);
|
|
81 inregs.x.di = (unsigned long) XFASTINT (XVECTOR (registers)->contents[5]);
|
|
82 inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (registers)->contents[6]);
|
|
83 inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (registers)->contents[7]);
|
5503
|
84
|
|
85 int86 (no, &inregs, &outregs);
|
|
86
|
14070
|
87 XVECTOR (registers)->contents[0] = make_number (outregs.x.ax);
|
|
88 XVECTOR (registers)->contents[1] = make_number (outregs.x.bx);
|
|
89 XVECTOR (registers)->contents[2] = make_number (outregs.x.cx);
|
|
90 XVECTOR (registers)->contents[3] = make_number (outregs.x.dx);
|
|
91 XVECTOR (registers)->contents[4] = make_number (outregs.x.si);
|
|
92 XVECTOR (registers)->contents[5] = make_number (outregs.x.di);
|
|
93 XVECTOR (registers)->contents[6] = make_number (outregs.x.cflag);
|
|
94 XVECTOR (registers)->contents[7] = make_number (outregs.x.flags);
|
5503
|
95
|
14070
|
96 return registers;
|
5503
|
97 }
|
|
98
|
13180
|
99 DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
|
41914
|
100 doc: /* Read DOS memory at offset ADDRESS into VECTOR.
|
|
101 Return the updated VECTOR. */)
|
|
102 (address, vector)
|
|
103 Lisp_Object address, vector;
|
13180
|
104 {
|
|
105 register int i;
|
|
106 int offs, len;
|
|
107 char *buf;
|
|
108 Lisp_Object val;
|
|
109
|
40656
|
110 CHECK_NUMBER (address);
|
14070
|
111 offs = (unsigned long) XINT (address);
|
40656
|
112 CHECK_VECTOR (vector);
|
14070
|
113 len = XVECTOR (vector)-> size;
|
|
114 if (len < 1 || len > 2048 || address < 0 || address > 0xfffff - len)
|
13180
|
115 return Qnil;
|
|
116 buf = alloca (len);
|
|
117 dosmemget (offs, len, buf);
|
|
118
|
|
119 for (i = 0; i < len; i++)
|
14070
|
120 XVECTOR (vector)->contents[i] = make_number (buf[i]);
|
13180
|
121
|
14070
|
122 return vector;
|
13180
|
123 }
|
|
124
|
|
125 DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
|
41914
|
126 doc: /* Write DOS memory at offset ADDRESS from VECTOR. */)
|
|
127 (address, vector)
|
|
128 Lisp_Object address, vector;
|
13180
|
129 {
|
|
130 register int i;
|
|
131 int offs, len;
|
|
132 char *buf;
|
|
133 Lisp_Object val;
|
|
134
|
40656
|
135 CHECK_NUMBER (address);
|
14070
|
136 offs = (unsigned long) XINT (address);
|
40656
|
137 CHECK_VECTOR (vector);
|
14070
|
138 len = XVECTOR (vector)-> size;
|
|
139 if (len < 1 || len > 2048 || address < 0 || address > 0xfffff - len)
|
13180
|
140 return Qnil;
|
|
141 buf = alloca (len);
|
|
142
|
|
143 for (i = 0; i < len; i++)
|
|
144 {
|
40656
|
145 CHECK_NUMBER (XVECTOR (vector)->contents[i]);
|
14070
|
146 buf[i] = (unsigned char) XFASTINT (XVECTOR (vector)->contents[i]) & 0xFF;
|
13180
|
147 }
|
|
148
|
|
149 dosmemput (buf, len, offs);
|
|
150 return Qt;
|
|
151 }
|
|
152
|
|
153 DEFUN ("msdos-set-keyboard", Fmsdos_set_keyboard, Smsdos_set_keyboard, 1, 2, 0,
|
41914
|
154 doc: /* Set keyboard layout according to COUNTRY-CODE.
|
|
155 If the optional argument ALLKEYS is non-nil, the keyboard is mapped for
|
|
156 all keys; otherwise it is only used when the ALT key is pressed.
|
|
157 The current keyboard layout is available in dos-keyboard-code. */)
|
|
158 (country_code, allkeys)
|
|
159 Lisp_Object country_code;
|
13180
|
160 {
|
40656
|
161 CHECK_NUMBER (country_code);
|
13180
|
162 if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
|
|
163 return Qnil;
|
|
164 return Qt;
|
|
165 }
|
|
166
|
9572
|
167 #ifndef HAVE_X_WINDOWS
|
|
168 /* Later we might want to control the mouse interface with this function,
|
|
169 e.g., with respect to non-80 column screen modes. */
|
|
170
|
41914
|
171 DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
|
|
172 doc: /* Report whether a mouse is present. */)
|
9572
|
173 ()
|
|
174 {
|
|
175 if (have_mouse)
|
|
176 return Qt;
|
|
177 else
|
|
178 return Qnil;
|
|
179 }
|
|
180 #endif
|
|
181
|
12990
|
182
|
|
183 DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
|
41914
|
184 doc: /* Initialize and enable mouse if available. */)
|
|
185 ()
|
12990
|
186 {
|
13180
|
187 if (have_mouse)
|
|
188 {
|
|
189 have_mouse = 1;
|
|
190 mouse_init ();
|
|
191 return Qt;
|
|
192 }
|
12990
|
193 return Qnil;
|
|
194 }
|
|
195
|
|
196 DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
|
41914
|
197 doc: /* Enable mouse if available. */)
|
|
198 ()
|
12990
|
199 {
|
|
200 if (have_mouse)
|
|
201 {
|
13180
|
202 have_mouse = 1;
|
|
203 mouse_on ();
|
12990
|
204 }
|
|
205 return have_mouse ? Qt : Qnil;
|
|
206 }
|
|
207
|
|
208 DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
|
41914
|
209 doc: /* Disable mouse if available. */)
|
|
210 ()
|
12990
|
211 {
|
|
212 mouse_off ();
|
|
213 if (have_mouse) have_mouse = -1;
|
|
214 return Qnil;
|
|
215 }
|
|
216
|
41914
|
217 DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "",
|
|
218 doc: /* Insert copy of screen contents prior to starting emacs.
|
|
219 Return nil if startup screen is not available. */)
|
|
220 ()
|
13180
|
221 {
|
|
222 char *s;
|
|
223 int rows, cols;
|
|
224 int i, j;
|
|
225
|
|
226 if (!dos_get_saved_screen (&s, &rows, &cols))
|
|
227 return Qnil;
|
|
228
|
|
229 for (i = 0; i < rows; i++)
|
|
230 {
|
|
231 for (j = 0; j < cols; j++)
|
|
232 {
|
19288
bdc4b7818976
(Finsert_startup_screen): Call `insert_char' with a single argument.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
233 insert_char (*s);
|
13180
|
234 s += 2;
|
|
235 }
|
19288
bdc4b7818976
(Finsert_startup_screen): Call `insert_char' with a single argument.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
236 insert_char ('\n');
|
13180
|
237 }
|
|
238
|
|
239 return Qt;
|
|
240 }
|
9572
|
241
|
13180
|
242 /* country info */
|
43713
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
243 EMACS_INT dos_country_code;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
244 EMACS_INT dos_codepage;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
245 EMACS_INT dos_timezone_offset;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
246 EMACS_INT dos_decimal_point;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
247 EMACS_INT dos_keyboard_layout;
|
13180
|
248 unsigned char dos_country_info[DOS_COUNTRY_INFO];
|
19294
|
249 static unsigned char usa_country_info[DOS_COUNTRY_INFO] = {
|
|
250 0, 0, /* date format */
|
|
251 '$', 0, 0, 0, 0, /* currency string */
|
|
252 ',', 0, /* thousands separator */
|
|
253 '.', 0, /* decimal separator */
|
|
254 '/', 0, /* date separator */
|
|
255 ':', 0, /* time separator */
|
|
256 0, /* currency format */
|
|
257 2, /* digits after decimal in currency */
|
|
258 0, /* time format */
|
|
259 0, 0, 0, 0, /* address of case map routine, GPF if used */
|
|
260 ' ', 0, /* data-list separator (?) */
|
|
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* reserved */
|
|
262 };
|
13180
|
263
|
43713
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
264 EMACS_INT dos_hyper_key;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
265 EMACS_INT dos_super_key;
|
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
266 EMACS_INT dos_keypad_mode;
|
13180
|
267
|
5503
|
268 Lisp_Object Vdos_version;
|
13180
|
269 Lisp_Object Vdos_display_scancodes;
|
20034
|
270
|
|
271 #ifndef HAVE_X_WINDOWS
|
|
272 static unsigned dos_windows_version;
|
|
273 Lisp_Object Vdos_windows_version;
|
|
274
|
|
275 char parent_vm_title[50]; /* Ralf Brown says 30 is enough */
|
|
276 int w95_set_virtual_machine_title (const char *);
|
|
277
|
|
278 void
|
|
279 restore_parent_vm_title (void)
|
|
280 {
|
|
281 if (NILP (Vdos_windows_version))
|
|
282 return;
|
|
283 if ((dos_windows_version & 0xff) >= 4 && parent_vm_title[0])
|
|
284 w95_set_virtual_machine_title (parent_vm_title);
|
|
285 delay (50);
|
|
286 }
|
|
287 #endif /* !HAVE_X_WINDOWS */
|
13180
|
288
|
5503
|
289 void
|
|
290 init_dosfns ()
|
|
291 {
|
|
292 union REGS regs;
|
|
293 _go32_dpmi_registers dpmiregs;
|
19294
|
294 unsigned long xbuf = _go32_info_block.linear_address_of_transfer_buffer;
|
5503
|
295
|
9572
|
296 #ifndef SYSTEM_MALLOC
|
5503
|
297 get_lim_data (); /* why the hell isn't this called elsewhere? */
|
9572
|
298 #endif
|
5503
|
299
|
|
300 regs.x.ax = 0x3000;
|
|
301 intdos (®s, ®s);
|
|
302 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
|
|
303
|
19294
|
304 /* Obtain the country code via DPMI, use DJGPP transfer buffer. */
|
|
305 dpmiregs.x.ax = 0x3800;
|
21430
b6b154ad6e22
(init_dosfns): Fix bug in passing segment address of the transfer buffer.
Eli Zaretskii <eliz@gnu.org>
diff
changeset
|
306 dpmiregs.x.ds = xbuf >> 4;
|
19294
|
307 dpmiregs.x.dx = 0;
|
|
308 dpmiregs.x.ss = dpmiregs.x.sp = dpmiregs.x.flags = 0;
|
|
309 _go32_dpmi_simulate_int (0x21, &dpmiregs);
|
|
310 if (dpmiregs.x.flags & 1)
|
|
311 {
|
|
312 dos_country_code = 1; /* assume USA if 213800 failed */
|
|
313 memcpy (dos_country_info, usa_country_info, DOS_COUNTRY_INFO);
|
|
314 }
|
5503
|
315 else
|
|
316 {
|
|
317 dos_country_code = dpmiregs.x.bx;
|
19294
|
318 dosmemget (xbuf, DOS_COUNTRY_INFO, dos_country_info);
|
5503
|
319 }
|
19294
|
320
|
13180
|
321 dos_set_keyboard (dos_country_code, 0);
|
5503
|
322
|
|
323 regs.x.ax = 0x6601;
|
|
324 intdos (®s, ®s);
|
|
325 if (regs.x.cflag)
|
|
326 /* Estimate code page from country code */
|
|
327 switch (dos_country_code)
|
|
328 {
|
|
329 case 45: /* Denmark */
|
|
330 case 47: /* Norway */
|
|
331 dos_codepage = 865;
|
|
332 break;
|
|
333 default:
|
|
334 /* US */
|
|
335 dos_codepage = 437;
|
|
336 }
|
|
337 else
|
|
338 dos_codepage = regs.x.bx & 0xffff;
|
15226
|
339
|
20034
|
340 #ifndef HAVE_X_WINDOWS
|
|
341 parent_vm_title[0] = '\0';
|
|
342
|
|
343 /* If we are running from DOS box on MS-Windows, get Windows version. */
|
|
344 dpmiregs.x.ax = 0x1600; /* enhanced mode installation check */
|
|
345 dpmiregs.x.ss = dpmiregs.x.sp = dpmiregs.x.flags = 0;
|
|
346 _go32_dpmi_simulate_int (0x2f, &dpmiregs);
|
|
347 /* We only support Windows-specific features when we run on Windows 9X
|
|
348 or on Windows 3.X/enhanced mode.
|
|
349
|
|
350 Int 2Fh/AX=1600h returns:
|
|
351
|
|
352 AL = 00: no Windows at all;
|
|
353 AL = 01: Windows/386 2.x;
|
|
354 AL = 80h: Windows 3.x in mode other than enhanced;
|
|
355 AL = FFh: Windows/386 2.x
|
|
356
|
|
357 We also check AH > 0 (Windows 3.1 or later), in case AL tricks us. */
|
|
358 if (dpmiregs.h.al > 2 && dpmiregs.h.al != 0x80 && dpmiregs.h.al != 0xff
|
|
359 && (dpmiregs.h.al > 3 || dpmiregs.h.ah > 0))
|
|
360 {
|
|
361 dos_windows_version = dpmiregs.x.ax;
|
|
362 Vdos_windows_version =
|
|
363 Fcons (make_number (dpmiregs.h.al), make_number (dpmiregs.h.ah));
|
|
364
|
|
365 /* Save the current title of this virtual machine, so we can restore
|
|
366 it before exiting. Otherwise, Windows 95 will continue to use
|
|
367 the title we set even after we are history, stupido... */
|
|
368 if (dpmiregs.h.al >= 4)
|
|
369 {
|
|
370 dpmiregs.x.ax = 0x168e;
|
|
371 dpmiregs.x.dx = 3; /* get VM title */
|
|
372 dpmiregs.x.cx = sizeof(parent_vm_title) - 1;
|
|
373 dpmiregs.x.es = __tb >> 4;
|
|
374 dpmiregs.x.di = __tb & 15;
|
|
375 dpmiregs.x.sp = dpmiregs.x.ss = dpmiregs.x.flags = 0;
|
|
376 _go32_dpmi_simulate_int (0x2f, &dpmiregs);
|
|
377 if (dpmiregs.x.ax == 1)
|
|
378 dosmemget (__tb, sizeof(parent_vm_title), parent_vm_title);
|
|
379 }
|
|
380 }
|
|
381 else
|
|
382 {
|
|
383 dos_windows_version = 0;
|
|
384 Vdos_windows_version = Qnil;
|
|
385 }
|
|
386 #endif /* !HAVE_X_WINDOWS */
|
|
387
|
15226
|
388 #if __DJGPP__ >= 2
|
|
389
|
16335
|
390 /* Without this, we never see hidden files.
|
|
391 Don't OR it with the previous value, so the value recorded at dump
|
|
392 time, possibly with `preserve-case' flags set, won't get through. */
|
|
393 __opendir_flags = __OPENDIR_FIND_HIDDEN;
|
15226
|
394
|
16335
|
395 #if __DJGPP_MINOR__ == 0
|
|
396 /* Under LFN, preserve the case of files as recorded in the directory
|
|
397 (in DJGPP 2.01 and later this is automagically done by the library). */
|
15226
|
398 if (!NILP (Fmsdos_long_file_names ()))
|
|
399 __opendir_flags |= __OPENDIR_PRESERVE_CASE;
|
16335
|
400 #endif /* __DJGPP_MINOR__ == 0 */
|
|
401 #endif /* __DJGPP__ >= 2 */
|
5503
|
402 }
|
|
403
|
20034
|
404 #ifndef HAVE_X_WINDOWS
|
25113
|
405
|
|
406 /* Emulation of some X window features from xfns.c and xfaces.c. */
|
|
407
|
|
408 /* Standard VGA colors, in the order of their standard numbering
|
|
409 in the default VGA palette. */
|
|
410 static char *vga_colors[16] = {
|
|
411 "black", "blue", "green", "cyan", "red", "magenta", "brown",
|
|
412 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
|
|
413 "lightred", "lightmagenta", "yellow", "white"
|
|
414 };
|
|
415
|
|
416 /* Given a color name, return its index, or -1 if not found. Note
|
|
417 that this only performs case-insensitive comparison against the
|
|
418 standard names. For anything more sophisticated, like matching
|
|
419 "gray" with "grey" or translating X color names into their MSDOS
|
26729
|
420 equivalents, call the Lisp function Qtty_color_desc (defined
|
|
421 on lisp/term/tty-colors.el). */
|
25113
|
422 int
|
|
423 msdos_stdcolor_idx (const char *name)
|
|
424 {
|
|
425 int i;
|
|
426
|
|
427 for (i = 0; i < sizeof (vga_colors) / sizeof (vga_colors[0]); i++)
|
|
428 if (strcasecmp (name, vga_colors[i]) == 0)
|
|
429 return i;
|
|
430
|
26902
|
431 return
|
27115
|
432 strcmp (name, unspecified_fg) == 0 ? FACE_TTY_DEFAULT_FG_COLOR
|
|
433 : strcmp (name, unspecified_bg) == 0 ? FACE_TTY_DEFAULT_BG_COLOR
|
26902
|
434 : FACE_TTY_DEFAULT_COLOR;
|
25113
|
435 }
|
|
436
|
|
437 /* Given a color index, return its standard name. */
|
26729
|
438 Lisp_Object
|
25113
|
439 msdos_stdcolor_name (int idx)
|
|
440 {
|
27115
|
441 extern Lisp_Object Qunspecified;
|
26729
|
442
|
27115
|
443 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
|
|
444 return build_string (unspecified_fg);
|
|
445 else if (idx == FACE_TTY_DEFAULT_BG_COLOR)
|
|
446 return build_string (unspecified_bg);
|
|
447 else if (idx >= 0 && idx < sizeof (vga_colors) / sizeof (vga_colors[0]))
|
|
448 return build_string (vga_colors[idx]);
|
|
449 else
|
|
450 return Qunspecified; /* meaning the default */
|
25113
|
451 }
|
|
452
|
20034
|
453 /* Support for features that are available when we run in a DOS box
|
|
454 on MS-Windows. */
|
|
455 int
|
|
456 ms_windows_version (void)
|
|
457 {
|
|
458 return dos_windows_version;
|
|
459 }
|
|
460
|
|
461 /* Set the title of the current virtual machine, to appear on
|
|
462 the caption bar of that machine's window. */
|
|
463
|
|
464 int
|
|
465 w95_set_virtual_machine_title (const char *title_string)
|
|
466 {
|
|
467 /* Only Windows 9X (version 4 and higher) support this function. */
|
|
468 if (!NILP (Vdos_windows_version)
|
|
469 && (dos_windows_version & 0xff) >= 4)
|
|
470 {
|
|
471 _go32_dpmi_registers regs;
|
|
472 dosmemput (title_string, strlen (title_string) + 1, __tb);
|
|
473 regs.x.ax = 0x168e;
|
|
474 regs.x.dx = 1;
|
|
475 regs.x.es = __tb >> 4;
|
|
476 regs.x.di = __tb & 15;
|
|
477 regs.x.sp = regs.x.ss = regs.x.flags = 0;
|
|
478 _go32_dpmi_simulate_int (0x2f, ®s);
|
|
479 return regs.x.ax == 1;
|
|
480 }
|
|
481 return 0;
|
|
482 }
|
|
483
|
|
484 /* Change the title of frame F to NAME.
|
|
485 If NAME is nil, use the frame name as the title.
|
|
486
|
|
487 If Emacs is not run from a DOS box on Windows 9X, this only
|
|
488 sets the name in the frame struct, but has no other effects. */
|
|
489
|
|
490 void
|
|
491 x_set_title (f, name)
|
|
492 struct frame *f;
|
|
493 Lisp_Object name;
|
|
494 {
|
|
495 /* Don't change the title if it's already NAME. */
|
|
496 if (EQ (name, f->title))
|
|
497 return;
|
|
498
|
|
499 update_mode_lines = 1;
|
|
500
|
|
501 f->title = name;
|
|
502
|
|
503 if (NILP (name))
|
|
504 name = f->name;
|
|
505
|
|
506 if (FRAME_MSDOS_P (f))
|
|
507 {
|
|
508 BLOCK_INPUT;
|
|
509 w95_set_virtual_machine_title (XSTRING (name)->data);
|
|
510 UNBLOCK_INPUT;
|
|
511 }
|
|
512 }
|
|
513 #endif /* !HAVE_X_WINDOWS */
|
|
514
|
34348
|
515 DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
|
41914
|
516 doc: /* Return storage information about the file system FILENAME is on.
|
|
517 Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
|
|
518 storage of the file system, FREE is the free storage, and AVAIL is the
|
|
519 storage available to a non-superuser. All 3 numbers are in bytes.
|
|
520 If the underlying system call fails, value is nil. */)
|
|
521 (filename)
|
|
522 Lisp_Object filename;
|
34348
|
523 {
|
|
524 struct statfs stfs;
|
|
525 Lisp_Object encoded, value;
|
|
526
|
40656
|
527 CHECK_STRING (filename);
|
34348
|
528 filename = Fexpand_file_name (filename, Qnil);
|
|
529 encoded = ENCODE_FILE (filename);
|
|
530
|
|
531 if (statfs (XSTRING (encoded)->data, &stfs))
|
|
532 value = Qnil;
|
|
533 else
|
|
534 value = list3 (make_float ((double) stfs.f_bsize * stfs.f_blocks),
|
|
535 make_float ((double) stfs.f_bsize * stfs.f_bfree),
|
|
536 make_float ((double) stfs.f_bsize * stfs.f_bavail));
|
|
537
|
|
538 return value;
|
|
539 }
|
|
540
|
20034
|
541 void
|
|
542 dos_cleanup (void)
|
|
543 {
|
|
544 #ifndef HAVE_X_WINDOWS
|
|
545 restore_parent_vm_title ();
|
|
546 #endif
|
23814
|
547 /* Make sure the termscript file is committed, in case we are
|
|
548 crashing and some vital info was written there. */
|
|
549 if (termscript)
|
|
550 {
|
|
551 fflush (termscript);
|
|
552 fsync (fileno (termscript));
|
|
553 }
|
20034
|
554 }
|
|
555
|
5503
|
556 /*
|
|
557 * Define everything
|
|
558 */
|
|
559 syms_of_dosfns ()
|
|
560 {
|
|
561 defsubr (&Sint86);
|
13180
|
562 defsubr (&Sdos_memget);
|
|
563 defsubr (&Sdos_memput);
|
12990
|
564 defsubr (&Smsdos_mouse_init);
|
|
565 defsubr (&Smsdos_mouse_enable);
|
13180
|
566 defsubr (&Smsdos_set_keyboard);
|
|
567 defsubr (&Sinsert_startup_screen);
|
12990
|
568 defsubr (&Smsdos_mouse_disable);
|
34348
|
569 defsubr (&Sfile_system_info);
|
9572
|
570 #ifndef HAVE_X_WINDOWS
|
|
571 defsubr (&Smsdos_mouse_p);
|
|
572 #endif
|
5503
|
573
|
|
574 DEFVAR_INT ("dos-country-code", &dos_country_code,
|
41914
|
575 doc: /* The country code returned by Dos when Emacs was started.
|
|
576 Usually this is the international telephone prefix. */);
|
5503
|
577
|
|
578 DEFVAR_INT ("dos-codepage", &dos_codepage,
|
41914
|
579 doc: /* The codepage active when Emacs was started.
|
|
580 The following are known:
|
|
581 437 United States
|
|
582 850 Multilingual (Latin I)
|
|
583 852 Slavic (Latin II)
|
|
584 857 Turkish
|
|
585 860 Portugal
|
|
586 861 Iceland
|
|
587 863 Canada (French)
|
|
588 865 Norway/Denmark */);
|
5503
|
589
|
13180
|
590 DEFVAR_INT ("dos-timezone-offset", &dos_timezone_offset,
|
41914
|
591 doc: /* The current timezone offset to UTC in minutes.
|
|
592 Implicitly modified when the TZ variable is changed. */);
|
13180
|
593
|
5503
|
594 DEFVAR_LISP ("dos-version", &Vdos_version,
|
41914
|
595 doc: /* The (MAJOR . MINOR) Dos version (subject to modification with setver). */);
|
13180
|
596
|
20034
|
597 #ifndef HAVE_X_WINDOWS
|
|
598 DEFVAR_LISP ("dos-windows-version", &Vdos_windows_version,
|
41914
|
599 doc: /* The (MAJOR . MINOR) Windows version for DOS session on MS-Windows. */);
|
20034
|
600 #endif
|
|
601
|
13180
|
602 DEFVAR_LISP ("dos-display-scancodes", &Vdos_display_scancodes,
|
41914
|
603 doc: /* *Controls whether DOS raw keyboard events are displayed as you type.
|
|
604 When non-nil, the keyboard scan-codes are displayed at the bottom right
|
|
605 corner of the display (typically at the end of the mode line).
|
|
606 The output format is: scan code:char code*modifiers. */);
|
|
607
|
13180
|
608 Vdos_display_scancodes = Qnil;
|
|
609
|
|
610 DEFVAR_INT ("dos-hyper-key", &dos_hyper_key,
|
41914
|
611 doc: /* *If set to 1, use right ALT key as hyper key.
|
|
612 If set to 2, use right CTRL key as hyper key. */);
|
13180
|
613 dos_hyper_key = 0;
|
|
614
|
|
615 DEFVAR_INT ("dos-super-key", &dos_super_key,
|
41914
|
616 doc: /* *If set to 1, use right ALT key as super key.
|
|
617 If set to 2, use right CTRL key as super key. */);
|
13180
|
618 dos_super_key = 0;
|
|
619
|
|
620 DEFVAR_INT ("dos-keypad-mode", &dos_keypad_mode,
|
41914
|
621 doc: /* *Controls what key code is returned by a key in the numeric keypad.
|
|
622 The `numlock ON' action is only taken if no modifier keys are pressed.
|
|
623 The value is an integer constructed by adding the following bits together:
|
|
624
|
|
625 0x00 Digit key returns digit (if numlock ON)
|
|
626 0x01 Digit key returns kp-digit (if numlock ON)
|
|
627 0x02 Digit key returns M-digit (if numlock ON)
|
|
628 0x03 Digit key returns edit key (if numlock ON)
|
|
629
|
|
630 0x00 Grey key returns char (if numlock ON)
|
|
631 0x04 Grey key returns kp-key (if numlock ON)
|
|
632
|
|
633 0x00 Digit key returns digit (if numlock OFF)
|
|
634 0x10 Digit key returns kp-digit (if numlock OFF)
|
|
635 0x20 Digit key returns M-digit (if numlock OFF)
|
|
636 0x30 Digit key returns edit key (if numlock OFF)
|
|
637
|
|
638 0x00 Grey key returns char (if numlock OFF)
|
|
639 0x40 Grey key returns kp-key (if numlock OFF)
|
|
640
|
|
641 0x200 ALT-0..ALT-9 in top-row produces shifted codes. */);
|
13612
|
642 dos_keypad_mode = 0x75;
|
13180
|
643
|
|
644 DEFVAR_INT ("dos-keyboard-layout", &dos_keyboard_layout,
|
41914
|
645 doc: /* Contains the country code for the current keyboard layout.
|
|
646 Use msdos-set-keyboard to select another keyboard layout. */);
|
13180
|
647 dos_keyboard_layout = 1; /* US */
|
|
648
|
|
649 DEFVAR_INT ("dos-decimal-point", &dos_decimal_point,
|
41914
|
650 doc: /* The character to produce when kp-decimal key is pressed.
|
|
651 If non-zero, this variable contains the character to be returned when the
|
|
652 decimal point key in the numeric keypad is pressed when Num Lock is on.
|
|
653 If zero, the decimal point key returns the country code specific value. */);
|
13180
|
654 dos_decimal_point = 0;
|
5503
|
655 }
|
|
656 #endif /* MSDOS */
|