1 /* MS-DOS specific C utilities.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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)
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.
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. */
20 /* Contributed by Morten Welinder */
22 /* Note: some of the stuff here was taken from end of sysdep.c in demacs. */
30 #include <sys/param.h>
36 #include "termhooks.h"
41 /* #include <process.h> */
42 /* Damn that local process.h! Instead we can define P_WAIT ourselves. */
45 static int break_stat
; /* BREAK check mode status. */
46 static int stdin_stat
; /* stdin IOCTL status. */
47 static int extended_kbd
; /* 101 (102) keyboard present. */
49 int have_mouse
; /* Mouse present? */
50 static int mouse_last_x
;
51 static int mouse_last_y
;
53 /* Turn off Dos' Ctrl-C checking and inhibit interpretation of control chars
54 by Dos. Determine the keyboard type. */
58 union REGS inregs
, outregs
;
61 int86 (0x15, &inregs
, &outregs
);
62 extended_kbd
= (!outregs
.x
.cflag
) && (outregs
.h
.ah
== 0);
64 break_stat
= getcbrk ();
66 install_ctrl_break_check ();
67 have_mouse
= mouse_init1 ();
69 inregs
.x
.ax
= 0x4400; /* Get IOCTL status. */
70 inregs
.x
.bx
= 0x00; /* 0 = stdin. */
71 intdos (&inregs
, &outregs
);
72 stdin_stat
= outregs
.h
.dl
;
74 inregs
.x
.dx
= (outregs
.x
.dx
| 0x0020) & 0x0027; /* raw mode */
76 intdos (&inregs
, &outregs
);
77 return !outregs
.x
.cflag
;
80 /* Restore status of standard input and Ctrl-C checking. */
84 union REGS inregs
, outregs
;
87 if (have_mouse
) mouse_off ();
89 inregs
.x
.ax
= 0x4401; /* Set IOCTL status. */
90 inregs
.x
.bx
= 0x00; /* 0 = stdin. */
91 inregs
.x
.dx
= stdin_stat
;
92 intdos (&inregs
, &outregs
);
93 return !outregs
.x
.cflag
;
97 ibmpc_translate_map
[] =
99 /* --------------- 00 to 0f --------------- */
102 0xffb1, /* Keypad 1 */
103 0xffb2, /* Keypad 2 */
104 0xffb3, /* Keypad 3 */
105 0xffb4, /* Keypad 4 */
106 0xffb5, /* Keypad 5 */
107 0xffb6, /* Keypad 6 */
108 0xffb7, /* Keypad 7 */
109 0xffb8, /* Keypad 8 */
110 0xffb9, /* Keypad 9 */
111 0xffb0, /* Keypad 0 */
113 0xff08, /* Backspace */
114 0xff74, /* (Shift) Tab [Tab doesn't use this table] */
116 /* --------------- 10 to 1f --------------- */
117 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
118 0xff8d, /* Keypad Enter */
122 /* --------------- 20 to 2f --------------- */
123 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
125 '\\', 'z', 'x', 'c', 'v',
127 /* --------------- 30 to 3f --------------- */
128 'b', 'n', 'm', ',', '.',
141 /* --------------- 40 to 4f --------------- */
151 0xff55, /* Page Up */
154 0xffb5, /* Keypad 5 */
159 /* --------------- 50 to 5f --------------- */
161 0xff56, /* Page Down */
164 0xffbe, /* (Shift) F1 */
165 0xffbf, /* (Shift) F2 */
166 0xffc0, /* (Shift) F3 */
167 0xffc1, /* (Shift) F4 */
168 0xffc2, /* (Shift) F5 */
169 0xffc3, /* (Shift) F6 */
170 0xffc4, /* (Shift) F7 */
171 0xffc5, /* (Shift) F8 */
172 0xffc6, /* (Shift) F9 */
173 0xffc7, /* (Shift) F10 */
174 0xffbe, /* (Ctrl) F1 */
175 0xffbf, /* (Ctrl) F2 */
177 /* --------------- 60 to 6f --------------- */
178 0xffc0, /* (Ctrl) F3 */
179 0xffc1, /* (Ctrl) F4 */
180 0xffc2, /* (Ctrl) F5 */
181 0xffc3, /* (Ctrl) F6 */
182 0xffc4, /* (Ctrl) F7 */
183 0xffc5, /* (Ctrl) F8 */
184 0xffc6, /* (Ctrl) F9 */
185 0xffc7, /* (Ctrl) F10 */
186 0xffbe, /* (Alt) F1 */
187 0xffbf, /* (Alt) F2 */
188 0xffc0, /* (Alt) F3 */
189 0xffc1, /* (Alt) F4 */
190 0xffc2, /* (Alt) F5 */
191 0xffc3, /* (Alt) F6 */
192 0xffc4, /* (Alt) F7 */
193 0xffc5, /* (Alt) F8 */
195 /* --------------- 70 to 7f --------------- */
196 0xffc6, /* (Alt) F9 */
197 0xffc7, /* (Alt) F10 */
198 0xff6d, /* (Ctrl) Sys Rq */
199 0xff51, /* (Ctrl) Left */
200 0xff53, /* (Ctrl) Right */
201 0xff57, /* (Ctrl) End */
202 0xff56, /* (Ctrl) Page Down */
203 0xff50, /* (Ctrl) Home */
204 '1', '2', '3', '4', '5', '6', '7', '8', /* (Alt) */
206 /* --------------- 80 to 8f --------------- */
207 '9', '0', '-', '=', /* (Alt) */
208 0xff55, /* (Ctrl) Page Up */
211 0xffc8, /* (Shift) F11 */
212 0xffc9, /* (Shift) F12 */
213 0xffc8, /* (Ctrl) F11 */
214 0xffc9, /* (Ctrl) F12 */
215 0xffc8, /* (Alt) F11 */
216 0xffc9, /* (Alt) F12 */
217 0xff52, /* (Ctrl) Up */
218 0xffae, /* (Ctrl) Grey - */
219 0xffb5, /* (Ctrl) Keypad 5 */
221 /* --------------- 90 to 9f --------------- */
222 0xffab, /* (Ctrl) Grey + */
223 0xff54, /* (Ctrl) Down */
224 0xff63, /* (Ctrl) Insert */
225 0xffff, /* (Ctrl) Delete */
226 0xff09, /* (Ctrl) Tab */
227 0xffaf, /* (Ctrl) Grey / */
228 0xffaa, /* (Ctrl) Grey * */
229 0xff50, /* (Alt) Home */
230 0xff52, /* (Alt) Up */
231 0xff55, /* (Alt) Page Up */
233 0xff51, /* (Alt) Left */
235 0xff53, /* (Alt) Right */
237 0xff57, /* (Alt) End */
239 /* --------------- a0 to af --------------- */
240 0xff54, /* (Alt) Down */
241 0xff56, /* (Alt) Page Down */
242 0xff63, /* (Alt) Insert */
243 0xffff, /* (Alt) Delete */
244 0xffaf, /* (Alt) Grey / */
245 0xff09, /* (Alt) Tab */
246 0xff0d /* (Alt) Enter */
249 /* Get a char from keyboard. Function keys are put into the event queue. */
253 struct input_event event
;
256 int ctrl_p
, alt_p
, shift_p
;
258 /* Calculate modifier bits */
259 regs
.h
.ah
= extended_kbd
? 0x12 : 0x02;
260 int86 (0x16, ®s
, ®s
);
261 ctrl_p
= ((regs
.h
.al
& 4) != 0);
262 shift_p
= ((regs
.h
.al
& 3) != 0);
263 /* Please be very careful here not to break international keyboard support.
264 When Keyb.Com is loaded, the key marked `Alt Gr' is used for accessing
265 characters like { and } if their positions are overlaid. */
266 alt_p
= ((extended_kbd
? (regs
.h
.ah
& 2) : (regs
.h
.al
& 8)) != 0);
271 register unsigned char c
;
274 regs
.h
.ah
= extended_kbd
? 0x10 : 0x00;
275 int86 (0x16, ®s
, ®s
);
279 /* Determine from the scan code if a keypad key was pressed. */
280 if (c
>= '0' && c
<= '9' && sc
> 0xb)
281 sc
= (c
== '0') ? 0xb : (c
- '0' + 1), c
= 0;
282 else if (sc
== 0x53 && c
!= 0xe0)
284 code
= 0xffae; /* Keypad decimal point/comma. */
291 case 10: /* Ctrl Enter */
307 || (ctrl_p
&& shift_p
)
308 || (c
== 0xe0 && sc
!= 0) /* Pseudo-key */
309 || sc
== 0x37 /* Grey * */
310 || sc
== 0x4a /* Grey - */
311 || sc
== 0x4e /* Grey + */
312 || sc
== 0x0e) /* Back space *key*, not Ctrl-h */
314 if (sc
>= (sizeof (ibmpc_translate_map
) / sizeof (short)))
317 code
= ibmpc_translate_map
[sc
];
323 event
.kind
= non_ascii_keystroke
;
324 event
.code
= (code
& 0xff) + 0xff00;
328 /* Don't return S- if we don't have to. `shifted' is
329 supposed to be the shifted versions of the characters
330 in `unshifted'. Unfortunately, this is only true for
331 US keyboard layout. If anyone knows how to do this
332 right, please tell us. */
333 static char *unshifted
334 = "abcdefghijklmnopqrstuvwxyz,./=;[\\]'-`0123456789";
336 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ<>?+:{|}\"_~)!@#$%^&*(";
339 if (shift_p
&& (pos
= strchr (unshifted
, code
)))
341 c
= shifted
[pos
- unshifted
];
345 if (c
== 0) c
= code
;
346 event
.kind
= ascii_keystroke
;
350 = (shift_p
? shift_modifier
: 0)
351 + (ctrl_p
? ctrl_modifier
: 0)
352 + (alt_p
? meta_modifier
: 0);
353 /* EMACS == Enter Meta Alt Control Shift */
354 event
.frame_or_window
= selected_frame
;
355 gettimeofday (&tv
, NULL
);
356 event
.timestamp
= tv
.tv_usec
;
357 kbd_buffer_store_event (&event
);
365 int but
, press
, x
, y
, ok
;
367 /* Check for mouse movement *before* buttons. */
368 mouse_check_moved ();
370 for (but
= 0; but
< NUM_MOUSE_BUTTONS
; but
++)
371 for (press
= 0; press
< 2; press
++)
374 ok
= mouse_pressed (but
, &x
, &y
);
376 ok
= mouse_released (but
, &x
, &y
);
379 event
.kind
= mouse_click
;
382 = (shift_p
? shift_modifier
: 0)
383 + (ctrl_p
? ctrl_modifier
: 0)
384 + (alt_p
? meta_modifier
: 0)
385 + (press
? down_modifier
: up_modifier
);
388 event
.frame_or_window
= selected_frame
;
389 gettimeofday (&tv
, NULL
);
390 event
.timestamp
= tv
.tv_usec
;
391 kbd_buffer_store_event (&event
);
399 static int prev_get_char
= -1;
401 /* Return 1 if a key is ready to be read without suspending execution. */
404 if (prev_get_char
!= -1)
407 return ((prev_get_char
= dos_rawgetc ()) != -1);
410 /* Read a key. Return -1 if no key is ready. */
413 if (prev_get_char
!= -1)
415 int c
= prev_get_char
;
420 return dos_rawgetc ();
423 /* Hostnames for a pc are not really funny, but they are used in change log
424 so we emulate the best we can. */
425 gethostname (p
, size
)
429 char *q
= egetenv ("HOSTNAME");
436 /* Destructively turn backslashes into slashes. */
438 dostounix_filename (p
)
449 /* Destructively turn slashes into backslashes. */
451 unixtodos_filename (p
)
462 /* Get the default directory for a given drive. 0=def, 1=A, 2=B, ... */
464 getdefdir (drive
, dst
)
472 regs
.x
.si
= (int) dst
;
474 intdos (®s
, ®s
);
475 return !regs
.x
.cflag
;
478 /* Remove all CR's that are followed by a LF. */
482 register unsigned char *buf
;
484 unsigned char *np
= buf
;
485 unsigned char *startp
= buf
;
486 unsigned char *endp
= buf
+ n
;
491 while (buf
< endp
- 1)
495 if (*(++buf
) != 0x0a)
507 /* Run command as specified by ARGV in directory DIR.
508 The command is run with input from TEMPIN and output to file TEMPOUT. */
510 run_msdos_command (argv
, dir
, tempin
, tempout
)
511 unsigned char **argv
;
515 char *saveargv1
, *saveargv2
, **envv
;
516 char oldwd
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
517 int msshell
, result
= -1;
518 int in
, out
, inbak
, outbak
, errbak
;
521 /* Get current directory as MSDOS cwd is not per-process. */
524 cmd
= Ffile_name_nondirectory (build_string (argv
[0]));
525 msshell
= !NILP (Fmember (cmd
, Fsymbol_value (intern ("msdos-shells"))))
526 && !strcmp ("-c", argv
[1]);
534 char *p
= alloca (strlen (argv
[2]) + 1);
536 strcpy (argv
[2] = p
, saveargv2
);
537 while (*p
&& isspace (*p
))
539 while (*p
&& !isspace (*p
))
547 /* Build the environment array. */
549 extern Lisp_Object Vprocess_environment
;
550 Lisp_Object tmp
, lst
;
553 lst
= Vprocess_environment
;
554 len
= XFASTINT (Flength (lst
));
556 envv
= alloca ((len
+ 1) * sizeof (char *));
557 for (i
= 0; i
< len
; i
++)
561 CHECK_STRING (tmp
, 0);
562 envv
[i
] = alloca (XSTRING (tmp
)->size
+ 1);
563 strcpy (envv
[i
], XSTRING (tmp
)->data
);
565 envv
[len
] = (char *) 0;
568 if (XTYPE (dir
) == Lisp_String
)
569 chdir (XSTRING (dir
)->data
);
573 if (inbak
< 0 || outbak
< 0 || errbak
< 0)
574 goto done
; /* Allocation might fail due to lack of descriptors. */
579 result
= spawnve (P_WAIT
, argv
[0], argv
, envv
);
599 fprintf (stderr
, "%s not yet implemented\r\n", badfunc
);
604 /* A list of unimplemented functions that we silently ignore. */
605 unsigned alarm (s
) unsigned s
; {}
606 fork () { return 0; }
607 int kill (x
, y
) int x
, y
; { return -1; }
609 void volatile pause () {}
611 setpgrp () {return 0; }
612 setpriority (x
,y
,z
) int x
,y
,z
; { return 0; }
613 sigsetmask (x
) int x
; { return 0; }
614 unrequest_sigio () {}
624 int len
= strlen (path
);
625 char *tmp
= (char *) alloca (len
+ 1);
626 /* Gotta do this extern here due to the corresponding #define: */
629 if (*path
&& path
[1] == ':' && (getdisk () != tolower (path
[0]) - 'a'))
630 setdisk (tolower (path
[0]) - 'a');
633 if (strcmp (path
, "/") && strcmp (path
+ 1, ":/") && (path
[len
- 1] == '/'))
638 /* Sleep SECS. If KBDOK also return immediately if a key is pressed. */
640 sleep_or_kbd_hit (secs
, kbdok
)
646 gettimeofday (&t
, NULL
);
647 clnow
= t
.tv_sec
* 100 + t
.tv_usec
/ 10000;
648 clthen
= clnow
+ (100 * secs
);
652 gettimeofday (&t
, NULL
);
653 clnow
= t
.tv_sec
* 100 + t
.tv_usec
/ 10000;
654 if (kbdok
&& detect_input_pending ())
657 while (clnow
< clthen
);
660 /* The Emacs root directory as determined by init_environment. */
661 static char emacsroot
[MAXPATHLEN
];
664 rootrelativepath (rel
)
667 static char result
[MAXPATHLEN
+ 10];
669 strcpy (result
, emacsroot
);
670 strcat (result
, "/");
671 strcat (result
, rel
);
675 /* Define a lot of environment variables if not already defined. Don't
676 remove anything unless you know what you're doing -- lots of code will
677 break if one or more of these are missing. */
679 init_environment (argc
, argv
, skip_args
)
687 /* Find our root from argv[0]. Assuming argv[0] is, say,
688 "c:/emacs/bin/emacs.exe" our root will be "c:/emacs". */
689 len
= strlen (argv
[0]);
690 root
= alloca (len
+ 10); /* A little extra space for the stuff below. */
691 strcpy (root
, argv
[0]);
692 while (len
> 0 && root
[len
] != '/' && root
[len
] != ':')
695 if (len
> 4 && strcmp (root
+ len
- 4, "/bin") == 0)
696 root
[len
- 4] = '\0';
698 strcpy (root
, "c:/emacs"); /* Only under debuggers, I think. */
700 strcpy (emacsroot
, root
);
702 /* We default HOME to our root. */
703 setenv ("HOME", root
, 0);
705 /* We default EMACSPATH to root + "/bin". */
706 strcpy (root
+ len
, "/bin");
707 setenv ("EMACSPATH", root
, 0);
709 /* I don't expect anybody to ever use other terminals so the internal
710 terminal is the default. */
711 setenv ("TERM", "internal", 0);
713 /* SHELL is a bit tricky -- COMSPEC is the closest we come, but we must
714 downcase it and mirror the backslashes. */
715 s
= getenv ("COMSPEC");
716 if (!s
) s
= "c:/command.com";
717 t
= alloca (strlen (s
) + 1);
720 dostounix_filename (t
);
721 setenv ("SHELL", t
, 0);
723 /* PATH is also downcased and backslashes mirrored. */
726 t
= alloca (strlen (s
) + 3);
727 /* Current directory is always considered part of MsDos's path but it is
728 not normally mentioned. Now it is. */
729 strcat (strcpy (t
, ".;"), s
);
731 dostounix_filename (t
); /* Not a single file name, but this should work. */
732 setenv ("PATH", t
, 1);
734 /* In some sense all dos users have root privileges, so... */
735 setenv ("USER", "root", 0);
736 setenv ("NAME", getenv ("USER"), 0);
738 /* Time zone determined from country code. To make this possible, the
739 country code may not span more than one time zone. In other words,
740 in the USA, you lose. */
741 switch (dos_country_code
)
743 case 31: /* Belgium */
744 case 32: /* The Netherlands */
745 case 33: /* France */
747 case 36: /* Hungary */
748 case 38: /* Yugoslavia (or what's left of it?) */
750 case 41: /* Switzerland */
751 case 42: /* Tjekia */
752 case 45: /* Denmark */
753 case 46: /* Sweden */
754 case 47: /* Norway */
755 case 48: /* Poland */
756 case 49: /* Germany */
757 /* Daylight saving from last Sunday in March to last Sunday in
758 September, both at 2AM. */
759 setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0);
761 case 44: /* United Kingdom */
762 case 351: /* Portugal */
763 case 354: /* Iceland */
764 setenv ("TZ", "GMT+00", 0);
768 setenv ("TZ", "???-09", 0);
770 case 90: /* Turkey */
771 case 358: /* Finland */
772 case 972: /* Israel */
773 setenv ("TZ", "EET-02", 0);
777 init_gettimeofday ();
780 /* Flash the screen as a substitute for BEEPs. */
782 static unsigned char _xorattr
;
785 do_visible_bell (xorattr
)
786 unsigned char xorattr
;
800 movl _ScreenPrimary,%eax
830 /* At screen position (X,Y), output C characters from string S with
831 attribute A. Do it fast! */
834 output_string (x
, y
, s
, c
, a
)
839 char *t
= (char *)ScreenPrimary
+ 2 * (x
+ ScreenCols () * y
);
849 movw %%ax,%%gs:(%%edi)
855 : "m" (a
), "g" (t
), "g" (c
), "g" (s
)
856 : "%eax", "%ecx", /* "%gs",*/ "%esi", "%edi");
859 static int internal_terminal
= 0;
866 static char spaces
[] = " ";
869 unsigned char *cp
, *cp0
;
872 if (internal_terminal
&& f
== stdout
)
874 if (have_mouse
) mouse_off ();
876 count
= stdout
->_ptr
- stdout
->_base
;
890 ScreenAttrib
= *cp
++;
894 do_visible_bell (*cp
++);
903 i
= ScreenCols () - x
;
905 while (i
>= sizeof spaces
)
907 output_string (j
, y
, spaces
, sizeof spaces
,
913 output_string (j
, y
, spaces
, i
, ScreenAttrib
);
925 ScreenAttrib
^= *cp
++;
933 write (1, "\007", 1);
951 while (count
> 0 && *cp
>= ' ')
953 output_string (x
, y
, cp0
, cp
- cp0
, ScreenAttrib
);
958 ScreenSetCursor (y
, x
);
959 if (have_mouse
) mouse_on ();
962 /* This is a call to the original fflush. */
966 /* Do we need the internal terminal? */
968 internal_terminal_init ()
970 char *term
= getenv ("TERM");
973 = (!noninteractive
) && term
&& !strcmp (term
, "internal");
976 /* When time zones are set from Ms-Dos too may C-libraries are playing
977 tricks with time values. We solve this by defining our own version
978 of `gettimeofday' bypassing GO32. Our version needs to be initialized
979 once and after each call to `tzset' with TZ changed. */
981 static int daylight
, gmtoffset
;
984 gettimeofday (struct timeval
*tp
, struct timezone
*tzp
)
994 tmrec
.tm_year
= d
.da_year
- 1900;
995 tmrec
.tm_mon
= d
.da_mon
- 1;
996 tmrec
.tm_mday
= d
.da_day
;
997 tmrec
.tm_hour
= t
.ti_hour
;
998 tmrec
.tm_min
= t
.ti_min
;
999 tmrec
.tm_sec
= t
.ti_sec
;
1000 tmrec
.tm_gmtoff
= gmtoffset
;
1001 tmrec
.tm_isdst
= daylight
;
1002 tp
->tv_sec
= mktime (&tmrec
);
1003 tp
->tv_usec
= t
.ti_hund
* (1000000 / 100);
1007 tzp
->tz_minuteswest
= gmtoffset
;
1008 tzp
->tz_dsttime
= daylight
;
1014 init_gettimeofday ()
1021 ltm
= gtm
= time (NULL
);
1022 ltm
= mktime (lstm
= localtime (<m
));
1023 gtm
= mktime (gmtime (>m
));
1024 daylight
= lstm
->tm_isdst
;
1025 gmtoffset
= (int)(gtm
- ltm
) / 60;
1028 /* These must be global. */
1029 static _go32_dpmi_seginfo ctrl_break_vector
;
1030 static _go32_dpmi_registers ctrl_break_regs
;
1031 static int ctrlbreakinstalled
= 0;
1033 /* Interrupt level detection of Ctrl-Break. Don't do anything fancy here! */
1035 ctrl_break_func (regs
)
1036 _go32_dpmi_registers
*regs
;
1042 install_ctrl_break_check ()
1044 if (!ctrlbreakinstalled
)
1046 /* Don't press Ctrl-Break if you don't have either DPMI or Emacs
1047 was compiler with Djgpp 1.11 maintenance level 2 or later! */
1048 ctrlbreakinstalled
= 1;
1049 ctrl_break_vector
.pm_offset
= (int) ctrl_break_func
;
1050 _go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector
,
1052 _go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector
);
1057 /* Mouse routines under devellopment follow. Coordinates are in screen
1058 positions and zero based. Mouse buttons are numbered from left to
1059 right and also zero based. */
1061 static int mouse_button_translate
[NUM_MOUSE_BUTTONS
];
1062 static int mouse_button_count
;
1071 regs
.x
.dx
= 8 * (ScreenCols () - 1);
1072 int86 (0x33, ®s
, ®s
);
1076 regs
.x
.dx
= 8 * (ScreenRows () - 1);
1077 int86 (0x33, ®s
, ®s
);
1079 mouse_moveto (ScreenCols () - 1, ScreenRows () - 1);
1089 int86 (0x33, ®s
, ®s
);
1098 int86 (0x33, ®s
, ®s
);
1108 mouse_last_x
= regs
.x
.cx
= x
* 8;
1109 mouse_last_y
= regs
.x
.dx
= y
* 8;
1110 int86 (0x33, ®s
, ®s
);
1114 mouse_pressed (b
, xp
, yp
)
1119 if (b
>= mouse_button_count
)
1122 regs
.x
.bx
= mouse_button_translate
[b
];
1123 int86 (0x33, ®s
, ®s
);
1125 *xp
= regs
.x
.cx
/ 8, *yp
= regs
.x
.dx
/8;
1126 return (regs
.x
.bx
!= 0);
1130 mouse_released (b
, xp
, yp
)
1135 if (b
>= mouse_button_count
)
1138 regs
.x
.bx
= mouse_button_translate
[b
];
1139 int86 (0x33, ®s
, ®s
);
1141 *xp
= regs
.x
.cx
/ 8, *yp
= regs
.x
.dx
/ 8;
1142 return (regs
.x
.bx
!= 0);
1146 mouse_get_pos (f
, bar_window
, part
, x
, y
, time
)
1148 Lisp_Object
*bar_window
, *x
, *y
;
1149 enum scroll_bar_part
*part
;
1150 unsigned long *time
;
1156 int86 (0x33, ®s
, ®s
);
1157 *f
= selected_frame
;
1159 gettimeofday (&tv
, NULL
);
1160 *x
= make_number (regs
.x
.cx
);
1161 *y
= make_number (regs
.x
.dx
);
1167 mouse_check_moved ()
1172 int86 (0x33, ®s
, ®s
);
1173 if (regs
.x
.cx
!= mouse_last_x
|| regs
.x
.dx
!= mouse_last_y
)
1176 mouse_last_x
= regs
.x
.cx
;
1177 mouse_last_y
= regs
.x
.dx
;
1188 int86 (0x33, ®s
, ®s
);
1189 present
= internal_terminal
&& (regs
.x
.ax
& 0xffff) == 0xffff;
1194 mouse_button_count
= 3;
1195 mouse_button_translate
[0] = 0; /* Left */
1196 mouse_button_translate
[1] = 2; /* Middle */
1197 mouse_button_translate
[2] = 1; /* Right */
1201 mouse_button_count
= 2;
1202 mouse_button_translate
[0] = 0;
1203 mouse_button_translate
[1] = 1;
1205 mouse_position_hook
= &mouse_get_pos
;
1211 /* See xterm.c for more info. */
1213 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1215 register int pix_x
, pix_y
;
1216 register int *x
, *y
;
1217 void /* XRectangle */ *bounds
;
1220 if (bounds
) abort ();
1222 /* Ignore clipping. */
1229 glyph_to_pixel_coords (f
, x
, y
, pix_x
, pix_y
)
1232 register int *pix_x
, *pix_y
;