Initial revision
[emacs.git] / src / dosfns.c
blob2b4ca88fce19b629d71fc1e2d40d78453e4fe773
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.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include <config.h>
24 #ifdef MSDOS
25 /* The entire file is within this conditional */
27 #include <stdio.h>
28 #include <dos.h>
29 #include "lisp.h"
30 #include "buffer.h"
31 #include "termchar.h"
32 #include "termhooks.h"
33 #include "frame.h"
34 #include "dosfns.h"
35 #include "msdos.h"
37 DEFUN ("mode25", Fmode25, Smode25, 0, 0, "", "\
38 Changes the number of rows to 25.")
41 union REGS regs;
43 #ifdef HAVE_X_WINDOWS
44 if (!inhibit_window_system)
45 return Qnil;
46 #endif
47 mouse_off ();
48 regs.x.ax = 3;
49 int86 (0x10, &regs, &regs);
50 regs.x.ax = 0x1101;
51 regs.h.bl = 0;
52 int86 (0x10, &regs, &regs);
53 regs.x.ax = 0x1200;
54 regs.h.bl = 32;
55 int86 (0x10, &regs, &regs);
56 regs.x.ax = 3;
57 int86 (0x10, &regs, &regs);
58 Fset_frame_size (Fselected_frame (), ScreenCols (), ScreenRows ());
59 Frecenter (Qnil);
60 Fredraw_display ();
61 if (have_mouse) mouse_init ();
62 return Qnil;
65 DEFUN ("mode4350", Fmode4350, Smode4350, 0, 0, "", "\
66 Changes the number of rows to 43 (EGA) or 50 (VGA).")
69 union REGS regs;
71 #ifdef HAVE_X_WINDOWS
72 if (!inhibit_window_system)
73 return Qnil;
74 #endif
75 mouse_off ();
76 regs.x.ax = 3;
77 int86 (0x10, &regs, &regs);
78 regs.x.ax = 0x1112;
79 regs.h.bl = 0;
80 int86 (0x10, &regs, &regs);
81 regs.x.ax = 0x1200;
82 regs.h.bl = 32;
83 int86 (0x10, &regs, &regs);
84 regs.x.ax = 0x0100;
85 regs.x.cx = 7;
86 int86 (0x10, &regs, &regs);
87 Fset_frame_size (Fselected_frame (), ScreenCols (), ScreenRows ());
88 Frecenter (Qnil);
89 Fredraw_display ();
90 if (have_mouse) mouse_init ();
91 return Qnil;
94 DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
95 "Call specific MSDOS interrupt number INTERRUPT with REGISTERS.\n\
96 Return the updated REGISTER vector.\n\
97 \n\
98 INTERRUPT should be an integer in the range 0 to 255.\n\
99 REGISTERS should be a vector produced by `make-register' and\n\
100 `set-register-value'.")
101 (intno, regs)
102 Lisp_Object intno, regs;
104 register int i;
105 int no;
106 union REGS inregs, outregs;
107 Lisp_Object val;
109 CHECK_NUMBER (intno, 0);
110 no = (unsigned long) XINT (intno);
111 CHECK_VECTOR (regs, 1);
112 if (no < 0 || no > 0xff || XVECTOR (regs)-> size != 8)
113 return Qnil;
114 for (i = 0; i < 8; i++)
115 CHECK_NUMBER (XVECTOR (regs)->contents[i], 1);
117 inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (regs)->contents[0]);
118 inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[1]);
119 inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[2]);
120 inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[3]);
121 inregs.x.si = (unsigned long) XFASTINT (XVECTOR (regs)->contents[4]);
122 inregs.x.di = (unsigned long) XFASTINT (XVECTOR (regs)->contents[5]);
123 inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (regs)->contents[6]);
124 inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (regs)->contents[7]);
126 int86 (no, &inregs, &outregs);
128 XVECTOR (regs)->contents[0] = make_number (outregs.x.ax);
129 XVECTOR (regs)->contents[1] = make_number (outregs.x.bx);
130 XVECTOR (regs)->contents[2] = make_number (outregs.x.cx);
131 XVECTOR (regs)->contents[3] = make_number (outregs.x.dx);
132 XVECTOR (regs)->contents[4] = make_number (outregs.x.si);
133 XVECTOR (regs)->contents[5] = make_number (outregs.x.di);
134 XVECTOR (regs)->contents[6] = make_number (outregs.x.cflag);
135 XVECTOR (regs)->contents[7] = make_number (outregs.x.flags);
137 return regs;
140 #ifndef HAVE_X_WINDOWS
141 /* Later we might want to control the mouse interface with this function,
142 e.g., with respect to non-80 column screen modes. */
144 DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0, "\
145 Report whether a mouse is present.")
148 if (have_mouse)
149 return Qt;
150 else
151 return Qnil;
154 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
155 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
156 WARNING: If you use this under X windows,\n\
157 you should call `unfocus-frame' afterwards.")
158 (frame, x, y)
159 Lisp_Object frame, x, y;
161 mouse_moveto (XINT (x), XINT (y));
162 return Qnil;
165 /* Function to translate colour names to integers. See lisp/term/pc-win.el
166 for its definition. */
168 Lisp_Object Qmsdos_color_translate;
169 #endif
172 DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
173 "Initialize and enable mouse if available.")
176 if (have_mouse) {
177 have_mouse = 1;
178 mouse_init ();
179 return Qt;
181 return Qnil;
184 DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
185 "Enable mouse if available.")
188 if (have_mouse)
190 have_mouse = 1;
191 mouse_on ();
193 return have_mouse ? Qt : Qnil;
196 DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
197 "Disable mouse if available.")
200 mouse_off ();
201 if (have_mouse) have_mouse = -1;
202 return Qnil;
207 int dos_country_code;
208 int dos_codepage;
209 Lisp_Object Vdos_version;
211 void
212 init_dosfns ()
214 union REGS regs;
215 _go32_dpmi_seginfo info;
216 _go32_dpmi_registers dpmiregs;
218 #ifndef SYSTEM_MALLOC
219 get_lim_data (); /* why the hell isn't this called elsewhere? */
220 #endif
222 regs.x.ax = 0x3000;
223 intdos (&regs, &regs);
224 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
226 /* Obtain the country code by calling Dos via Dpmi. Don't rely on GO32. */
227 info.size = (34 + 15) / 16;
228 if (_go32_dpmi_allocate_dos_memory (&info))
229 dos_country_code = 1;
230 else
232 dpmiregs.x.ax = 0x3800;
233 dpmiregs.x.ds = info.rm_segment;
234 dpmiregs.x.dx = 0;
235 dpmiregs.x.ss = dpmiregs.x.sp = 0;
236 _go32_dpmi_simulate_int (0x21, &dpmiregs);
237 dos_country_code = dpmiregs.x.bx;
238 _go32_dpmi_free_dos_memory (&info);
241 regs.x.ax = 0x6601;
242 intdos (&regs, &regs);
243 if (regs.x.cflag)
244 /* Estimate code page from country code */
245 switch (dos_country_code)
247 case 45: /* Denmark */
248 case 47: /* Norway */
249 dos_codepage = 865;
250 break;
251 default:
252 /* US */
253 dos_codepage = 437;
255 else
256 dos_codepage = regs.x.bx & 0xffff;
260 * Define everything
262 syms_of_dosfns ()
264 defsubr (&Smode25);
265 defsubr (&Smode4350);
266 defsubr (&Sint86);
267 defsubr (&Smsdos_mouse_init);
268 defsubr (&Smsdos_mouse_enable);
269 defsubr (&Smsdos_mouse_disable);
270 #ifndef HAVE_X_WINDOWS
271 defsubr (&Smsdos_mouse_p);
272 defsubr (&Sset_mouse_position);
274 Qmsdos_color_translate = intern ("msdos-color-translate");
275 staticpro (&Qmsdos_color_translate);
276 #endif
278 DEFVAR_INT ("dos-country-code", &dos_country_code,
279 "The country code returned by Dos when Emacs was started.\n\
280 Usually this is the international telephone prefix.");
282 DEFVAR_INT ("dos-codepage", &dos_codepage,
283 "The codepage active when Emacs was started.\n\
284 The following are known:\n\
285 437 United States\n\
286 850 Multilingual (Latin I)\n\
287 852 Slavic (Latin II)\n\
288 857 Turkish\n\
289 860 Portugal\n\
290 861 Iceland\n\
291 863 Canada (French)\n\
292 865 Norway/Denmark");
294 DEFVAR_LISP ("dos-version", &Vdos_version,
295 "The (MAJOR . MINOR) Dos version (subject to modification with setver).");
297 #endif /* MSDOS */