diff options
| author | Richard M. Stallman | 1994-01-08 09:22:50 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-01-08 09:22:50 +0000 |
| commit | 1b94449f31e3c35ab82023e4f90cbb796ec5558f (patch) | |
| tree | cedeb7a17bd1c60bf9cb1d6b25232704e3154d9d /src | |
| parent | 54ad07d30fe057d5709f9deb939bca788ba01c8c (diff) | |
| download | emacs-1b94449f31e3c35ab82023e4f90cbb796ec5558f.tar.gz emacs-1b94449f31e3c35ab82023e4f90cbb796ec5558f.zip | |
Initial revision
Diffstat (limited to 'src')
| -rw-r--r-- | src/dosfns.c | 215 | ||||
| -rw-r--r-- | src/dosfns.h | 23 | ||||
| -rw-r--r-- | src/m/dos386.h | 112 | ||||
| -rw-r--r-- | src/msdos.c | 1067 | ||||
| -rw-r--r-- | src/msdos.h | 45 | ||||
| -rw-r--r-- | src/s/msdos.h | 219 |
6 files changed, 1681 insertions, 0 deletions
diff --git a/src/dosfns.c b/src/dosfns.c new file mode 100644 index 00000000000..82af5adb9c2 --- /dev/null +++ b/src/dosfns.c | |||
| @@ -0,0 +1,215 @@ | |||
| 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 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 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 1, or (at your option) | ||
| 10 | any later version. | ||
| 11 | |||
| 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. | ||
| 16 | |||
| 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. */ | ||
| 20 | |||
| 21 | |||
| 22 | #include "config.h" | ||
| 23 | |||
| 24 | #ifdef MSDOS | ||
| 25 | /* The entire file is within this conditional */ | ||
| 26 | |||
| 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" | ||
| 36 | |||
| 37 | static void | ||
| 38 | mode_resetsize () | ||
| 39 | { | ||
| 40 | Fset_screen_width (ScreenCols (), Qnil); | ||
| 41 | Fset_screen_height (ScreenRows (), Qnil); | ||
| 42 | } | ||
| 43 | |||
| 44 | DEFUN ("mode25", Fmode25, Smode25, 0, 0, "", | ||
| 45 | "Set the number of rows to 25.") | ||
| 46 | () | ||
| 47 | { | ||
| 48 | union REGS regs; | ||
| 49 | |||
| 50 | if (have_mouse) Mouse_off (); | ||
| 51 | regs.x.ax = 3; | ||
| 52 | int86 (0x10, ®s, ®s); | ||
| 53 | regs.x.ax = 0x1101; | ||
| 54 | regs.h.bl = 0; | ||
| 55 | int86 (0x10, ®s, ®s); | ||
| 56 | regs.x.ax = 0x1200; | ||
| 57 | regs.h.bl = 32; | ||
| 58 | int86 (0x10, ®s, ®s); | ||
| 59 | regs.x.ax = 3; | ||
| 60 | int86 (0x10, ®s, ®s); | ||
| 61 | mode_resetsize (); | ||
| 62 | Frecenter (Qnil); | ||
| 63 | Fredraw_display (); | ||
| 64 | if (have_mouse) Mouse_init (); | ||
| 65 | } | ||
| 66 | |||
| 67 | DEFUN ("mode4350", Fmode4350, Smode4350, 0, 0, "", | ||
| 68 | "Set the number of rows to 43 (EGA) or 50 (VGA).") | ||
| 69 | () | ||
| 70 | { | ||
| 71 | union REGS regs; | ||
| 72 | |||
| 73 | if (have_mouse) Mouse_off (); | ||
| 74 | regs.x.ax = 3; | ||
| 75 | int86 (0x10, ®s, ®s); | ||
| 76 | regs.x.ax = 0x1112; | ||
| 77 | regs.h.bl = 0; | ||
| 78 | int86 (0x10, ®s, ®s); | ||
| 79 | regs.x.ax = 0x1200; | ||
| 80 | regs.h.bl = 32; | ||
| 81 | int86 (0x10, ®s, ®s); | ||
| 82 | regs.x.ax = 0x0100; | ||
| 83 | regs.x.cx = 7; | ||
| 84 | int86 (0x10, ®s, ®s); | ||
| 85 | mode_resetsize (); | ||
| 86 | Frecenter (Qnil); | ||
| 87 | Fredraw_display (); | ||
| 88 | if (have_mouse) Mouse_init (); | ||
| 89 | } | ||
| 90 | |||
| 91 | DEFUN ("int86", Fint86, Sint86, 2, 2, 0, | ||
| 92 | "Call specific MSDOS interrupt number INTERRUPT with REGISTERS.\n\ | ||
| 93 | Return the updated REGISTER vector.\n\ | ||
| 94 | \n\ | ||
| 95 | INTERRUPT should be an integer in the range 0 to 255.\n\ | ||
| 96 | REGISTERS should be a vector produced by `make-register' and\n\ | ||
| 97 | `set-register-value'.") | ||
| 98 | (intno, regs) | ||
| 99 | Lisp_Object intno, regs; | ||
| 100 | { | ||
| 101 | register int i; | ||
| 102 | int no; | ||
| 103 | union REGS inregs, outregs; | ||
| 104 | Lisp_Object val; | ||
| 105 | |||
| 106 | CHECK_NUMBER (intno, 0); | ||
| 107 | no = (unsigned long) XINT (intno); | ||
| 108 | CHECK_VECTOR (regs, 1); | ||
| 109 | if (no < 0 || no > 0xff || XVECTOR (regs)-> size != 8) | ||
| 110 | return Qnil; | ||
| 111 | for (i = 0; i < 8; i++) | ||
| 112 | CHECK_NUMBER (XVECTOR (regs)->contents[i], 1); | ||
| 113 | |||
| 114 | inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (regs)->contents[0]); | ||
| 115 | inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[1]); | ||
| 116 | inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[2]); | ||
| 117 | inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[3]); | ||
| 118 | inregs.x.si = (unsigned long) XFASTINT (XVECTOR (regs)->contents[4]); | ||
| 119 | inregs.x.di = (unsigned long) XFASTINT (XVECTOR (regs)->contents[5]); | ||
| 120 | inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (regs)->contents[6]); | ||
| 121 | inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (regs)->contents[7]); | ||
| 122 | |||
| 123 | int86 (no, &inregs, &outregs); | ||
| 124 | |||
| 125 | XVECTOR (regs)->contents[0] = make_number (outregs.x.ax); | ||
| 126 | XVECTOR (regs)->contents[1] = make_number (outregs.x.bx); | ||
| 127 | XVECTOR (regs)->contents[2] = make_number (outregs.x.cx); | ||
| 128 | XVECTOR (regs)->contents[3] = make_number (outregs.x.dx); | ||
| 129 | XVECTOR (regs)->contents[4] = make_number (outregs.x.si); | ||
| 130 | XVECTOR (regs)->contents[5] = make_number (outregs.x.di); | ||
| 131 | XVECTOR (regs)->contents[6] = make_number (outregs.x.cflag); | ||
| 132 | XVECTOR (regs)->contents[7] = make_number (outregs.x.flags); | ||
| 133 | |||
| 134 | return regs; | ||
| 135 | } | ||
| 136 | |||
| 137 | int dos_country_code; | ||
| 138 | int dos_codepage; | ||
| 139 | Lisp_Object Vdos_version; | ||
| 140 | |||
| 141 | void | ||
| 142 | init_dosfns () | ||
| 143 | { | ||
| 144 | union REGS regs; | ||
| 145 | _go32_dpmi_seginfo info; | ||
| 146 | _go32_dpmi_registers dpmiregs; | ||
| 147 | |||
| 148 | get_lim_data (); /* why the hell isn't this called elsewhere? */ | ||
| 149 | |||
| 150 | regs.x.ax = 0x3000; | ||
| 151 | intdos (®s, ®s); | ||
| 152 | Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah)); | ||
| 153 | |||
| 154 | /* Obtain the country code by calling Dos via Dpmi. Don't rely on GO32. */ | ||
| 155 | info.size = (34 + 15) / 16; | ||
| 156 | if (_go32_dpmi_allocate_dos_memory (&info)) | ||
| 157 | dos_country_code = 1; | ||
| 158 | else | ||
| 159 | { | ||
| 160 | dpmiregs.x.ax = 0x3800; | ||
| 161 | dpmiregs.x.ds = info.rm_segment; | ||
| 162 | dpmiregs.x.dx = 0; | ||
| 163 | dpmiregs.x.ss = dpmiregs.x.sp = 0; | ||
| 164 | _go32_dpmi_simulate_int (0x21, &dpmiregs); | ||
| 165 | dos_country_code = dpmiregs.x.bx; | ||
| 166 | _go32_dpmi_free_dos_memory (&info); | ||
| 167 | } | ||
| 168 | |||
| 169 | regs.x.ax = 0x6601; | ||
| 170 | intdos (®s, ®s); | ||
| 171 | if (regs.x.cflag) | ||
| 172 | /* Estimate code page from country code */ | ||
| 173 | switch (dos_country_code) | ||
| 174 | { | ||
| 175 | case 45: /* Denmark */ | ||
| 176 | case 47: /* Norway */ | ||
| 177 | dos_codepage = 865; | ||
| 178 | break; | ||
| 179 | default: | ||
| 180 | /* US */ | ||
| 181 | dos_codepage = 437; | ||
| 182 | } | ||
| 183 | else | ||
| 184 | dos_codepage = regs.x.bx & 0xffff; | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Define everything | ||
| 189 | */ | ||
| 190 | syms_of_dosfns () | ||
| 191 | { | ||
| 192 | defsubr (&Smode25); | ||
| 193 | defsubr (&Smode4350); | ||
| 194 | defsubr (&Sint86); | ||
| 195 | |||
| 196 | DEFVAR_INT ("dos-country-code", &dos_country_code, | ||
| 197 | "The country code returned by Dos when Emacs was started.\n\ | ||
| 198 | Usually this is the international telephone prefix."); | ||
| 199 | |||
| 200 | DEFVAR_INT ("dos-codepage", &dos_codepage, | ||
| 201 | "The codepage active when Emacs was started.\n\ | ||
| 202 | The following are known: | ||
| 203 | 437 US | ||
| 204 | 850 Multilingual | ||
| 205 | 852 Slavic/Latin II | ||
| 206 | 857 Turkish | ||
| 207 | 860 Portugal | ||
| 208 | 861 Iceland | ||
| 209 | 863 Canada (French) | ||
| 210 | 865 Norway/Denmark"); | ||
| 211 | |||
| 212 | DEFVAR_LISP ("dos-version", &Vdos_version, | ||
| 213 | "The (MAJOR . MINOR) Dos version (subject to modification with setver)."); | ||
| 214 | } | ||
| 215 | #endif /* MSDOS */ | ||
diff --git a/src/dosfns.h b/src/dosfns.h new file mode 100644 index 00000000000..f27b344bb5c --- /dev/null +++ b/src/dosfns.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* MS-DOS specific Lisp utilities interface. | ||
| 2 | Coded by Manabu Higashida, 1991. | ||
| 3 | Copyright (C) 1991 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 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 1, or (at your option) | ||
| 10 | any later version. | ||
| 11 | |||
| 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. | ||
| 16 | |||
| 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. */ | ||
| 20 | |||
| 21 | extern int dos_country_code; | ||
| 22 | extern int dos_codepage; | ||
| 23 | extern Lisp_Object Vdos_version; | ||
diff --git a/src/m/dos386.h b/src/m/dos386.h new file mode 100644 index 00000000000..defd8f1036e --- /dev/null +++ b/src/m/dos386.h | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | /* Machine description file for MS-DOS | ||
| 2 | |||
| 3 | Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 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. | ||
| 11 | |||
| 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. | ||
| 16 | |||
| 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. */ | ||
| 20 | |||
| 21 | /* Note: lots of stuff here was taken from m-dos386.h in demacs. */ | ||
| 22 | |||
| 23 | |||
| 24 | /* The following three symbols give information on | ||
| 25 | the size of various data types. */ | ||
| 26 | |||
| 27 | #define SHORTBITS 16 /* Number of bits in a short */ | ||
| 28 | #define INTBITS 32 /* Number of bits in an int */ | ||
| 29 | #define LONGBITS 32 /* Number of bits in a long */ | ||
| 30 | |||
| 31 | /* Define BIG_ENDIAN iff lowest-numbered byte in a word | ||
| 32 | is the most significant byte. */ | ||
| 33 | |||
| 34 | /* #define BIG_ENDIAN */ | ||
| 35 | |||
| 36 | /* Define NO_ARG_ARRAY if you cannot take the address of the first of a | ||
| 37 | * group of arguments and treat it as an array of the arguments. */ | ||
| 38 | |||
| 39 | /* #define NO_ARG_ARRAY */ | ||
| 40 | |||
| 41 | /* Define WORD_MACHINE if addresses and such have | ||
| 42 | * to be corrected before they can be used as byte counts. */ | ||
| 43 | |||
| 44 | /* #define WORD_MACHINE */ | ||
| 45 | |||
| 46 | /* Define how to take a char and sign-extend into an int. | ||
| 47 | On machines where char is signed, this is a no-op. */ | ||
| 48 | |||
| 49 | #define SIGN_EXTEND_CHAR(c) (c) | ||
| 50 | |||
| 51 | /* Now define a symbol for the cpu type, if your compiler | ||
| 52 | does not define it automatically: | ||
| 53 | Ones defined so far include vax, m68000, ns16000, pyramid, | ||
| 54 | orion, tahoe, APOLLO and many others */ | ||
| 55 | |||
| 56 | #define INTEL386 | ||
| 57 | |||
| 58 | /* Use type int rather than a union, to represent Lisp_Object */ | ||
| 59 | /* This is desirable for most machines. */ | ||
| 60 | |||
| 61 | #define NO_UNION_TYPE | ||
| 62 | |||
| 63 | /* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend | ||
| 64 | the 24-bit bit field into an int. In other words, if bit fields | ||
| 65 | are always unsigned. | ||
| 66 | |||
| 67 | If you use NO_UNION_TYPE, this flag does not matter. */ | ||
| 68 | |||
| 69 | #define EXPLICIT_SIGN_EXTEND | ||
| 70 | |||
| 71 | /* Data type of load average, as read out of kmem. */ | ||
| 72 | |||
| 73 | /* #define LOAD_AVE_TYPE long */ | ||
| 74 | |||
| 75 | /* Convert that into an integer that is 100 for a load average of 1.0 */ | ||
| 76 | |||
| 77 | /* #define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / FSCALE) */ | ||
| 78 | |||
| 79 | /* Define CANNOT_DUMP on machines where unexec does not work. | ||
| 80 | Then the function dump-emacs will not be defined | ||
| 81 | and temacs will do (load "loadup") automatically unless told otherwise. */ | ||
| 82 | |||
| 83 | /* #define CANNOT_DUMP */ | ||
| 84 | |||
| 85 | /* Define VIRT_ADDR_VARIES if the virtual addresses of | ||
| 86 | pure and impure space as loaded can vary, and even their | ||
| 87 | relative order cannot be relied on. | ||
| 88 | |||
| 89 | Otherwise Emacs assumes that text space precedes data space, | ||
| 90 | numerically. */ | ||
| 91 | |||
| 92 | /* #define VIRT_ADDR_VARIES */ | ||
| 93 | |||
| 94 | /* Define C_ALLOCA if this machine does not support a true alloca | ||
| 95 | and the one written in C should be used instead. | ||
| 96 | Define HAVE_ALLOCA to say that the system provides a properly | ||
| 97 | working alloca function and it should be used. | ||
| 98 | Define neither one if an assembler-language alloca | ||
| 99 | in the file alloca.s should be used. */ | ||
| 100 | |||
| 101 | #define HAVE_ALLOCA | ||
| 102 | #define alloca(x) __builtin_alloca(x) | ||
| 103 | |||
| 104 | /* Define NO_REMAP if memory segmentation makes it not work well | ||
| 105 | to change the boundary between the text section and data section | ||
| 106 | when Emacs is dumped. If you define this, the preloaded Lisp | ||
| 107 | code will not be sharable; but that's better than failing completely. */ | ||
| 108 | |||
| 109 | #define NO_REMAP | ||
| 110 | |||
| 111 | /* We need a little extra space, see ../../lisp/loadup.el */ | ||
| 112 | #define PURESIZE 210000 | ||
diff --git a/src/msdos.c b/src/msdos.c new file mode 100644 index 00000000000..d0937cf763b --- /dev/null +++ b/src/msdos.c | |||
| @@ -0,0 +1,1067 @@ | |||
| 1 | /* MS-DOS specific C utilities. Coded by Morten Welinder 1993 | ||
| 2 | Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | /* Note: some of the stuff here was taken from end of sysdep.c in demacs. */ | ||
| 21 | |||
| 22 | #include "config.h" | ||
| 23 | |||
| 24 | #ifdef MSDOS | ||
| 25 | #include "lisp.h" | ||
| 26 | #include <stdio.h> | ||
| 27 | #include <stdlib.h> | ||
| 28 | #include <sys/param.h> | ||
| 29 | #include <sys/time.h> | ||
| 30 | #include <dos.h> | ||
| 31 | #include "dosfns.h" | ||
| 32 | #include "msdos.h" | ||
| 33 | #include "systime.h" | ||
| 34 | #include "termhooks.h" | ||
| 35 | #include "frame.h" | ||
| 36 | #include <go32.h> | ||
| 37 | #include <pc.h> | ||
| 38 | #include <ctype.h> | ||
| 39 | /* #include <process.h> */ | ||
| 40 | /* Damn that local process.h! Instead we can define P_WAIT ourselves. */ | ||
| 41 | #define P_WAIT 1 | ||
| 42 | |||
| 43 | static int break_stat; /* BREAK check mode status. */ | ||
| 44 | static int stdin_stat; /* stdin IOCTL status. */ | ||
| 45 | static int extended_kbd; /* 101 (102) keyboard present. */ | ||
| 46 | |||
| 47 | int have_mouse; /* Mouse present? */ | ||
| 48 | static int mouse_last_x; | ||
| 49 | static int mouse_last_y; | ||
| 50 | |||
| 51 | /* Turn off Dos' Ctrl-C checking and inhibit interpretation of control chars | ||
| 52 | by Dos. Determine the keyboard type. */ | ||
| 53 | int | ||
| 54 | dos_ttraw () | ||
| 55 | { | ||
| 56 | union REGS inregs, outregs; | ||
| 57 | |||
| 58 | inregs.h.ah = 0xc0; | ||
| 59 | int86 (0x15, &inregs, &outregs); | ||
| 60 | extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0); | ||
| 61 | |||
| 62 | break_stat = getcbrk (); | ||
| 63 | setcbrk (0); | ||
| 64 | install_ctrl_break_check (); | ||
| 65 | have_mouse = Mouse_init1 (); | ||
| 66 | |||
| 67 | inregs.x.ax = 0x4400; /* Get IOCTL status. */ | ||
| 68 | inregs.x.bx = 0x00; /* 0 = stdin. */ | ||
| 69 | intdos (&inregs, &outregs); | ||
| 70 | stdin_stat = outregs.h.dl; | ||
| 71 | |||
| 72 | inregs.x.dx = (outregs.x.dx | 0x0020) & 0x0027; /* raw mode */ | ||
| 73 | inregs.h.al = 0x01; | ||
| 74 | intdos (&inregs, &outregs); | ||
| 75 | return !outregs.x.cflag; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Restore status of standard input and Ctrl-C checking. */ | ||
| 79 | int | ||
| 80 | dos_ttcooked () | ||
| 81 | { | ||
| 82 | union REGS inregs, outregs; | ||
| 83 | |||
| 84 | setcbrk (break_stat); | ||
| 85 | if (have_mouse) Mouse_off (); | ||
| 86 | |||
| 87 | inregs.x.ax = 0x4401; /* Set IOCTL status. */ | ||
| 88 | inregs.x.bx = 0x00; /* 0 = stdin. */ | ||
| 89 | inregs.x.dx = stdin_stat; | ||
| 90 | intdos (&inregs, &outregs); | ||
| 91 | return !outregs.x.cflag; | ||
| 92 | } | ||
| 93 | |||
| 94 | static unsigned short | ||
| 95 | ibmpc_translate_map[] = | ||
| 96 | { | ||
| 97 | /* --------------- 00 to 0f --------------- */ | ||
| 98 | 0, /* Ctrl Break */ | ||
| 99 | 0xff1b, /* Escape */ | ||
| 100 | 0xffb1, /* Keypad 1 */ | ||
| 101 | 0xffb2, /* Keypad 2 */ | ||
| 102 | 0xffb3, /* Keypad 3 */ | ||
| 103 | 0xffb4, /* Keypad 4 */ | ||
| 104 | 0xffb5, /* Keypad 5 */ | ||
| 105 | 0xffb6, /* Keypad 6 */ | ||
| 106 | 0xffb7, /* Keypad 7 */ | ||
| 107 | 0xffb8, /* Keypad 8 */ | ||
| 108 | 0xffb9, /* Keypad 9 */ | ||
| 109 | 0xffb0, /* Keypad 0 */ | ||
| 110 | '-', '=', | ||
| 111 | 0xff08, /* Backspace */ | ||
| 112 | 0xff74, /* (Shift) Tab [Tab doesn't use this table] */ | ||
| 113 | |||
| 114 | /* --------------- 10 to 1f --------------- */ | ||
| 115 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', | ||
| 116 | 0xff8d, /* Keypad Enter */ | ||
| 117 | 0, /* Ctrl */ | ||
| 118 | 'a', 's', | ||
| 119 | |||
| 120 | /* --------------- 20 to 2f --------------- */ | ||
| 121 | 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', | ||
| 122 | 0, /* Left shift */ | ||
| 123 | '\\', 'z', 'x', 'c', 'v', | ||
| 124 | |||
| 125 | /* --------------- 30 to 3f --------------- */ | ||
| 126 | 'b', 'n', 'm', ',', '.', | ||
| 127 | 0xffaf, /* Grey / */ | ||
| 128 | 0, /* Right shift */ | ||
| 129 | 0xffaa, /* Grey * */ | ||
| 130 | 0, /* Alt */ | ||
| 131 | ' ', | ||
| 132 | 0, /* Caps Lock */ | ||
| 133 | 0xffbe, /* F1 */ | ||
| 134 | 0xffbf, /* F2 */ | ||
| 135 | 0xffc0, /* F3 */ | ||
| 136 | 0xffc1, /* F4 */ | ||
| 137 | 0xffc2, /* F5 */ | ||
| 138 | |||
| 139 | /* --------------- 40 to 4f --------------- */ | ||
| 140 | 0xffc3, /* F6 */ | ||
| 141 | 0xffc4, /* F7 */ | ||
| 142 | 0xffc5, /* F8 */ | ||
| 143 | 0xffc6, /* F9 */ | ||
| 144 | 0xffc7, /* F10 */ | ||
| 145 | 0, /* Num Lock */ | ||
| 146 | 0, /* Scroll Lock */ | ||
| 147 | 0xff50, /* Home */ | ||
| 148 | 0xff52, /* Up */ | ||
| 149 | 0xff55, /* Page Up */ | ||
| 150 | 0xffad, /* Grey - */ | ||
| 151 | 0xff51, /* Left */ | ||
| 152 | 0xffb5, /* Keypad 5 */ | ||
| 153 | 0xff53, /* Right */ | ||
| 154 | 0xffab, /* Grey + */ | ||
| 155 | 0xff57, /* End */ | ||
| 156 | |||
| 157 | /* --------------- 50 to 5f --------------- */ | ||
| 158 | 0xff54, /* Down */ | ||
| 159 | 0xff56, /* Page Down */ | ||
| 160 | 0xff63, /* Insert */ | ||
| 161 | 0xffff, /* Delete */ | ||
| 162 | 0xffbe, /* (Shift) F1 */ | ||
| 163 | 0xffbf, /* (Shift) F2 */ | ||
| 164 | 0xffc0, /* (Shift) F3 */ | ||
| 165 | 0xffc1, /* (Shift) F4 */ | ||
| 166 | 0xffc2, /* (Shift) F5 */ | ||
| 167 | 0xffc3, /* (Shift) F6 */ | ||
| 168 | 0xffc4, /* (Shift) F7 */ | ||
| 169 | 0xffc5, /* (Shift) F8 */ | ||
| 170 | 0xffc6, /* (Shift) F9 */ | ||
| 171 | 0xffc7, /* (Shift) F10 */ | ||
| 172 | 0xffbe, /* (Ctrl) F1 */ | ||
| 173 | 0xffbf, /* (Ctrl) F2 */ | ||
| 174 | |||
| 175 | /* --------------- 60 to 6f --------------- */ | ||
| 176 | 0xffc0, /* (Ctrl) F3 */ | ||
| 177 | 0xffc1, /* (Ctrl) F4 */ | ||
| 178 | 0xffc2, /* (Ctrl) F5 */ | ||
| 179 | 0xffc3, /* (Ctrl) F6 */ | ||
| 180 | 0xffc4, /* (Ctrl) F7 */ | ||
| 181 | 0xffc5, /* (Ctrl) F8 */ | ||
| 182 | 0xffc6, /* (Ctrl) F9 */ | ||
| 183 | 0xffc7, /* (Ctrl) F10 */ | ||
| 184 | 0xffbe, /* (Alt) F1 */ | ||
| 185 | 0xffbf, /* (Alt) F2 */ | ||
| 186 | 0xffc0, /* (Alt) F3 */ | ||
| 187 | 0xffc1, /* (Alt) F4 */ | ||
| 188 | 0xffc2, /* (Alt) F5 */ | ||
| 189 | 0xffc3, /* (Alt) F6 */ | ||
| 190 | 0xffc4, /* (Alt) F7 */ | ||
| 191 | 0xffc5, /* (Alt) F8 */ | ||
| 192 | |||
| 193 | /* --------------- 70 to 7f --------------- */ | ||
| 194 | 0xffc6, /* (Alt) F9 */ | ||
| 195 | 0xffc7, /* (Alt) F10 */ | ||
| 196 | 0xff6d, /* (Ctrl) Sys Rq */ | ||
| 197 | 0xff51, /* (Ctrl) Left */ | ||
| 198 | 0xff53, /* (Ctrl) Right */ | ||
| 199 | 0xff57, /* (Ctrl) End */ | ||
| 200 | 0xff56, /* (Ctrl) Page Down */ | ||
| 201 | 0xff50, /* (Ctrl) Home */ | ||
| 202 | '1', '2', '3', '4', '5', '6', '7', '8', /* (Alt) */ | ||
| 203 | |||
| 204 | /* --------------- 80 to 8f --------------- */ | ||
| 205 | '9', '0', '-', '=', /* (Alt) */ | ||
| 206 | 0xff55, /* (Ctrl) Page Up */ | ||
| 207 | 0xffc8, /* F11 */ | ||
| 208 | 0xffc9, /* F12 */ | ||
| 209 | 0xffc8, /* (Shift) F11 */ | ||
| 210 | 0xffc9, /* (Shift) F12 */ | ||
| 211 | 0xffc8, /* (Ctrl) F11 */ | ||
| 212 | 0xffc9, /* (Ctrl) F12 */ | ||
| 213 | 0xffc8, /* (Alt) F11 */ | ||
| 214 | 0xffc9, /* (Alt) F12 */ | ||
| 215 | 0xff52, /* (Ctrl) Up */ | ||
| 216 | 0xffae, /* (Ctrl) Grey - */ | ||
| 217 | 0xffb5, /* (Ctrl) Keypad 5 */ | ||
| 218 | |||
| 219 | /* --------------- 90 to 9f --------------- */ | ||
| 220 | 0xffab, /* (Ctrl) Grey + */ | ||
| 221 | 0xff54, /* (Ctrl) Down */ | ||
| 222 | 0xff63, /* (Ctrl) Insert */ | ||
| 223 | 0xffff, /* (Ctrl) Delete */ | ||
| 224 | 0xff09, /* (Ctrl) Tab */ | ||
| 225 | 0xffaf, /* (Ctrl) Grey / */ | ||
| 226 | 0xffaa, /* (Ctrl) Grey * */ | ||
| 227 | 0xff50, /* (Alt) Home */ | ||
| 228 | 0xff52, /* (Alt) Up */ | ||
| 229 | 0xff55, /* (Alt) Page Up */ | ||
| 230 | 0, /* NO KEY */ | ||
| 231 | 0xff51, /* (Alt) Left */ | ||
| 232 | 0, /* NO KEY */ | ||
| 233 | 0xff53, /* (Alt) Right */ | ||
| 234 | 0, /* NO KEY */ | ||
| 235 | 0xff57, /* (Alt) End */ | ||
| 236 | |||
| 237 | /* --------------- a0 to af --------------- */ | ||
| 238 | 0xff54, /* (Alt) Down */ | ||
| 239 | 0xff56, /* (Alt) Page Down */ | ||
| 240 | 0xff63, /* (Alt) Insert */ | ||
| 241 | 0xffff, /* (Alt) Delete */ | ||
| 242 | 0xffaf, /* (Alt) Grey / */ | ||
| 243 | 0xff09, /* (Alt) Tab */ | ||
| 244 | 0xff0d /* (Alt) Enter */ | ||
| 245 | }; | ||
| 246 | |||
| 247 | /* Get a char from keyboard. Function keys are put into the event queue. */ | ||
| 248 | static int | ||
| 249 | dos_rawgetc () | ||
| 250 | { | ||
| 251 | struct input_event event; | ||
| 252 | struct timeval tv; | ||
| 253 | union REGS regs; | ||
| 254 | int ctrl_p, alt_p, shift_p; | ||
| 255 | |||
| 256 | /* Calculate modifier bits */ | ||
| 257 | regs.h.ah = extended_kbd ? 0x12 : 0x02; | ||
| 258 | int86 (0x16, ®s, ®s); | ||
| 259 | ctrl_p = ((regs.h.al & 4) != 0); | ||
| 260 | shift_p = ((regs.h.al & 3) != 0); | ||
| 261 | alt_p = ((extended_kbd ? (regs.h.ah & 2) : (regs.h.al & 8)) != 0); | ||
| 262 | |||
| 263 | while (kbhit ()) | ||
| 264 | { | ||
| 265 | union REGS regs; | ||
| 266 | register unsigned char c; | ||
| 267 | int sc, code; | ||
| 268 | |||
| 269 | regs.h.ah = extended_kbd ? 0x10 : 0x00; | ||
| 270 | int86 (0x16, ®s, ®s); | ||
| 271 | c = regs.h.al; | ||
| 272 | sc = regs.h.ah; | ||
| 273 | |||
| 274 | /* Determine from the scan code if a keypad key was pressed. */ | ||
| 275 | if (c >= '0' && c <= '9' && sc > 0xb) | ||
| 276 | sc = (c == '0') ? 0xb : (c - '0' + 1), c = 0; | ||
| 277 | else if (sc == 0xe0) | ||
| 278 | { | ||
| 279 | switch (c) | ||
| 280 | { | ||
| 281 | case 10: /* Ctrl Enter */ | ||
| 282 | case 13: | ||
| 283 | sc = 0x1c; | ||
| 284 | break; | ||
| 285 | case '.': /* Decimal point or decimal comma */ | ||
| 286 | case ',': | ||
| 287 | sc = 0x53; | ||
| 288 | break; | ||
| 289 | case '/': | ||
| 290 | sc = 0x35; | ||
| 291 | break; | ||
| 292 | default: | ||
| 293 | sc = 0; | ||
| 294 | }; | ||
| 295 | c = 0; | ||
| 296 | } | ||
| 297 | |||
| 298 | if (c == 0 | ||
| 299 | || c == ' ' | ||
| 300 | || alt_p | ||
| 301 | || (ctrl_p && shift_p) | ||
| 302 | || (c == 0xe0 && sc != 0) /* Pseudo-key */ | ||
| 303 | || sc == 0x37 /* Grey * */ | ||
| 304 | || sc == 0x4a /* Grey - */ | ||
| 305 | || sc == 0x4e /* Grey + */ | ||
| 306 | || sc == 0x0e) /* Back space *key*, not Ctrl-h */ | ||
| 307 | { | ||
| 308 | if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short))) | ||
| 309 | code = 0; | ||
| 310 | else | ||
| 311 | code = ibmpc_translate_map[sc]; | ||
| 312 | if (code != 0) | ||
| 313 | { | ||
| 314 | if (code >= 0x100) | ||
| 315 | { | ||
| 316 | event.kind = non_ascii_keystroke; | ||
| 317 | event.code = code & 0xff; | ||
| 318 | } | ||
| 319 | else | ||
| 320 | { | ||
| 321 | /* Don't return S- if we don't have to. */ | ||
| 322 | if (code >= 'a' && code <= 'z') | ||
| 323 | { | ||
| 324 | c = shift_p ? toupper (code) : code; | ||
| 325 | shift_p = 0; | ||
| 326 | } | ||
| 327 | else | ||
| 328 | if (c == 0) c = code; | ||
| 329 | event.kind = ascii_keystroke; | ||
| 330 | event.code = c; | ||
| 331 | } | ||
| 332 | event.modifiers | ||
| 333 | = (shift_p ? shift_modifier : 0) | ||
| 334 | + (ctrl_p ? ctrl_modifier : 0) | ||
| 335 | + (alt_p ? meta_modifier : 0); | ||
| 336 | /* EMACS == Enter Meta Alt Control Shift */ | ||
| 337 | event.frame_or_window = selected_frame; | ||
| 338 | gettimeofday (&tv, NULL); | ||
| 339 | event.timestamp = tv.tv_usec; | ||
| 340 | kbd_buffer_store_event (&event); | ||
| 341 | } | ||
| 342 | } else | ||
| 343 | return c; | ||
| 344 | } | ||
| 345 | |||
| 346 | if (have_mouse) | ||
| 347 | { | ||
| 348 | int but, press, x, y, ok; | ||
| 349 | |||
| 350 | /* Check for mouse movement *before* buttons. */ | ||
| 351 | Mouse_check_moved (); | ||
| 352 | |||
| 353 | for (but = 0; but < NUM_MOUSE_BUTTONS; but++) | ||
| 354 | for (press = 0; press < 2; press++) | ||
| 355 | { | ||
| 356 | if (press) | ||
| 357 | ok = Mouse_pressed (but, &x, &y); | ||
| 358 | else | ||
| 359 | ok = Mouse_released (but, &x, &y); | ||
| 360 | if (ok) | ||
| 361 | { | ||
| 362 | event.kind = mouse_click; | ||
| 363 | event.code = but; | ||
| 364 | event.modifiers | ||
| 365 | = (shift_p ? shift_modifier : 0) | ||
| 366 | + (ctrl_p ? ctrl_modifier : 0) | ||
| 367 | + (alt_p ? meta_modifier : 0) | ||
| 368 | + (press ? down_modifier : up_modifier); | ||
| 369 | event.x = x; | ||
| 370 | event.y = y; | ||
| 371 | event.frame_or_window = selected_frame; | ||
| 372 | gettimeofday (&tv, NULL); | ||
| 373 | event.timestamp = tv.tv_usec; | ||
| 374 | kbd_buffer_store_event (&event); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | return -1; | ||
| 380 | } | ||
| 381 | |||
| 382 | static int prev_get_char = -1; | ||
| 383 | |||
| 384 | /* Return 1 if a key is ready to be read without suspending execution. */ | ||
| 385 | dos_keysns () | ||
| 386 | { | ||
| 387 | if (prev_get_char != -1) | ||
| 388 | return 1; | ||
| 389 | else | ||
| 390 | return ((prev_get_char = dos_rawgetc ()) != -1); | ||
| 391 | } | ||
| 392 | |||
| 393 | /* Read a key. Return -1 if no key is ready. */ | ||
| 394 | dos_keyread () | ||
| 395 | { | ||
| 396 | if (prev_get_char != -1) | ||
| 397 | { | ||
| 398 | int c = prev_get_char; | ||
| 399 | prev_get_char = -1; | ||
| 400 | return c; | ||
| 401 | } | ||
| 402 | else | ||
| 403 | return dos_rawgetc (); | ||
| 404 | } | ||
| 405 | |||
| 406 | /* Hostnames for a pc are not really funny, but they are used in change log | ||
| 407 | so we emulate the best we can. */ | ||
| 408 | gethostname (p, size) | ||
| 409 | char *p; | ||
| 410 | int size; | ||
| 411 | { | ||
| 412 | char *q = egetenv ("HOSTNAME"); | ||
| 413 | |||
| 414 | if (!q) q = "pc"; | ||
| 415 | strcpy (p, q); | ||
| 416 | return 0; | ||
| 417 | } | ||
| 418 | |||
| 419 | /* Destructively turn backslashes into slashes. */ | ||
| 420 | void | ||
| 421 | dostounix_filename (p) | ||
| 422 | register char *p; | ||
| 423 | { | ||
| 424 | while (*p) | ||
| 425 | { | ||
| 426 | if (*p == '\\') | ||
| 427 | *p = '/'; | ||
| 428 | p++; | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | /* Destructively turn slashes into backslashes. */ | ||
| 433 | void | ||
| 434 | unixtodos_filename (p) | ||
| 435 | register char *p; | ||
| 436 | { | ||
| 437 | while (*p) | ||
| 438 | { | ||
| 439 | if (*p == '/') | ||
| 440 | *p = '\\'; | ||
| 441 | p++; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | /* Get the default directory for a given drive. 0=def, 1=A, 2=B, ... */ | ||
| 446 | int | ||
| 447 | getdefdir (drive, dst) | ||
| 448 | int drive; | ||
| 449 | char *dst; | ||
| 450 | { | ||
| 451 | union REGS regs; | ||
| 452 | |||
| 453 | *dst++ = '/'; | ||
| 454 | regs.h.dl = drive; | ||
| 455 | regs.x.si = (int) dst; | ||
| 456 | regs.h.ah = 0x47; | ||
| 457 | intdos (®s, ®s); | ||
| 458 | return !regs.x.cflag; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* Remove all CR's that are followed by a LF. */ | ||
| 462 | int | ||
| 463 | crlf_to_lf (n, buf) | ||
| 464 | register int n; | ||
| 465 | register unsigned char *buf; | ||
| 466 | { | ||
| 467 | unsigned char *np = buf; | ||
| 468 | unsigned char *startp = buf; | ||
| 469 | unsigned char *endp = buf + n; | ||
| 470 | unsigned char c; | ||
| 471 | |||
| 472 | if (n == 0) | ||
| 473 | return n; | ||
| 474 | while (buf < endp) | ||
| 475 | { | ||
| 476 | if (*buf == 0x0d) | ||
| 477 | { | ||
| 478 | if (*(++buf) != 0x0a) | ||
| 479 | *np++ = 0x0d; | ||
| 480 | } | ||
| 481 | else | ||
| 482 | *np++ = *buf++; | ||
| 483 | } | ||
| 484 | return np - startp; | ||
| 485 | } | ||
| 486 | |||
| 487 | |||
| 488 | /* Run command as specified by ARGV in directory DIR. | ||
| 489 | The command is run with input from TEMPIN and output to file TEMPOUT. */ | ||
| 490 | int | ||
| 491 | run_msdos_command (argv, dir, tempin, tempout) | ||
| 492 | unsigned char **argv; | ||
| 493 | Lisp_Object dir; | ||
| 494 | int tempin, tempout; | ||
| 495 | { | ||
| 496 | char *saveargv1, *saveargv2, **envv; | ||
| 497 | char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ | ||
| 498 | int msshell, result = -1; | ||
| 499 | int in, out, inbak, outbak, errbak; | ||
| 500 | Lisp_Object cmd; | ||
| 501 | |||
| 502 | /* Get current directory as MSDOS cwd is not per-process. */ | ||
| 503 | getwd (oldwd); | ||
| 504 | |||
| 505 | cmd = Ffile_name_nondirectory (build_string (argv[0])); | ||
| 506 | msshell = !NILP (Fmember (cmd, Fsymbol_value (intern ("msdos-shells")))) | ||
| 507 | && !strcmp ("-c", argv[1]); | ||
| 508 | if (msshell) | ||
| 509 | { | ||
| 510 | saveargv1 = argv[1]; | ||
| 511 | argv[1] = "/c"; | ||
| 512 | if (argv[2]) | ||
| 513 | { | ||
| 514 | saveargv2 = argv[2]; | ||
| 515 | unixtodos_filename (argv[2] = strdup (argv[2])); | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 519 | /* Build the environment array. */ | ||
| 520 | { | ||
| 521 | extern Lisp_Object Vprocess_environment; | ||
| 522 | Lisp_Object tmp, lst = Vprocess_environment; | ||
| 523 | int i, len = XFASTINT (Flength (lst)); | ||
| 524 | |||
| 525 | envv = alloca ((len + 1) * sizeof (char *)); | ||
| 526 | for (i = 0; i < len; i++) | ||
| 527 | { | ||
| 528 | tmp = Fcar (lst); | ||
| 529 | lst = Fcdr (lst); | ||
| 530 | CHECK_STRING (tmp, 0); | ||
| 531 | envv[i] = alloca (XSTRING (tmp)->size + 1); | ||
| 532 | strcpy (envv[i], XSTRING (tmp)->data); | ||
| 533 | } | ||
| 534 | envv[len] = (char *) 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | if (XTYPE (dir) == Lisp_String) | ||
| 538 | chdir (XSTRING (dir)->data); | ||
| 539 | inbak = dup (0); | ||
| 540 | outbak = dup (1); | ||
| 541 | errbak = dup (2); | ||
| 542 | if (inbak < 0 || outbak < 0 || errbak < 0) | ||
| 543 | goto done; /* Allocation might fail due to lack of descriptors. */ | ||
| 544 | dup2 (tempin, 0); | ||
| 545 | dup2 (tempout, 1); | ||
| 546 | dup2 (tempout, 2); | ||
| 547 | dos_ttcooked (); | ||
| 548 | result = spawnve (P_WAIT, argv[0], argv, envv); | ||
| 549 | dos_ttraw (); | ||
| 550 | dup2 (inbak, 0); | ||
| 551 | dup2 (outbak, 1); | ||
| 552 | dup2 (errbak, 2); | ||
| 553 | |||
| 554 | done: | ||
| 555 | chdir (oldwd); | ||
| 556 | if (msshell) | ||
| 557 | { | ||
| 558 | argv[1] = saveargv1; | ||
| 559 | if (argv[2]) | ||
| 560 | { | ||
| 561 | free (argv[2]); | ||
| 562 | argv[2] = saveargv2; | ||
| 563 | } | ||
| 564 | } | ||
| 565 | return result; | ||
| 566 | } | ||
| 567 | |||
| 568 | |||
| 569 | croak (badfunc) | ||
| 570 | char *badfunc; | ||
| 571 | { | ||
| 572 | fprintf (stderr, "%s not yet implemented\r\n", badfunc); | ||
| 573 | reset_sys_modes (); | ||
| 574 | exit (1); | ||
| 575 | } | ||
| 576 | |||
| 577 | /* A list of unimplemented functions that we silently ignore. */ | ||
| 578 | unsigned alarm (s) unsigned s; {} | ||
| 579 | fork () { return 0; } | ||
| 580 | int kill (x, y) int x, y; { return -1; } | ||
| 581 | nice (p) int p; {} | ||
| 582 | void volatile pause () {} | ||
| 583 | request_sigio () {} | ||
| 584 | setpgrp () {return 0; } | ||
| 585 | setpriority (x,y,z) int x,y,z; { return 0; } | ||
| 586 | sigsetmask (x) int x; { return 0; } | ||
| 587 | unrequest_sigio () {} | ||
| 588 | |||
| 589 | #ifdef chdir | ||
| 590 | #undef chdir | ||
| 591 | #endif | ||
| 592 | |||
| 593 | int | ||
| 594 | sys_chdir (path) | ||
| 595 | const char* path; | ||
| 596 | { | ||
| 597 | int len = strlen (path); | ||
| 598 | char *tmp = (char *) alloca (len + 1); | ||
| 599 | /* Gotta do this extern here due to the corresponding #define: */ | ||
| 600 | extern int chdir (); | ||
| 601 | |||
| 602 | if (*path && path[1] == ':' && (getdisk () != tolower (path[0]) - 'a')) | ||
| 603 | setdisk (tolower (path[0]) - 'a'); | ||
| 604 | |||
| 605 | strcpy (tmp, path); | ||
| 606 | if (strcmp (path, "/") && strcmp (path + 1, ":/") && (path[len - 1] == '/')) | ||
| 607 | tmp[len - 1] = 0; | ||
| 608 | return chdir (tmp); | ||
| 609 | } | ||
| 610 | |||
| 611 | /* Sleep SECS. If KBDOK also return immediately if a key is pressed. */ | ||
| 612 | void | ||
| 613 | sleep_or_kbd_hit (secs, kbdok) | ||
| 614 | int secs, kbdok; | ||
| 615 | { | ||
| 616 | long clnow, clthen; | ||
| 617 | struct timeval t; | ||
| 618 | |||
| 619 | gettimeofday (&t, NULL); | ||
| 620 | clnow = t.tv_sec * 100 + t.tv_usec / 10000; | ||
| 621 | clthen = clnow + (100 * secs); | ||
| 622 | |||
| 623 | do | ||
| 624 | { | ||
| 625 | gettimeofday (&t, NULL); | ||
| 626 | clnow = t.tv_sec * 100 + t.tv_usec / 10000; | ||
| 627 | if (kbdok && detect_input_pending ()) | ||
| 628 | return; | ||
| 629 | } | ||
| 630 | while (clnow < clthen); | ||
| 631 | } | ||
| 632 | |||
| 633 | /* Define a lot of environment variables if not already defined. Don't | ||
| 634 | remove anything unless you know what you're doing -- lots of code will | ||
| 635 | break if one or more of these are missing. */ | ||
| 636 | void | ||
| 637 | init_environment (argc, argv, skip_args) | ||
| 638 | int argc; | ||
| 639 | char **argv; | ||
| 640 | int skip_args; | ||
| 641 | { | ||
| 642 | char *s, *t; | ||
| 643 | |||
| 644 | /* We default HOME to the directory from which Emacs was started, but with | ||
| 645 | a "/bin" suffix removed. */ | ||
| 646 | s = argv[0]; | ||
| 647 | t = alloca (strlen (s) + 1); | ||
| 648 | strcpy (t, s); | ||
| 649 | s = t + strlen (t); | ||
| 650 | while (s != t && *s != '/' && *s != ':') s--; | ||
| 651 | if (s == t) | ||
| 652 | t = "c:/emacs"; /* When run under debug32. */ | ||
| 653 | else | ||
| 654 | { | ||
| 655 | if (*s == ':') s++; | ||
| 656 | *s = 0; | ||
| 657 | if (s - 4 >= t && strcmp (s - 4, "/bin") == 0) | ||
| 658 | s[strlen (s) - 4] = 0; | ||
| 659 | } | ||
| 660 | setenv ("HOME", t, 0); | ||
| 661 | |||
| 662 | /* We set EMACSPATH to ~/bin (expanded) */ | ||
| 663 | s = getenv ("HOME"); | ||
| 664 | t = strcpy (alloca (strlen (s) + 6), s); | ||
| 665 | if (s[strlen (s) - 1] != '/') strcat (t, "/"); | ||
| 666 | strcat (t, "bin"); | ||
| 667 | setenv ("EMACSPATH", t, 0); | ||
| 668 | |||
| 669 | /* I don't expect anybody to ever use other terminals so the internal | ||
| 670 | terminal is the default. */ | ||
| 671 | setenv ("TERM", "internal", 0); | ||
| 672 | |||
| 673 | /* SHELL is a bit tricky -- COMSPEC is the closest we come, but we must | ||
| 674 | downcase it and mirror the backslashes. */ | ||
| 675 | s = getenv ("COMSPEC"); | ||
| 676 | if (!s) s = "c:/command.com"; | ||
| 677 | t = alloca (strlen (s) + 1); | ||
| 678 | strcpy (t, s); | ||
| 679 | strlwr (t); | ||
| 680 | dostounix_filename (t); | ||
| 681 | setenv ("SHELL", t, 0); | ||
| 682 | |||
| 683 | /* PATH is also downcased and backslashes mirrored. */ | ||
| 684 | s = getenv ("PATH"); | ||
| 685 | if (!s) s = ""; | ||
| 686 | t = alloca (strlen (s) + 3); | ||
| 687 | /* Current directory is always considered part of MsDos's path but it is | ||
| 688 | not normally mentioned. Now it is. */ | ||
| 689 | strcat (strcpy (t, ".;"), s); | ||
| 690 | strlwr (t); | ||
| 691 | dostounix_filename (t); /* Not a single file name, but this should work. */ | ||
| 692 | setenv ("PATH", t, 1); | ||
| 693 | |||
| 694 | /* In some sense all dos users have root privileges, so... */ | ||
| 695 | setenv ("USER", "root", 0); | ||
| 696 | setenv ("NAME", getenv ("USER"), 0); | ||
| 697 | |||
| 698 | /* Time zone determined from country code. To make this possible, the | ||
| 699 | country code may not span more than one time zone. In other words, | ||
| 700 | in the USA, you lose. */ | ||
| 701 | switch (dos_country_code) | ||
| 702 | { | ||
| 703 | case 31: /* Belgium */ | ||
| 704 | case 32: /* The Netherlands */ | ||
| 705 | case 33: /* France */ | ||
| 706 | case 34: /* Spain */ | ||
| 707 | case 36: /* Hungary */ | ||
| 708 | case 38: /* Yugoslavia (or what's left of it?) */ | ||
| 709 | case 39: /* Italy */ | ||
| 710 | case 41: /* Switzerland */ | ||
| 711 | case 42: /* Tjekia */ | ||
| 712 | case 45: /* Denmark */ | ||
| 713 | case 46: /* Sweden */ | ||
| 714 | case 47: /* Norway */ | ||
| 715 | case 48: /* Poland */ | ||
| 716 | case 49: /* Germany */ | ||
| 717 | /* Daylight saving from last Sunday in March to last Sunday in | ||
| 718 | September, both at 2AM. */ | ||
| 719 | setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0); | ||
| 720 | break; | ||
| 721 | case 44: /* United Kingdom */ | ||
| 722 | case 351: /* Portugal */ | ||
| 723 | case 354: /* Iceland */ | ||
| 724 | setenv ("TZ", "GMT+00", 0); | ||
| 725 | break; | ||
| 726 | case 81: /* Japan */ | ||
| 727 | case 82: /* Korea */ | ||
| 728 | setenv ("TZ", "???-09", 0); | ||
| 729 | break; | ||
| 730 | case 90: /* Turkey */ | ||
| 731 | case 358: /* Finland */ | ||
| 732 | case 972: /* Israel */ | ||
| 733 | setenv ("TZ", "EET-02", 0); | ||
| 734 | break; | ||
| 735 | } | ||
| 736 | tzset (); | ||
| 737 | } | ||
| 738 | |||
| 739 | /* Flash the screen as a substitute for BEEPs. */ | ||
| 740 | |||
| 741 | static unsigned char _xorattr; | ||
| 742 | |||
| 743 | void | ||
| 744 | visible_bell (xorattr) | ||
| 745 | unsigned char xorattr; | ||
| 746 | { | ||
| 747 | _xorattr = xorattr; | ||
| 748 | asm (" pushl %eax | ||
| 749 | pushl %ebx | ||
| 750 | pushl %ecx | ||
| 751 | pushl %edx | ||
| 752 | movl $1,%edx | ||
| 753 | visible_bell_0: | ||
| 754 | movl _ScreenPrimary,%eax | ||
| 755 | call dosmemsetup | ||
| 756 | movl %eax,%ebx | ||
| 757 | call _ScreenRows | ||
| 758 | movl %eax,%ecx | ||
| 759 | call _ScreenCols | ||
| 760 | imull %eax,%ecx | ||
| 761 | movb (__xorattr),%al | ||
| 762 | incl %ebx | ||
| 763 | visible_bell_1: | ||
| 764 | xorb %al,%gs:(%ebx) | ||
| 765 | addl $2,%ebx | ||
| 766 | decl %ecx | ||
| 767 | jne visible_bell_1 | ||
| 768 | decl %edx | ||
| 769 | jne visible_bell_3 | ||
| 770 | visible_bell_2: | ||
| 771 | movzwl %ax,%eax | ||
| 772 | movzwl %ax,%eax | ||
| 773 | movzwl %ax,%eax | ||
| 774 | movzwl %ax,%eax | ||
| 775 | decw %cx | ||
| 776 | jne visible_bell_2 | ||
| 777 | jmp visible_bell_0 | ||
| 778 | visible_bell_3: | ||
| 779 | popl %edx | ||
| 780 | popl %ecx | ||
| 781 | popl %ebx | ||
| 782 | popl %eax"); | ||
| 783 | } | ||
| 784 | |||
| 785 | static int internal_terminal = 0; | ||
| 786 | #undef fflush | ||
| 787 | |||
| 788 | int | ||
| 789 | internal_flush (f) | ||
| 790 | FILE *f; | ||
| 791 | { | ||
| 792 | static int x; | ||
| 793 | static int y; | ||
| 794 | char c, *cp; | ||
| 795 | int count, i; | ||
| 796 | |||
| 797 | if (internal_terminal && f == stdout) | ||
| 798 | { | ||
| 799 | if (have_mouse) Mouse_off (); | ||
| 800 | cp = stdout->_base; | ||
| 801 | count = stdout->_ptr - stdout->_base; | ||
| 802 | while (count > 0) | ||
| 803 | { | ||
| 804 | switch (c = *cp++) | ||
| 805 | { | ||
| 806 | case 27: | ||
| 807 | switch (*cp++) | ||
| 808 | { | ||
| 809 | case '@': | ||
| 810 | y = *cp++; | ||
| 811 | x = *cp++; | ||
| 812 | count -= 4; | ||
| 813 | break; | ||
| 814 | case 'A': | ||
| 815 | ScreenAttrib = *cp++; | ||
| 816 | count -= 3; | ||
| 817 | break; | ||
| 818 | case 'B': | ||
| 819 | visible_bell (*cp++); | ||
| 820 | count -= 3; | ||
| 821 | break; | ||
| 822 | case 'C': | ||
| 823 | ScreenClear (); | ||
| 824 | x = y = 0; | ||
| 825 | count -= 2; | ||
| 826 | break; | ||
| 827 | case 'E': | ||
| 828 | for (i = ScreenCols () - 1; i >= x; i--) | ||
| 829 | ScreenPutChar (' ', ScreenAttrib, i, y); | ||
| 830 | count -= 2; | ||
| 831 | break; | ||
| 832 | case 'R': | ||
| 833 | x++; | ||
| 834 | count -= 2; | ||
| 835 | break; | ||
| 836 | case 'U': | ||
| 837 | y--; | ||
| 838 | count -= 2; | ||
| 839 | break; | ||
| 840 | case 'X': | ||
| 841 | ScreenAttrib ^= *cp++; | ||
| 842 | count -= 3; | ||
| 843 | break; | ||
| 844 | default: | ||
| 845 | count -= 2; | ||
| 846 | } | ||
| 847 | break; | ||
| 848 | case 8: | ||
| 849 | x--; | ||
| 850 | count--; | ||
| 851 | break; | ||
| 852 | case 13: | ||
| 853 | x = 0; | ||
| 854 | count--; | ||
| 855 | break; | ||
| 856 | case 10: | ||
| 857 | y++; | ||
| 858 | count--; | ||
| 859 | break; | ||
| 860 | default: | ||
| 861 | ScreenPutChar (c, ScreenAttrib, x++, y); | ||
| 862 | count--; | ||
| 863 | } | ||
| 864 | } | ||
| 865 | fpurge (stdout); | ||
| 866 | ScreenSetCursor (y, x); | ||
| 867 | if (have_mouse) Mouse_on (); | ||
| 868 | } | ||
| 869 | else | ||
| 870 | /* This is a call to the original fflush. */ | ||
| 871 | fflush (f); | ||
| 872 | } | ||
| 873 | |||
| 874 | /* Do we need the internal terminal? */ | ||
| 875 | void | ||
| 876 | internal_terminal_init () | ||
| 877 | { | ||
| 878 | char *term = getenv ("TERM"); | ||
| 879 | |||
| 880 | internal_terminal | ||
| 881 | = (!noninteractive) && term && !strcmp (term, "internal"); | ||
| 882 | } | ||
| 883 | |||
| 884 | /* These must be global. */ | ||
| 885 | static _go32_dpmi_seginfo ctrl_break_vector; | ||
| 886 | static _go32_dpmi_registers ctrl_break_regs; | ||
| 887 | static int ctrlbreakinstalled = 0; | ||
| 888 | |||
| 889 | /* Interrupt level detection of Ctrl-Break. Don't do anything fancy here! */ | ||
| 890 | void | ||
| 891 | ctrl_break_func (regs) | ||
| 892 | _go32_dpmi_registers *regs; | ||
| 893 | { | ||
| 894 | Vquit_flag = Qt; | ||
| 895 | } | ||
| 896 | |||
| 897 | void | ||
| 898 | install_ctrl_break_check () | ||
| 899 | { | ||
| 900 | if (!ctrlbreakinstalled) | ||
| 901 | { | ||
| 902 | /* Don't press Ctrl-Break if you don't have either DPMI or Emacs | ||
| 903 | was compiler with Djgpp 1.11 maintenance level 2 or later! */ | ||
| 904 | ctrlbreakinstalled = 1; | ||
| 905 | ctrl_break_vector.pm_offset = (int) ctrl_break_func; | ||
| 906 | _go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector, | ||
| 907 | &ctrl_break_regs); | ||
| 908 | _go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector); | ||
| 909 | } | ||
| 910 | } | ||
| 911 | |||
| 912 | |||
| 913 | /* Mouse routines under devellopment follow. Coordinates are in screen | ||
| 914 | positions and zero based. Mouse buttons are numbered from left to | ||
| 915 | right and also zero based. */ | ||
| 916 | |||
| 917 | static int mouse_button_translate[NUM_MOUSE_BUTTONS]; | ||
| 918 | static int mouse_button_count; | ||
| 919 | |||
| 920 | void | ||
| 921 | mouse_init () | ||
| 922 | { | ||
| 923 | union REGS regs; | ||
| 924 | |||
| 925 | regs.x.ax = 0x0007; | ||
| 926 | regs.x.cx = 0; | ||
| 927 | regs.x.dx = 8 * (ScreenCols () - 1); | ||
| 928 | int86 (0x33, ®s, ®s); | ||
| 929 | |||
| 930 | regs.x.ax = 0x0008; | ||
| 931 | regs.x.cx = 0; | ||
| 932 | regs.x.dx = 8 * (ScreenRows () - 1); | ||
| 933 | int86 (0x33, ®s, ®s); | ||
| 934 | |||
| 935 | mouse_moveto (ScreenCols () - 1, ScreenRows () - 1); | ||
| 936 | mouse_on (); | ||
| 937 | } | ||
| 938 | |||
| 939 | void | ||
| 940 | mouse_on () | ||
| 941 | { | ||
| 942 | union REGS regs; | ||
| 943 | |||
| 944 | regs.x.ax = 0x0001; | ||
| 945 | int86 (0x33, ®s, ®s); | ||
| 946 | } | ||
| 947 | |||
| 948 | void | ||
| 949 | mouse_off () | ||
| 950 | { | ||
| 951 | union REGS regs; | ||
| 952 | |||
| 953 | regs.x.ax = 0x0002; | ||
| 954 | int86 (0x33, ®s, ®s); | ||
| 955 | } | ||
| 956 | |||
| 957 | void | ||
| 958 | mouse_moveto (x, y) | ||
| 959 | int x, y; | ||
| 960 | { | ||
| 961 | union REGS regs; | ||
| 962 | |||
| 963 | regs.x.ax = 0x0004; | ||
| 964 | mouse_last_x = regs.x.cx = x * 8; | ||
| 965 | mouse_last_y = regs.x.dx = y * 8; | ||
| 966 | int86 (0x33, ®s, ®s); | ||
| 967 | } | ||
| 968 | |||
| 969 | int | ||
| 970 | mouse_pressed (b, xp, yp) | ||
| 971 | int b, *xp, *yp; | ||
| 972 | { | ||
| 973 | union REGS regs; | ||
| 974 | |||
| 975 | if (b >= mouse_button_count) | ||
| 976 | return 0; | ||
| 977 | regs.x.ax = 0x0005; | ||
| 978 | regs.x.bx = mouse_button_translate[b]; | ||
| 979 | int86 (0x33, ®s, ®s); | ||
| 980 | if (regs.x.bx) | ||
| 981 | *xp = regs.x.cx / 8, *yp = regs.x.dx /8; | ||
| 982 | return (regs.x.bx != 0); | ||
| 983 | } | ||
| 984 | |||
| 985 | int | ||
| 986 | mouse_released (b, xp, yp) | ||
| 987 | int b, *xp, *yp; | ||
| 988 | { | ||
| 989 | union REGS regs; | ||
| 990 | |||
| 991 | if (b >= mouse_button_count) | ||
| 992 | return 0; | ||
| 993 | regs.x.ax = 0x0006; | ||
| 994 | regs.x.bx = mouse_button_translate[b]; | ||
| 995 | int86 (0x33, ®s, ®s); | ||
| 996 | if (regs.x.bx) | ||
| 997 | *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; | ||
| 998 | return (regs.x.bx != 0); | ||
| 999 | } | ||
| 1000 | |||
| 1001 | void | ||
| 1002 | mouse_get_pos (f, bar_window, part, x, y, time) | ||
| 1003 | FRAME_PTR *f; | ||
| 1004 | Lisp_Object *bar_window, *x, *y; | ||
| 1005 | enum scroll_bar_part *part; | ||
| 1006 | unsigned long *time; | ||
| 1007 | { | ||
| 1008 | union REGS regs; | ||
| 1009 | struct timeval tv; | ||
| 1010 | |||
| 1011 | regs.x.ax = 0x0003; | ||
| 1012 | int86 (0x33, ®s, ®s); | ||
| 1013 | *f = selected_frame; | ||
| 1014 | *bar_window = Qnil; | ||
| 1015 | gettimeofday (&tv, NULL); | ||
| 1016 | *x = make_number (regs.x.cx / 8); | ||
| 1017 | *y = make_number (regs.x.dx / 8); | ||
| 1018 | *time = tv.tv_usec; | ||
| 1019 | mouse_moved = 0; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | void | ||
| 1023 | mouse_check_moved () | ||
| 1024 | { | ||
| 1025 | union REGS regs; | ||
| 1026 | |||
| 1027 | regs.x.ax = 0x0003; | ||
| 1028 | int86 (0x33, ®s, ®s); | ||
| 1029 | if (regs.x.cx != mouse_last_x || regs.x.dx != mouse_last_y) | ||
| 1030 | { | ||
| 1031 | mouse_moved = 1; | ||
| 1032 | mouse_last_x = regs.x.cx; | ||
| 1033 | mouse_last_y = regs.x.dx; | ||
| 1034 | } | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | int | ||
| 1038 | mouse_init1 () | ||
| 1039 | { | ||
| 1040 | union REGS regs; | ||
| 1041 | int present; | ||
| 1042 | |||
| 1043 | regs.x.ax = 0x0021; | ||
| 1044 | int86 (0x33, ®s, ®s); | ||
| 1045 | present = internal_terminal && (regs.x.ax & 0xffff) == 0xffff; | ||
| 1046 | if (present) | ||
| 1047 | { | ||
| 1048 | if (regs.x.bx == 3) | ||
| 1049 | { | ||
| 1050 | mouse_button_count = 3; | ||
| 1051 | mouse_button_translate[0] = 0; /* Left */ | ||
| 1052 | mouse_button_translate[1] = 2; /* Middle */ | ||
| 1053 | mouse_button_translate[2] = 1; /* Right */ | ||
| 1054 | } | ||
| 1055 | else | ||
| 1056 | { | ||
| 1057 | mouse_button_count = 2; | ||
| 1058 | mouse_button_translate[0] = 0; | ||
| 1059 | mouse_button_translate[1] = 1; | ||
| 1060 | } | ||
| 1061 | mouse_position_hook = &mouse_get_pos; | ||
| 1062 | mouse_init (); | ||
| 1063 | } | ||
| 1064 | return present; | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | #endif /* MSDOS */ | ||
diff --git a/src/msdos.h b/src/msdos.h new file mode 100644 index 00000000000..bf3030c00df --- /dev/null +++ b/src/msdos.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* MS-DOS specific C utilities, interface. | ||
| 2 | Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | #include <time.h> | ||
| 21 | #include <dpmi.h> | ||
| 22 | |||
| 23 | int dos_ttraw (); | ||
| 24 | int dos_ttcooked (); | ||
| 25 | int getdefdir (int, char*); | ||
| 26 | void unixtodos_filename (char *); | ||
| 27 | void dostounix_filename (char *); | ||
| 28 | void sleep_or_kbd_hit (int, int); | ||
| 29 | void init_environment (); | ||
| 30 | void internal_terminal_init (); | ||
| 31 | #ifndef _stdio_h_ | ||
| 32 | int internal_flush (FILE *); | ||
| 33 | #endif | ||
| 34 | void ctrl_break_func (_go32_dpmi_registers *); | ||
| 35 | void install_ctrl_break_check (); | ||
| 36 | |||
| 37 | extern int have_mouse; | ||
| 38 | int mouse_init1 (); | ||
| 39 | void mouse_init (); | ||
| 40 | void mouse_on (); | ||
| 41 | void mouse_off (); | ||
| 42 | void mouse_moveto (int, int); | ||
| 43 | void mouse_check_moved (); | ||
| 44 | int mouse_pressed (int, int *, int *); | ||
| 45 | int mouse_released (int, int *, int *); | ||
diff --git a/src/s/msdos.h b/src/s/msdos.h new file mode 100644 index 00000000000..10c15ee682e --- /dev/null +++ b/src/s/msdos.h | |||
| @@ -0,0 +1,219 @@ | |||
| 1 | /* System description file for MS-DOS | ||
| 2 | |||
| 3 | Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 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. | ||
| 11 | |||
| 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. | ||
| 16 | |||
| 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. */ | ||
| 20 | |||
| 21 | /* Note: lots of stuff here was taken from s-msdos.h in demacs. */ | ||
| 22 | |||
| 23 | |||
| 24 | /* | ||
| 25 | * Define symbols to identify the version of Unix this is. | ||
| 26 | * Define all the symbols that apply correctly. | ||
| 27 | */ | ||
| 28 | |||
| 29 | /* #define UNIPLUS */ | ||
| 30 | /* #define USG5 */ | ||
| 31 | /* #define USG */ | ||
| 32 | /* #define HPUX */ | ||
| 33 | /* #define UMAX */ | ||
| 34 | /* #define BSD4_1 */ | ||
| 35 | /* #define BSD4_2 */ | ||
| 36 | /* #define BSD4_3 */ | ||
| 37 | /* #define BSD */ | ||
| 38 | /* #define VMS */ | ||
| 39 | #ifndef MSDOS | ||
| 40 | #define MSDOS | ||
| 41 | #endif | ||
| 42 | #undef BSD | ||
| 43 | #undef VMS | ||
| 44 | |||
| 45 | /* SYSTEM_TYPE should indicate the kind of system you are using. | ||
| 46 | It sets the Lisp variable system-type. */ | ||
| 47 | |||
| 48 | #define SYSTEM_TYPE "ms-dos" | ||
| 49 | |||
| 50 | #define SYMS_SYSTEM syms_of_dosfns() | ||
| 51 | |||
| 52 | /* NOMULTIPLEJOBS should be defined if your system's shell | ||
| 53 | does not have "job control" (the ability to stop a program, | ||
| 54 | run some other program, then continue the first one). */ | ||
| 55 | |||
| 56 | #define NOMULTIPLEJOBS | ||
| 57 | |||
| 58 | /* Emacs can read input using SIGIO and buffering characters itself, | ||
| 59 | or using CBREAK mode and making C-g cause SIGINT. | ||
| 60 | The choice is controlled by the variable interrupt_input. | ||
| 61 | Define INTERRUPT_INPUT to make interrupt_input = 1 the default (use SIGIO) | ||
| 62 | |||
| 63 | SIGIO can be used only on systems that implement it (4.2 and 4.3). | ||
| 64 | CBREAK mode has two disadvatages | ||
| 65 | 1) At least in 4.2, it is impossible to handle the Meta key properly. | ||
| 66 | I hear that in system V this problem does not exist. | ||
| 67 | 2) Control-G causes output to be discarded. | ||
| 68 | I do not know whether this can be fixed in system V. | ||
| 69 | |||
| 70 | Another method of doing input is planned but not implemented. | ||
| 71 | It would have Emacs fork off a separate process | ||
| 72 | to read the input and send it to the true Emacs process | ||
| 73 | through a pipe. | ||
| 74 | */ | ||
| 75 | |||
| 76 | /* #define INTERRUPT_INPUT */ | ||
| 77 | |||
| 78 | /* Letter to use in finding device name of first pty, | ||
| 79 | if system supports pty's. 'a' means it is /dev/ptya0 */ | ||
| 80 | |||
| 81 | /* #define FIRST_PTY_LETTER 'a' */ | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Define HAVE_TIMEVAL if the system supports the BSD style clock values. | ||
| 85 | * Look in <sys/time.h> for a timeval structure. | ||
| 86 | */ | ||
| 87 | |||
| 88 | #define HAVE_TIMEVAL | ||
| 89 | |||
| 90 | /* | ||
| 91 | * Define HAVE_SELECT if the system supports the `select' system call. | ||
| 92 | */ | ||
| 93 | |||
| 94 | /* #define HAVE_SELECT */ | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Define HAVE_PTYS if the system supports pty devices. | ||
| 98 | */ | ||
| 99 | |||
| 100 | /* #define HAVE_PTYS */ | ||
| 101 | |||
| 102 | /* | ||
| 103 | * Define NONSYSTEM_DIR_LIBRARY to make Emacs emulate | ||
| 104 | * The 4.2 opendir, etc., library functions. | ||
| 105 | */ | ||
| 106 | |||
| 107 | /* #define NONSYSTEM_DIR_LIBRARY */ | ||
| 108 | |||
| 109 | #define SYSV_SYSTEM_DIR | ||
| 110 | |||
| 111 | /* Define this symbol if your system has the functions bcopy, etc. */ | ||
| 112 | |||
| 113 | #define BSTRING | ||
| 114 | |||
| 115 | /* subprocesses should be defined if you want to | ||
| 116 | have code for asynchronous subprocesses | ||
| 117 | (as used in M-x compile and M-x shell). | ||
| 118 | This is generally OS dependent, and not supported | ||
| 119 | under most USG systems. */ | ||
| 120 | |||
| 121 | #undef subprocesses | ||
| 122 | |||
| 123 | /* If your system uses COFF (Common Object File Format) then define the | ||
| 124 | preprocessor symbol "COFF". */ | ||
| 125 | |||
| 126 | #define COFF | ||
| 127 | |||
| 128 | /* define MAIL_USE_FLOCK if the mailer uses flock | ||
| 129 | to interlock access to /usr/spool/mail/$USER. | ||
| 130 | The alternative is that a lock file named | ||
| 131 | /usr/spool/mail/$USER.lock. */ | ||
| 132 | |||
| 133 | /* #define MAIL_USE_FLOCK */ | ||
| 134 | |||
| 135 | /* Define CLASH_DETECTION if you want lock files to be written | ||
| 136 | so that Emacs can tell instantly when you try to modify | ||
| 137 | a file that someone else has modified in his Emacs. */ | ||
| 138 | |||
| 139 | /* #define CLASH_DETECTION */ | ||
| 140 | |||
| 141 | /* Here, on a separate page, add any special hacks needed | ||
| 142 | to make Emacs work on this system. For example, | ||
| 143 | you might define certain system call names that don't | ||
| 144 | exist on your system, or that do different things on | ||
| 145 | your system and must be used only through an encapsulation | ||
| 146 | (Which you should place, by convention, in sysdep.c). */ | ||
| 147 | |||
| 148 | /* Some compilers tend to put everything declared static | ||
| 149 | into the initialized data area, which becomes pure after dumping Emacs. | ||
| 150 | On these systems, you must #define static as nothing to foil this. | ||
| 151 | Note that emacs carefully avoids static vars inside functions. */ | ||
| 152 | |||
| 153 | /* #define static */ | ||
| 154 | |||
| 155 | /* we use djgcc's malloc */ | ||
| 156 | /* #define SYSTEM_MALLOC */ | ||
| 157 | /* setjmp and longjmp can safely replace _setjmp and _longjmp, | ||
| 158 | but they will run slower. */ | ||
| 159 | |||
| 160 | #define _setjmp setjmp | ||
| 161 | #define _longjmp longjmp | ||
| 162 | |||
| 163 | #define NO_MODE_T | ||
| 164 | |||
| 165 | /* we can use dj's getpagesize() */ | ||
| 166 | #define HAVE_GETPAGESIZE | ||
| 167 | |||
| 168 | /* New chdir () routine. */ | ||
| 169 | #ifdef chdir | ||
| 170 | #undef chdir | ||
| 171 | #endif | ||
| 172 | #define chdir sys_chdir | ||
| 173 | |||
| 174 | #define LIBS_SYSTEM -lpc | ||
| 175 | |||
| 176 | /* This somehow needs to be defined even though we use COFF. */ | ||
| 177 | #define TEXT_START -1 | ||
| 178 | |||
| 179 | #define ORDINARY_LINK | ||
| 180 | |||
| 181 | /* command.com does not under stand `...` so we define this. */ | ||
| 182 | #define LIB_GCC -Lgcc | ||
| 183 | #define DONT_NEED_ENVIRON | ||
| 184 | #define SEPCHAR ';' | ||
| 185 | |||
| 186 | #define NULL_DEVICE "nul" | ||
| 187 | #define EXEC_SUFFIXES ".exe:.com:.bat:" | ||
| 188 | |||
| 189 | #define O_RDONLY 0x0001 | ||
| 190 | #define O_WRONLY 0x0002 | ||
| 191 | #define O_RDWR 0x0004 | ||
| 192 | #define O_CREAT 0x0100 | ||
| 193 | #define O_TRUNC 0x0200 | ||
| 194 | #define O_EXCL 0x0400 | ||
| 195 | #define O_APPEND 0x0800 | ||
| 196 | #define O_TEXT 0x4000 | ||
| 197 | #define O_BINARY 0x8000 | ||
| 198 | |||
| 199 | #define HAVE_INVERSE_HYPERBOLIC | ||
| 200 | #define FLOAT_CHECK_DOMAIN | ||
| 201 | |||
| 202 | /* When $TERM is "internal" then this is substituted: */ | ||
| 203 | #define INTERNAL_TERMINAL "pc|bios|IBM PC with colour display:\ | ||
| 204 | :co#80:li#25:km:\ | ||
| 205 | :cm=\E@%.%.:\ | ||
| 206 | :do=^J:le=^H:up=\EU:ri=\ER:\ | ||
| 207 | :ti=\EA\027:te=\EA\007\EE:\ | ||
| 208 | :so=\EA\077:se=\EA\027:\ | ||
| 209 | :ms:mb=\EX\200:md=\EX\010:mk=\EA\161:me=\EA\027:\ | ||
| 210 | :cl=\EC:ce=\EE:\ | ||
| 211 | :vb=\EB\140:bl=:" | ||
| 212 | #define fflush internal_flush | ||
| 213 | |||
| 214 | /* Define this to a function (Fdowncase, Fupcase) if your file system | ||
| 215 | likes that */ | ||
| 216 | #define FILE_SYSTEM_CASE Fdowncase | ||
| 217 | |||
| 218 | /* MSDOS doesn't really have this function. */ | ||
| 219 | #define getppid() 1 | ||