(IT_set_frame_parameters): Actually store the frame
[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)
3 Copyright (C) 1991, 1993 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
edfc0d45 9the Free Software Foundation; either version 2, or (at your option)
1b94449f
RS
10any later version.
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
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
1b94449f
RS
21
22
48984716 23#include <config.h>
1b94449f
RS
24
25#ifdef MSDOS
26/* The entire file is within this conditional */
27
28#include <stdio.h>
29#include <dos.h>
30#include "lisp.h"
31#include "buffer.h"
32#include "termchar.h"
33#include "termhooks.h"
34#include "frame.h"
35#include "dosfns.h"
36#include "msdos.h"
5f08dc78 37#include <go32.h>
50666766 38#include <dirent.h>
1b94449f 39
1b94449f
RS
40DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
41 "Call specific MSDOS interrupt number INTERRUPT with REGISTERS.\n\
42Return the updated REGISTER vector.\n\
43\n\
44INTERRUPT should be an integer in the range 0 to 255.\n\
45REGISTERS should be a vector produced by `make-register' and\n\
46`set-register-value'.")
e20104ba
EN
47 (interrupt, registers)
48 Lisp_Object interrupt, registers;
1b94449f
RS
49{
50 register int i;
51 int no;
52 union REGS inregs, outregs;
53 Lisp_Object val;
54
e20104ba
EN
55 CHECK_NUMBER (interrupt, 0);
56 no = (unsigned long) XINT (interrupt);
57 CHECK_VECTOR (registers, 1);
58 if (no < 0 || no > 0xff || XVECTOR (registers)-> size != 8)
1b94449f
RS
59 return Qnil;
60 for (i = 0; i < 8; i++)
e20104ba 61 CHECK_NUMBER (XVECTOR (registers)->contents[i], 1);
1b94449f 62
e20104ba
EN
63 inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (registers)->contents[0]);
64 inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[1]);
65 inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[2]);
66 inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (registers)->contents[3]);
67 inregs.x.si = (unsigned long) XFASTINT (XVECTOR (registers)->contents[4]);
68 inregs.x.di = (unsigned long) XFASTINT (XVECTOR (registers)->contents[5]);
69 inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (registers)->contents[6]);
70 inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (registers)->contents[7]);
1b94449f
RS
71
72 int86 (no, &inregs, &outregs);
73
e20104ba
EN
74 XVECTOR (registers)->contents[0] = make_number (outregs.x.ax);
75 XVECTOR (registers)->contents[1] = make_number (outregs.x.bx);
76 XVECTOR (registers)->contents[2] = make_number (outregs.x.cx);
77 XVECTOR (registers)->contents[3] = make_number (outregs.x.dx);
78 XVECTOR (registers)->contents[4] = make_number (outregs.x.si);
79 XVECTOR (registers)->contents[5] = make_number (outregs.x.di);
80 XVECTOR (registers)->contents[6] = make_number (outregs.x.cflag);
81 XVECTOR (registers)->contents[7] = make_number (outregs.x.flags);
1b94449f 82
e20104ba 83 return registers;
1b94449f
RS
84}
85
5f08dc78
KS
86DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
87 "Read DOS memory at offset ADDRESS into VECTOR.\n\
88Return the updated VECTOR.")
e20104ba
EN
89 (address, vector)
90 Lisp_Object address, vector;
5f08dc78
KS
91{
92 register int i;
93 int offs, len;
94 char *buf;
95 Lisp_Object val;
96
e20104ba
EN
97 CHECK_NUMBER (address, 0);
98 offs = (unsigned long) XINT (address);
99 CHECK_VECTOR (vector, 1);
100 len = XVECTOR (vector)-> size;
101 if (len < 1 || len > 2048 || address < 0 || address > 0xfffff - len)
5f08dc78
KS
102 return Qnil;
103 buf = alloca (len);
104 dosmemget (offs, len, buf);
105
106 for (i = 0; i < len; i++)
e20104ba 107 XVECTOR (vector)->contents[i] = make_number (buf[i]);
5f08dc78 108
e20104ba 109 return vector;
5f08dc78
KS
110}
111
112DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
113 "Write DOS memory at offset ADDRESS from VECTOR.")
e20104ba
EN
114 (address, vector)
115 Lisp_Object address, vector;
5f08dc78
KS
116{
117 register int i;
118 int offs, len;
119 char *buf;
120 Lisp_Object val;
121
e20104ba
EN
122 CHECK_NUMBER (address, 0);
123 offs = (unsigned long) XINT (address);
124 CHECK_VECTOR (vector, 1);
125 len = XVECTOR (vector)-> size;
126 if (len < 1 || len > 2048 || address < 0 || address > 0xfffff - len)
5f08dc78
KS
127 return Qnil;
128 buf = alloca (len);
129
130 for (i = 0; i < len; i++)
131 {
e20104ba
EN
132 CHECK_NUMBER (XVECTOR (vector)->contents[i], 1);
133 buf[i] = (unsigned char) XFASTINT (XVECTOR (vector)->contents[i]) & 0xFF;
5f08dc78
KS
134 }
135
136 dosmemput (buf, len, offs);
137 return Qt;
138}
139
140DEFUN ("msdos-set-keyboard", Fmsdos_set_keyboard, Smsdos_set_keyboard, 1, 2, 0,
e20104ba 141 "Set keyboard layout according to COUNTRY-CODE.\n\
5f08dc78
KS
142If the optional argument ALLKEYS is non-nil, the keyboard is mapped for\n\
143all keys; otherwise it is only used when the ALT key is pressed.\n\
144The current keyboard layout is available in dos-keyboard-code.")
145 (country_code, allkeys)
146 Lisp_Object country_code;
147{
148 CHECK_NUMBER (country_code, 0);
149 if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
150 return Qnil;
151 return Qt;
152}
153
87485d6f
MW
154#ifndef HAVE_X_WINDOWS
155/* Later we might want to control the mouse interface with this function,
156 e.g., with respect to non-80 column screen modes. */
157
158DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0, "\
159Report whether a mouse is present.")
160 ()
161{
162 if (have_mouse)
163 return Qt;
164 else
165 return Qnil;
166}
167
87485d6f
MW
168/* Function to translate colour names to integers. See lisp/term/pc-win.el
169 for its definition. */
170
171Lisp_Object Qmsdos_color_translate;
172#endif
173
ac3b0279
RS
174
175DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
176 "Initialize and enable mouse if available.")
177 ()
178{
5f08dc78
KS
179 if (have_mouse)
180 {
181 have_mouse = 1;
182 mouse_init ();
183 return Qt;
184 }
ac3b0279
RS
185 return Qnil;
186}
187
188DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
189 "Enable mouse if available.")
190 ()
191{
192 if (have_mouse)
193 {
5f08dc78
KS
194 have_mouse = 1;
195 mouse_on ();
ac3b0279
RS
196 }
197 return have_mouse ? Qt : Qnil;
198}
199
200DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
201 "Disable mouse if available.")
202 ()
203{
204 mouse_off ();
205 if (have_mouse) have_mouse = -1;
206 return Qnil;
207}
208
5f08dc78
KS
209DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "", "\
210Insert copy of screen contents prior to starting emacs.\n\
211Return nil if startup screen is not available.")
212 ()
213{
214 char *s;
215 int rows, cols;
216 int i, j;
217
218 if (!dos_get_saved_screen (&s, &rows, &cols))
219 return Qnil;
220
221 for (i = 0; i < rows; i++)
222 {
223 for (j = 0; j < cols; j++)
224 {
65788bc2 225 insert_char (*s);
5f08dc78
KS
226 s += 2;
227 }
65788bc2 228 insert_char ('\n');
5f08dc78
KS
229 }
230
231 return Qt;
232}
87485d6f 233\f
5f08dc78 234/* country info */
1b94449f
RS
235int dos_country_code;
236int dos_codepage;
5f08dc78
KS
237int dos_timezone_offset;
238int dos_decimal_point;
239int dos_keyboard_layout;
240unsigned char dos_country_info[DOS_COUNTRY_INFO];
241
242int dos_hyper_key;
243int dos_super_key;
244int dos_keypad_mode;
1b94449f 245
5f08dc78
KS
246Lisp_Object Vdos_version;
247Lisp_Object Vdos_display_scancodes;
5f08dc78 248
1b94449f
RS
249void
250init_dosfns ()
251{
252 union REGS regs;
253 _go32_dpmi_seginfo info;
254 _go32_dpmi_registers dpmiregs;
255
87485d6f 256#ifndef SYSTEM_MALLOC
1b94449f 257 get_lim_data (); /* why the hell isn't this called elsewhere? */
87485d6f 258#endif
1b94449f
RS
259
260 regs.x.ax = 0x3000;
261 intdos (&regs, &regs);
262 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
263
264 /* Obtain the country code by calling Dos via Dpmi. Don't rely on GO32. */
5f08dc78 265 info.size = (sizeof(dos_country_info) + 15) / 16;
1b94449f
RS
266 if (_go32_dpmi_allocate_dos_memory (&info))
267 dos_country_code = 1;
268 else
269 {
270 dpmiregs.x.ax = 0x3800;
271 dpmiregs.x.ds = info.rm_segment;
272 dpmiregs.x.dx = 0;
273 dpmiregs.x.ss = dpmiregs.x.sp = 0;
274 _go32_dpmi_simulate_int (0x21, &dpmiregs);
275 dos_country_code = dpmiregs.x.bx;
5f08dc78 276 dosmemget (info.rm_segment * 16, DOS_COUNTRY_INFO, dos_country_info);
1b94449f
RS
277 _go32_dpmi_free_dos_memory (&info);
278 }
5f08dc78 279 dos_set_keyboard (dos_country_code, 0);
1b94449f
RS
280
281 regs.x.ax = 0x6601;
282 intdos (&regs, &regs);
283 if (regs.x.cflag)
284 /* Estimate code page from country code */
285 switch (dos_country_code)
286 {
287 case 45: /* Denmark */
288 case 47: /* Norway */
289 dos_codepage = 865;
290 break;
291 default:
292 /* US */
293 dos_codepage = 437;
294 }
295 else
296 dos_codepage = regs.x.bx & 0xffff;
50666766
RS
297
298#if __DJGPP__ >= 2
299
459f4042
RS
300 /* Without this, we never see hidden files.
301 Don't OR it with the previous value, so the value recorded at dump
302 time, possibly with `preserve-case' flags set, won't get through. */
303 __opendir_flags = __OPENDIR_FIND_HIDDEN;
304
305#if __DJGPP_MINOR__ == 0
306 /* Under LFN, preserve the case of files as recorded in the directory
307 (in DJGPP 2.01 and later this is automagically done by the library). */
50666766
RS
308 if (!NILP (Fmsdos_long_file_names ()))
309 __opendir_flags |= __OPENDIR_PRESERVE_CASE;
459f4042
RS
310#endif /* __DJGPP_MINOR__ == 0 */
311#endif /* __DJGPP__ >= 2 */
1b94449f
RS
312}
313\f
314/*
315 * Define everything
316 */
317syms_of_dosfns ()
318{
1b94449f 319 defsubr (&Sint86);
5f08dc78
KS
320 defsubr (&Sdos_memget);
321 defsubr (&Sdos_memput);
ac3b0279
RS
322 defsubr (&Smsdos_mouse_init);
323 defsubr (&Smsdos_mouse_enable);
5f08dc78
KS
324 defsubr (&Smsdos_set_keyboard);
325 defsubr (&Sinsert_startup_screen);
ac3b0279 326 defsubr (&Smsdos_mouse_disable);
87485d6f
MW
327#ifndef HAVE_X_WINDOWS
328 defsubr (&Smsdos_mouse_p);
87485d6f
MW
329 Qmsdos_color_translate = intern ("msdos-color-translate");
330 staticpro (&Qmsdos_color_translate);
331#endif
1b94449f
RS
332
333 DEFVAR_INT ("dos-country-code", &dos_country_code,
334 "The country code returned by Dos when Emacs was started.\n\
335Usually this is the international telephone prefix.");
336
337 DEFVAR_INT ("dos-codepage", &dos_codepage,
5f08dc78 338 "The codepage active when Emacs was started.\n\
24ba360b
RS
339The following are known:\n\
340 437 United States\n\
341 850 Multilingual (Latin I)\n\
342 852 Slavic (Latin II)\n\
343 857 Turkish\n\
344 860 Portugal\n\
345 861 Iceland\n\
346 863 Canada (French)\n\
1b94449f
RS
347 865 Norway/Denmark");
348
5f08dc78
KS
349 DEFVAR_INT ("dos-timezone-offset", &dos_timezone_offset,
350 "The current timezone offset to UTC in minutes.
351Implicitly modified when the TZ variable is changed.");
352
1b94449f
RS
353 DEFVAR_LISP ("dos-version", &Vdos_version,
354 "The (MAJOR . MINOR) Dos version (subject to modification with setver).");
5f08dc78
KS
355
356 DEFVAR_LISP ("dos-display-scancodes", &Vdos_display_scancodes,
357 "*When non-nil, the keyboard scan-codes are displayed at the bottom right\n\
358corner of the display (typically at the end of the mode line).\n\
359The output format is: scan code:char code*modifiers.");
360 Vdos_display_scancodes = Qnil;
361
5f08dc78
KS
362 DEFVAR_INT ("dos-hyper-key", &dos_hyper_key,
363 "*If set to 1, use right ALT key as hyper key.\n\
364If set to 2, use right CTRL key as hyper key.");
365 dos_hyper_key = 0;
366
367 DEFVAR_INT ("dos-super-key", &dos_super_key,
368 "*If set to 1, use right ALT key as super key.\n\
369If set to 2, use right CTRL key as super key.");
370 dos_super_key = 0;
371
372 DEFVAR_INT ("dos-keypad-mode", &dos_keypad_mode,
373 "*Controls what key code is returned by a key in the numeric keypad.\n\
374The `numlock ON' action is only taken if no modifier keys are pressed.\n\
375The value is an integer constructed by adding the following bits together:\n\
376 \n\
377 0x00 Digit key returns digit (if numlock ON)\n\
378 0x01 Digit key returns kp-digit (if numlock ON)\n\
379 0x02 Digit key returns M-digit (if numlock ON)\n\
380 0x03 Digit key returns edit key (if numlock ON)\n\
381 \n\
382 0x00 Grey key returns char (if numlock ON)\n\
383 0x04 Grey key returns kp-key (if numlock ON)\n\
384 \n\
385 0x00 Digit key returns digit (if numlock OFF)\n\
386 0x10 Digit key returns kp-digit (if numlock OFF)\n\
387 0x20 Digit key returns M-digit (if numlock OFF)\n\
388 0x30 Digit key returns edit key (if numlock OFF)\n\
389 \n\
390 0x00 Grey key returns char (if numlock OFF)\n\
391 0x40 Grey key returns kp-key (if numlock OFF)\n\
392 \n\
393 0x200 ALT-0..ALT-9 in top-row produces shifted codes.");
b3d5621c 394 dos_keypad_mode = 0x75;
5f08dc78
KS
395
396 DEFVAR_INT ("dos-keyboard-layout", &dos_keyboard_layout,
397 "Contains the country code for the current keyboard layout.\n\
398Use msdos-set-keyboard to select another keyboard layout.");
399 dos_keyboard_layout = 1; /* US */
400
401 DEFVAR_INT ("dos-decimal-point", &dos_decimal_point,
402 "If non-zero, it contains the character to be returned when the\n\
403decimal point key in the numeric keypad is pressed when Num Lock is on.\n\
404If zero, the decimal point key returns the country code specific value.");
405 dos_decimal_point = 0;
1b94449f
RS
406}
407#endif /* MSDOS */