aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1995-09-03 17:32:58 +0000
committerRichard M. Stallman1995-09-03 17:32:58 +0000
commitaee81730019fba3d28a288fd843921671826c523 (patch)
tree2de6649b513e93126b536f5c1785f7e28e2e34b6 /src
parentc70c27055d0cd10097196099b5429af2e9638d08 (diff)
downloademacs-aee81730019fba3d28a288fd843921671826c523.tar.gz
emacs-aee81730019fba3d28a288fd843921671826c523.zip
(putchar): Call internal_flush instead of _flsbuf.
(DO_TERMSCRIPT): New macro to support open-termscript. (internal_flush): Corrected handling of flush in middle of escape sequences. Handle screen width > 127. (flush_escape): New function for use by internal_flush. (sys_select): New MS-DOS specific version with us timing. (EMACSCOLORS): New environment variable. (IT_clear_end_of_line): Set default face. (run_msdos_command): Restore mouse position after command. Close "backup fd"s. Corrected switch to cooked mode while running command. (mouse_on, mouse_off): Now checks have_mouse > 0. Note: "have_mouse < 0" means that a mouse is present, but it has been disabled via msdos-mouse-disable. (IT_write_glyphs): Allow esc-character itself to be printed. (event_timestamp): New function to make reliable times stamps. (sys_chdir): Skip drive letter before calling chdir. (sleep_or_kbd_hit): Handle 60 seconds time wrap. (mouse_get_pos): Return event_timestamp.
Diffstat (limited to 'src')
-rw-r--r--src/msdos.c665
1 files changed, 451 insertions, 214 deletions
diff --git a/src/msdos.c b/src/msdos.c
index 4adb6408fed..c93da0bc942 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -53,29 +53,49 @@ int have_mouse; /* Mouse present? */
53static int mouse_last_x; 53static int mouse_last_x;
54static int mouse_last_y; 54static int mouse_last_y;
55 55
56#define DO_TERMSCRIPT /* define if you want open-termscript to work on msdos */
57
58/* Standard putchar may call _flsbuf which doesn't go through
59 fflush's overlayed internal_flush routine. */
60#undef putchar
61#define putchar(x) \
62 (--(stdout)->_cnt>=0? \
63 ((int)((unsigned char)((*(stdout)->_ptr++=(unsigned)(x))))): \
64 (internal_flush (stdout), --(stdout)->_cnt, *(stdout)->_ptr++=(unsigned)(x)))
65
66static void
67mouse_get_xy (int *x, int *y);
68
56/* Turn off Dos' Ctrl-C checking and inhibit interpretation of control chars 69/* Turn off Dos' Ctrl-C checking and inhibit interpretation of control chars
57 by Dos. Determine the keyboard type. */ 70 by Dos. Determine the keyboard type. */
58int 71int
59dos_ttraw () 72dos_ttraw ()
60{ 73{
61 union REGS inregs, outregs; 74 union REGS inregs, outregs;
62 75 static int only_once = 1;
63 inregs.h.ah = 0xc0; 76
64 int86 (0x15, &inregs, &outregs); 77 if (only_once) {
65 extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0); 78 inregs.h.ah = 0xc0;
66 79 int86 (0x15, &inregs, &outregs);
80 extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0);
81 }
82
67 break_stat = getcbrk (); 83 break_stat = getcbrk ();
68 setcbrk (0); 84 setcbrk (0);
69 install_ctrl_break_check (); 85 install_ctrl_break_check ();
70 have_mouse = mouse_init1 ();
71 86
72 inregs.x.ax = 0x4400; /* Get IOCTL status. */ 87 if (only_once)
73 inregs.x.bx = 0x00; /* 0 = stdin. */ 88 have_mouse = mouse_init1 ();
89
90 inregs.x.ax = 0x4400; /* Get IOCTL status. */
91 inregs.x.bx = 0x00; /* 0 = stdin. */
74 intdos (&inregs, &outregs); 92 intdos (&inregs, &outregs);
75 stdin_stat = outregs.h.dl; 93 stdin_stat = outregs.h.dl;
76 94
77 inregs.x.dx = (outregs.x.dx | 0x0020) & 0x0027; /* raw mode */ 95 only_once = 0;
78 inregs.h.al = 0x01; 96
97 inregs.x.dx = stdin_stat | 0x0020; /* raw mode */
98 inregs.x.ax = 0x4401; /* Set IOCTL status */
79 intdos (&inregs, &outregs); 99 intdos (&inregs, &outregs);
80 return !outregs.x.cflag; 100 return !outregs.x.cflag;
81} 101}
@@ -87,7 +107,7 @@ dos_ttcooked ()
87 union REGS inregs, outregs; 107 union REGS inregs, outregs;
88 108
89 setcbrk (break_stat); 109 setcbrk (break_stat);
90 if (have_mouse) mouse_off (); 110 mouse_off ();
91 111
92 inregs.x.ax = 0x4401; /* Set IOCTL status. */ 112 inregs.x.ax = 0x4401; /* Set IOCTL status. */
93 inregs.x.bx = 0x00; /* 0 = stdin. */ 113 inregs.x.bx = 0x00; /* 0 = stdin. */
@@ -96,6 +116,24 @@ dos_ttcooked ()
96 return !outregs.x.cflag; 116 return !outregs.x.cflag;
97} 117}
98 118
119/* generate a reliable event timestamp, KFS 1995-07-06 */
120
121static unsigned long
122event_timestamp ()
123{
124 struct time t;
125 unsigned long s;
126
127 gettime (&t);
128 s = t.ti_min;
129 s *= 60;
130 s += t.ti_sec;
131 s *= 1000;
132 s += t.ti_hund * 10;
133
134 return s;
135}
136
99static unsigned short 137static unsigned short
100ibmpc_translate_map[] = 138ibmpc_translate_map[] =
101{ 139{
@@ -254,10 +292,9 @@ static int
254dos_rawgetc () 292dos_rawgetc ()
255{ 293{
256 struct input_event event; 294 struct input_event event;
257 struct timeval tv;
258 union REGS regs; 295 union REGS regs;
259 int ctrl_p, alt_p, shift_p; 296 int ctrl_p, alt_p, shift_p;
260 297
261 /* Calculate modifier bits */ 298 /* Calculate modifier bits */
262 regs.h.ah = extended_kbd ? 0x12 : 0x02; 299 regs.h.ah = extended_kbd ? 0x12 : 0x02;
263 int86 (0x16, &regs, &regs); 300 int86 (0x16, &regs, &regs);
@@ -288,14 +325,14 @@ dos_rawgetc ()
288 sc = (c == '0') ? 0xb : (c - '0' + 1), c = 0; 325 sc = (c == '0') ? 0xb : (c - '0' + 1), c = 0;
289 else if (sc == 0x53 && c != 0xe0) 326 else if (sc == 0x53 && c != 0xe0)
290 { 327 {
291 code = 0xffae; /* Keypad decimal point/comma. */ 328 code = 0xffae; /* Keypad decimal point/comma. */
292 goto nonascii; 329 goto nonascii;
293 } 330 }
294 else if (sc == 0xe0) 331 else if (sc == 0xe0)
295 { 332 {
296 switch (c) 333 switch (c)
297 { 334 {
298 case 10: /* Ctrl Enter */ 335 case 10: /* Ctrl Enter */
299 case 13: 336 case 13:
300 sc = 0x1c; 337 sc = 0x1c;
301 break; 338 break;
@@ -312,62 +349,61 @@ dos_rawgetc ()
312 || c == ' ' 349 || c == ' '
313 || alt_p 350 || alt_p
314 || (ctrl_p && shift_p) 351 || (ctrl_p && shift_p)
315 || (c == 0xe0 && sc != 0) /* Pseudo-key */ 352 || (c == 0xe0 && sc != 0) /* Pseudo-key */
316 || sc == 0x37 /* Grey * */ 353 || sc == 0x37 /* Grey * */
317 || sc == 0x4a /* Grey - */ 354 || sc == 0x4a /* Grey - */
318 || sc == 0x4e /* Grey + */ 355 || sc == 0x4e /* Grey + */
319 || sc == 0x0e) /* Back space *key*, not Ctrl-h */ 356 || sc == 0x0e) /* Back space *key*, not Ctrl-h */
320 { 357 {
321 if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short))) 358 if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short)))
322 code = 0; 359 code = 0;
323 else 360 else
324 code = ibmpc_translate_map[sc]; 361 code = ibmpc_translate_map[sc];
325 if (code != 0) 362 if (code != 0)
326 { 363 {
327 if (code >= 0x100) 364 if (code >= 0x100)
328 { 365 {
329 nonascii: 366 nonascii:
330 event.kind = non_ascii_keystroke; 367 event.kind = non_ascii_keystroke;
331 event.code = (code & 0xff) + 0xff00; 368 event.code = (code & 0xff) + 0xff00;
332 } 369 }
333 else 370 else
334 { 371 {
335 /* Don't return S- if we don't have to. `shifted' is 372 /* Don't return S- if we don't have to. `shifted' is
336 supposed to be the shifted versions of the characters 373 supposed to be the shifted versions of the characters
337 in `unshifted'. Unfortunately, this is only true for 374 in `unshifted'. Unfortunately, this is only true for
338 US keyboard layout. If anyone knows how to do this 375 US keyboard layout. If anyone knows how to do this
339 right, please tell us. */ 376 right, please tell us. */
340 static char *unshifted 377 static char *unshifted
341 = "abcdefghijklmnopqrstuvwxyz,./=;[\\]'-`0123456789"; 378 = "abcdefghijklmnopqrstuvwxyz,./=;[\\]'-`0123456789";
342 static char *shifted 379 static char *shifted
343 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ<>?+:{|}\"_~)!@#$%^&*("; 380 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ<>?+:{|}\"_~)!@#$%^&*(";
344 char *pos; 381 char *pos;
345 382
346 if (shift_p && (pos = strchr (unshifted, code))) 383 if (shift_p && (pos = strchr (unshifted, code)))
347 { 384 {
348 c = shifted[pos - unshifted]; 385 c = shifted[pos - unshifted];
349 shift_p = 0; 386 shift_p = 0;
350 } 387 }
351 else 388 else
352 if (c == 0) c = code; 389 if (c == 0) c = code;
353 event.kind = ascii_keystroke; 390 event.kind = ascii_keystroke;
354 event.code = c; 391 event.code = c;
355 } 392 }
356 event.modifiers 393 event.modifiers
357 = (shift_p ? shift_modifier : 0) 394 = (shift_p ? shift_modifier : 0)
358 + (ctrl_p ? ctrl_modifier : 0) 395 + (ctrl_p ? ctrl_modifier : 0)
359 + (alt_p ? meta_modifier : 0); 396 + (alt_p ? meta_modifier : 0);
360 /* EMACS == Enter Meta Alt Control Shift */ 397 /* EMACS == Enter Meta Alt Control Shift */
361 XSETFRAME (event.frame_or_window, selected_frame); 398 XSETFRAME (event.frame_or_window, selected_frame);
362 gettimeofday (&tv, NULL); 399 event.timestamp = event_timestamp ();
363 event.timestamp = tv.tv_usec; 400 kbd_buffer_store_event (&event);
364 kbd_buffer_store_event (&event); 401 }
365 } 402 } else
366 } else 403 return c;
367 return c;
368 } 404 }
369 405
370 if (have_mouse) 406 if (have_mouse > 0)
371 { 407 {
372 int but, press, x, y, ok; 408 int but, press, x, y, ok;
373 409
@@ -393,8 +429,7 @@ dos_rawgetc ()
393 event.x = x; 429 event.x = x;
394 event.y = y; 430 event.y = y;
395 XSETFRAME (event.frame_or_window, selected_frame); 431 XSETFRAME (event.frame_or_window, selected_frame);
396 gettimeofday (&tv, NULL); 432 event.timestamp = event_timestamp ();
397 event.timestamp = tv.tv_usec;
398 kbd_buffer_store_event (&event); 433 kbd_buffer_store_event (&event);
399 } 434 }
400 } 435 }
@@ -523,6 +558,7 @@ run_msdos_command (argv, dir, tempin, tempout)
523 char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ 558 char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
524 int msshell, result = -1; 559 int msshell, result = -1;
525 int in, out, inbak, outbak, errbak; 560 int in, out, inbak, outbak, errbak;
561 int x, y;
526 Lisp_Object cmd; 562 Lisp_Object cmd;
527 563
528 /* Get current directory as MSDOS cwd is not per-process. */ 564 /* Get current directory as MSDOS cwd is not per-process. */
@@ -579,16 +615,33 @@ run_msdos_command (argv, dir, tempin, tempout)
579 errbak = dup (2); 615 errbak = dup (2);
580 if (inbak < 0 || outbak < 0 || errbak < 0) 616 if (inbak < 0 || outbak < 0 || errbak < 0)
581 goto done; /* Allocation might fail due to lack of descriptors. */ 617 goto done; /* Allocation might fail due to lack of descriptors. */
618
619 if (have_mouse > 0)
620 {
621 mouse_get_xy (&x, &y);
622 mouse_off ();
623 }
624 dos_ttcooked(); /* do it here while 0 = stdin */
625
582 dup2 (tempin, 0); 626 dup2 (tempin, 0);
583 dup2 (tempout, 1); 627 dup2 (tempout, 1);
584 dup2 (tempout, 2); 628 dup2 (tempout, 2);
585 dos_ttcooked (); 629
586 result = spawnve (P_WAIT, argv[0], argv, envv); 630 result = spawnve (P_WAIT, argv[0], argv, envv);
587 dos_ttraw (); 631
588 dup2 (inbak, 0); 632 dup2 (inbak, 0);
589 dup2 (outbak, 1); 633 dup2 (outbak, 1);
590 dup2 (errbak, 2); 634 dup2 (errbak, 2);
591 635 close (inbak);
636 close (outbak);
637 close (errbak);
638
639 dos_ttraw();
640 if (have_mouse > 0) {
641 mouse_init ();
642 mouse_moveto (x, y);
643 }
644
592 done: 645 done:
593 chdir (oldwd); 646 chdir (oldwd);
594 if (msshell) 647 if (msshell)
@@ -629,40 +682,86 @@ sys_chdir (path)
629 const char* path; 682 const char* path;
630{ 683{
631 int len = strlen (path); 684 int len = strlen (path);
632 char *tmp = (char *) alloca (len + 1); 685 char *tmp = (char *)path;
633 /* Gotta do this extern here due to the corresponding #define: */ 686 /* Gotta do this extern here due to the corresponding #define: */
634 extern int chdir (); 687 extern int chdir ();
635 688
636 if (*path && path[1] == ':' && (getdisk () != tolower (path[0]) - 'a')) 689 if (*tmp && tmp[1] == ':')
637 setdisk (tolower (path[0]) - 'a'); 690 {
638 691 if (getdisk () != tolower (tmp[0]) - 'a')
639 strcpy (tmp, path); 692 setdisk (tolower (tmp[0]) - 'a');
640 if (strcmp (path, "/") && strcmp (path + 1, ":/") && (path[len - 1] == '/')) 693 tmp += 2; /* strip drive: KFS 1995-07-06 */
641 tmp[len - 1] = 0; 694 len -= 2;
695 }
696
697 if (len > 1 && (tmp[len - 1] == '/'))
698 {
699 char *tmp1 = (char *) alloca (len + 1);
700 strcpy (tmp1, tmp);
701 tmp1[len - 1] = 0;
702 tmp = tmp1;
703 }
642 return chdir (tmp); 704 return chdir (tmp);
643} 705}
644 706
645/* Sleep SECS. If KBDOK also return immediately if a key is pressed. */ 707#ifndef HAVE_SELECT
646void 708#include "sysselect.h"
647sleep_or_kbd_hit (secs, kbdok) 709
648 int secs, kbdok; 710/* Only event queue is checked. */
711int
712sys_select (nfds, rfds, wfds, efds, timeout)
713 int nfds;
714 SELECT_TYPE *rfds, *wfds, *efds;
715 EMACS_TIME *timeout;
649{ 716{
650 long clnow, clthen; 717 SELECT_TYPE orfds;
651 struct timeval t; 718 long timeoutval, clnow, cllast;
719 struct time t;
652 720
653 gettimeofday (&t, NULL); 721 FD_ZERO (&orfds);
654 clnow = t.tv_sec * 100 + t.tv_usec / 10000; 722 if (rfds)
655 clthen = clnow + (100 * secs); 723 {
724 orfds = *rfds;
725 FD_ZERO (rfds);
726 }
727 if (wfds)
728 FD_ZERO (wfds);
729 if (efds)
730 FD_ZERO (efds);
656 731
657 do 732 if (nfds != 1 || !FD_ISSET (0, &orfds))
733 abort ();
734
735 /* If we are looking only for the terminal, with no timeout,
736 just read it and wait -- that's more efficient. */
737 if (!timeout)
658 { 738 {
659 gettimeofday (&t, NULL); 739 while (! detect_input_pending ());
660 clnow = t.tv_sec * 100 + t.tv_usec / 10000;
661 if (kbdok && detect_input_pending ())
662 return;
663 } 740 }
664 while (clnow < clthen); 741 else
742 {
743 timeoutval = EMACS_SECS (*timeout) * 100 + EMACS_USECS (*timeout) / 10000;
744 gettime (&t);
745 cllast = t.ti_sec * 100 + t.ti_hund;
746
747 while (!detect_input_pending ())
748 {
749 gettime (&t);
750 clnow = t.ti_sec * 100 + t.ti_hund;
751 if (clnow < cllast) /* time wrap */
752 timeoutval -= clnow + 6000 - cllast;
753 else
754 timeoutval -= clnow - cllast;
755 if (timeoutval <= 0) /* Stop on timer being cleared */
756 return 0;
757 cllast = clnow;
758 }
759 }
760
761 FD_SET (0, rfds);
762 return 1;
665} 763}
764#endif
666 765
667/* The Emacs root directory as determined by init_environment. */ 766/* The Emacs root directory as determined by init_environment. */
668static char emacsroot[MAXPATHLEN]; 767static char emacsroot[MAXPATHLEN];
@@ -836,6 +935,13 @@ output_string (x, y, s, c, a)
836 unsigned char a; 935 unsigned char a;
837{ 936{
838 char *t = (char *)ScreenPrimary + 2 * (x + ScreenCols () * y); 937 char *t = (char *)ScreenPrimary + 2 * (x + ScreenCols () * y);
938#ifdef DO_TERMSCRIPT
939 if (termscript)
940 {
941 fprintf (termscript, "<%d@%dx%d>", c, x, y);
942 fwrite (s, sizeof (unsigned char), c, termscript);
943 }
944#endif
839 asm volatile 945 asm volatile
840 (" movl %1,%%eax 946 (" movl %1,%%eax
841 call dosmemsetup 947 call dosmemsetup
@@ -850,9 +956,9 @@ output_string1:
850 incl %%esi 956 incl %%esi
851 decl %%ecx 957 decl %%ecx
852 jne output_string1" 958 jne output_string1"
853 : /* no output */ 959 : /* no output */
854 : "m" (a), "g" (t), "g" (c), "g" (s) 960 : "m" (a), "g" (t), "g" (c), "g" (s)
855 : "%eax", "%ecx", /* "%gs",*/ "%esi", "%edi"); 961 : "%eax", "%ecx", /* "%gs",*/ "%esi", "%edi");
856} 962}
857 963
858static int internal_terminal = 0; 964static int internal_terminal = 0;
@@ -860,108 +966,189 @@ static int highlight;
860 966
861#undef fflush 967#undef fflush
862 968
969static int /* number of characters used by escape; -1 if incomplete */
970flush_escape (resume, cp, count, xp, yp)
971 int resume;
972 unsigned char *cp;
973 int count;
974 int *xp;
975 int *yp;
976{
977 static char spaces[] = " ";
978 static unsigned char esc_cmd[8];
979 static int esc_count = 0;
980 int esc_needed;
981 int i, j, used = 0;
982
983 if (!resume)
984 {
985 esc_cmd[0] = '\e';
986 esc_count = 1;
987 used++;
988 }
989
990 while (esc_count < 2)
991 {
992 if (used == count)
993 return -1;
994 esc_cmd[esc_count++] = *cp++;
995 used++;
996 }
997
998 switch (esc_cmd[1])
999 {
1000 case '@':
1001 esc_needed = 4;
1002 break;
1003 case 'A':
1004 case 'B':
1005 case 'X':
1006 esc_needed = 3;
1007 break;
1008 default:
1009 esc_needed = 2;
1010 break;
1011 }
1012
1013 while (esc_count < esc_needed)
1014 {
1015 if (used == count)
1016 return -1;
1017 esc_cmd[esc_count++] = *cp++;
1018 used++;
1019 }
1020
1021 switch (esc_cmd[1])
1022 {
1023 case '@':
1024 *yp = esc_cmd[2];
1025 *xp = esc_cmd[3];
1026 break;
1027 case 'A':
1028 ScreenAttrib = esc_cmd[2];
1029 break;
1030 case 'B':
1031 do_visible_bell (esc_cmd[2]);
1032 break;
1033 case 'C':
1034 ScreenClear ();
1035 *xp = *yp = 0;
1036 break;
1037 case 'E':
1038 i = ScreenCols () - *xp;
1039 j = *xp;
1040 while (i >= sizeof spaces)
1041 {
1042 output_string (j, *yp, spaces, sizeof spaces, ScreenAttrib);
1043 j += sizeof spaces;
1044 i -= sizeof spaces;
1045 }
1046 if (i > 0)
1047 output_string (j, *yp, spaces, i, ScreenAttrib);
1048 break;
1049 case 'R':
1050 ++*xp;
1051 break;
1052 case 'U':
1053 --*yp;
1054 break;
1055 case 'X':
1056 ScreenAttrib ^= esc_cmd[2];
1057 break;
1058 case '\e':
1059 output_string (*xp, *yp, &esc_cmd[1], 1, ScreenAttrib);
1060 ++*xp;
1061 break;
1062 }
1063
1064 esc_count = 0;
1065 return used;
1066}
1067
863int 1068int
864internal_flush (f) 1069internal_flush (f)
865 FILE *f; 1070 FILE *f;
866{ 1071{
867 static char spaces[] = " ";
868 static int x; 1072 static int x;
869 static int y; 1073 static int y;
1074 static int resume_esc = 0;
870 unsigned char *cp, *cp0; 1075 unsigned char *cp, *cp0;
871 int count, i, j; 1076 int count, i;
872 1077
873 if (internal_terminal && f == stdout) 1078 if (!internal_terminal || f != stdout)
874 { 1079 {
875 if (have_mouse) mouse_off (); 1080 /* This is a call to the original fflush. */
876 cp = stdout->_base; 1081 fflush (f);
877 count = stdout->_ptr - stdout->_base; 1082 return;
878 while (count > 0) 1083 }
1084
1085 mouse_off ();
1086 cp = stdout->_base;
1087 count = stdout->_ptr - stdout->_base;
1088
1089#ifdef DO_TERMSCRIPT
1090 if (termscript)
1091 fprintf (termscript, "\n<FLUSH%s %d>\n", resume_esc ? " RESUME" : "", count);
1092#endif
1093
1094 if (resume_esc)
1095 {
1096 i = flush_escape (1, cp, count, &x, &y);
1097 if (i < 0)
1098 count = 0;
1099 else
879 { 1100 {
880 switch (*cp++) 1101 resume_esc = 0;
1102 count -= i;
1103 cp += i;
1104 }
1105 }
1106
1107 while (count > 0)
1108 {
1109 switch (*cp++)
1110 {
1111 case 27:
1112 i = flush_escape (0, cp, count, &x, &y);
1113 if (i < 0)
881 { 1114 {
882 case 27: 1115 resume_esc = 1;
883 switch (*cp++) 1116 count = 0;
884 {
885 case '@':
886 y = *cp++;
887 x = *cp++;
888 count -= 4;
889 break;
890 case 'A':
891 ScreenAttrib = *cp++;
892 count -= 3;
893 break;
894 case 'B':
895 do_visible_bell (*cp++);
896 count -= 3;
897 break;
898 case 'C':
899 ScreenClear ();
900 x = y = 0;
901 count -= 2;
902 break;
903 case 'E':
904 i = ScreenCols () - x;
905 j = x;
906 while (i >= sizeof spaces)
907 {
908 output_string (j, y, spaces, sizeof spaces,
909 ScreenAttrib);
910 j += sizeof spaces;
911 i -= sizeof spaces;
912 }
913 if (i > 0)
914 output_string (j, y, spaces, i, ScreenAttrib);
915 count -= 2;
916 break;
917 case 'R':
918 x++;
919 count -= 2;
920 break;
921 case 'U':
922 y--;
923 count -= 2;
924 break;
925 case 'X':
926 ScreenAttrib ^= *cp++;
927 count -= 3;
928 break;
929 default:
930 count -= 2;
931 }
932 break;
933 case 7:
934 write (1, "\007", 1);
935 count--;
936 break;
937 case 8:
938 x--;
939 count--;
940 break;
941 case 13:
942 x = 0;
943 count--;
944 break;
945 case 10:
946 y++;
947 count--;
948 break;
949 default:
950 cp0 = cp - 1;
951 count--;
952 while (count > 0 && *cp >= ' ')
953 cp++, count--;
954 output_string (x, y, cp0, cp - cp0, ScreenAttrib);
955 x += (cp - cp0);
956 } 1117 }
1118 else
1119 {
1120 count -= i;
1121 cp += i - 1;
1122 }
1123 break;
1124 case 7:
1125 write (1, "\007", 1);
1126 count--;
1127 break;
1128 case 8:
1129 x--;
1130 count--;
1131 break;
1132 case 13:
1133 x = 0;
1134 count--;
1135 break;
1136 case 10:
1137 y++;
1138 count--;
1139 break;
1140 default:
1141 cp0 = cp - 1;
1142 count--;
1143 while (count > 0 && *cp >= ' ')
1144 cp++, count--;
1145 output_string (x, y, cp0, cp - cp0, ScreenAttrib);
1146 x += (cp - cp0);
957 } 1147 }
958 fpurge (stdout);
959 ScreenSetCursor (y, x);
960 if (have_mouse) mouse_on ();
961 } 1148 }
962 else 1149 fpurge (stdout);
963 /* This is a call to the original fflush. */ 1150 ScreenSetCursor (y, x);
964 fflush (f); 1151 mouse_on ();
965} 1152}
966 1153
967#ifndef HAVE_X_WINDOWS 1154#ifndef HAVE_X_WINDOWS
@@ -978,11 +1165,11 @@ IT_ring_bell ()
978 { 1165 {
979 /* This creates an xor-mask that will swap the default fore- and 1166 /* This creates an xor-mask that will swap the default fore- and
980 background colors. */ 1167 background colors. */
981 if (have_mouse) mouse_off (); 1168 mouse_off ();
982 do_visible_bell (((the_only_x_display.foreground_pixel 1169 do_visible_bell (((the_only_x_display.foreground_pixel
983 ^ the_only_x_display.background_pixel) 1170 ^ the_only_x_display.background_pixel)
984 * 0x11) & 0x7f); 1171 * 0x11) & 0x7f);
985 if (have_mouse) mouse_on (); 1172 mouse_on ();
986 } 1173 }
987 else 1174 else
988 /* Write it directly to ms-dos -- don't let it go through our terminal 1175 /* Write it directly to ms-dos -- don't let it go through our terminal
@@ -1002,6 +1189,10 @@ IT_set_face (int face)
1002 fp = FRAME_DEFAULT_FACE (foo); 1189 fp = FRAME_DEFAULT_FACE (foo);
1003 else 1190 else
1004 fp = intern_face (selected_frame, FRAME_COMPUTED_FACES (foo)[face]); 1191 fp = intern_face (selected_frame, FRAME_COMPUTED_FACES (foo)[face]);
1192#ifdef DO_TERMSCRIPT
1193 if (termscript)
1194 fprintf (termscript, "<FACE:%d:%d>", FACE_FOREGROUND (fp), FACE_BACKGROUND (fp));
1195#endif
1005 putchar ('\e'); 1196 putchar ('\e');
1006 putchar ('A'); 1197 putchar ('A');
1007 putchar ((FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp)); 1198 putchar ((FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp));
@@ -1012,13 +1203,20 @@ IT_write_glyphs (GLYPH *str, int len)
1012{ 1203{
1013 int face = -1; 1204 int face = -1;
1014 int newface; 1205 int newface;
1015 1206 int ch;
1207
1016 while (len > 0) 1208 while (len > 0)
1017 { 1209 {
1018 newface = FAST_GLYPH_FACE (*str); 1210 newface = FAST_GLYPH_FACE (*str);
1019 if (newface != face) 1211 if (newface != face)
1020 IT_set_face ((face = newface)); 1212 IT_set_face ((face = newface));
1021 putchar (FAST_GLYPH_CHAR (*str)); 1213 ch = FAST_GLYPH_CHAR (*str);
1214#ifdef DO_TERMSCRIPT
1215 if (termscript)
1216 fputc (ch, termscript);
1217#endif
1218 if (ch == '\e') putchar (ch); /* allow esc to be printed */
1219 putchar (ch);
1022 str++, len--; 1220 str++, len--;
1023 } 1221 }
1024} 1222}
@@ -1026,6 +1224,11 @@ IT_write_glyphs (GLYPH *str, int len)
1026static 1224static
1027IT_clear_end_of_line (first_unused) 1225IT_clear_end_of_line (first_unused)
1028{ 1226{
1227 IT_set_face (0);
1228#ifdef DO_TERMSCRIPT
1229 if (termscript)
1230 fprintf (termscript, "<CLR:EOL>");
1231#endif
1029 putchar ('\e'); 1232 putchar ('\e');
1030 putchar ('E'); 1233 putchar ('E');
1031} 1234}
@@ -1033,6 +1236,10 @@ IT_clear_end_of_line (first_unused)
1033static 1236static
1034IT_cursor_to (int y, int x) 1237IT_cursor_to (int y, int x)
1035{ 1238{
1239#ifdef DO_TERMSCRIPT
1240 if (termscript)
1241 fprintf (termscript, "\n<XY=%dx%d>", x, y);
1242#endif
1036 putchar ('\e'); 1243 putchar ('\e');
1037 putchar ('@'); 1244 putchar ('@');
1038 putchar (y); 1245 putchar (y);
@@ -1157,7 +1364,8 @@ void
1157internal_terminal_init () 1364internal_terminal_init ()
1158{ 1365{
1159 char *term = getenv ("TERM"); 1366 char *term = getenv ("TERM");
1160 1367 char *colors;
1368
1161#ifdef HAVE_X_WINDOWS 1369#ifdef HAVE_X_WINDOWS
1162 if (!inhibit_window_system) 1370 if (!inhibit_window_system)
1163 return; 1371 return;
@@ -1175,6 +1383,12 @@ internal_terminal_init ()
1175 bzero (&the_only_x_display, sizeof the_only_x_display); 1383 bzero (&the_only_x_display, sizeof the_only_x_display);
1176 the_only_x_display.background_pixel = 7; /* White */ 1384 the_only_x_display.background_pixel = 7; /* White */
1177 the_only_x_display.foreground_pixel = 0; /* Black */ 1385 the_only_x_display.foreground_pixel = 0; /* Black */
1386 colors = getenv ("EMACSCOLORS");
1387 if (colors && strlen (colors) >=2)
1388 {
1389 the_only_x_display.foreground_pixel = colors[0] & 0x07;
1390 the_only_x_display.background_pixel = colors[1] & 0x07;
1391 }
1178 the_only_x_display.line_height = 1; 1392 the_only_x_display.line_height = 1;
1179 the_only_frame.display.x = &the_only_x_display; 1393 the_only_frame.display.x = &the_only_x_display;
1180 the_only_frame.output_method = output_msdos_raw; 1394 the_only_frame.output_method = output_msdos_raw;
@@ -1312,8 +1526,11 @@ mouse_on ()
1312{ 1526{
1313 union REGS regs; 1527 union REGS regs;
1314 1528
1315 regs.x.ax = 0x0001; 1529 if (have_mouse > 0)
1316 int86 (0x33, &regs, &regs); 1530 {
1531 regs.x.ax = 0x0001;
1532 int86 (0x33, &regs, &regs);
1533 }
1317} 1534}
1318 1535
1319void 1536void
@@ -1321,8 +1538,11 @@ mouse_off ()
1321{ 1538{
1322 union REGS regs; 1539 union REGS regs;
1323 1540
1324 regs.x.ax = 0x0002; 1541 if (have_mouse > 0)
1325 int86 (0x33, &regs, &regs); 1542 {
1543 regs.x.ax = 0x0002;
1544 int86 (0x33, &regs, &regs);
1545 }
1326} 1546}
1327 1547
1328void 1548void
@@ -1364,6 +1584,10 @@ mouse_released (b, xp, yp)
1364 regs.x.ax = 0x0006; 1584 regs.x.ax = 0x0006;
1365 regs.x.bx = mouse_button_translate[b]; 1585 regs.x.bx = mouse_button_translate[b];
1366 int86 (0x33, &regs, &regs); 1586 int86 (0x33, &regs, &regs);
1587#if 0
1588 if (regs.x.ax & (1 << mouse_button_translate[b]))
1589 regs.x.bx = 0; /* if mouse is still pressed, ignore release */
1590#endif
1367 if (regs.x.bx) 1591 if (regs.x.bx)
1368 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; 1592 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
1369 return (regs.x.bx != 0); 1593 return (regs.x.bx != 0);
@@ -1390,18 +1614,16 @@ mouse_get_pos (f, insist, bar_window, part, x, y, time)
1390{ 1614{
1391 int ix, iy; 1615 int ix, iy;
1392 union REGS regs; 1616 union REGS regs;
1393 struct timeval tv;
1394 1617
1395 regs.x.ax = 0x0003; 1618 regs.x.ax = 0x0003;
1396 int86 (0x33, &regs, &regs); 1619 int86 (0x33, &regs, &regs);
1397 *f = selected_frame; 1620 *f = selected_frame;
1398 *bar_window = Qnil; 1621 *bar_window = Qnil;
1399 gettimeofday (&tv, NULL);
1400 mouse_get_xy (&ix, &iy); 1622 mouse_get_xy (&ix, &iy);
1401 selected_frame->mouse_moved = 0; 1623 selected_frame->mouse_moved = 0;
1402 *x = make_number (ix); 1624 *x = make_number (ix);
1403 *y = make_number (iy); 1625 *y = make_number (iy);
1404 *time = tv.tv_usec; 1626 *time = event_timestamp ();
1405} 1627}
1406 1628
1407void 1629void
@@ -1458,7 +1680,7 @@ mouse_init1 ()
1458 } 1680 }
1459 mouse_position_hook = &mouse_get_pos; 1681 mouse_position_hook = &mouse_get_pos;
1460 mouse_init (); 1682 mouse_init ();
1461 } 1683 }
1462 return present; 1684 return present;
1463} 1685}
1464 1686
@@ -1510,6 +1732,7 @@ IT_menu_create ()
1510 1732
1511/* Allocate some (more) memory for MENU ensuring that there is room for one 1733/* Allocate some (more) memory for MENU ensuring that there is room for one
1512 for item. */ 1734 for item. */
1735
1513static void 1736static void
1514IT_menu_make_room (XMenu *menu) 1737IT_menu_make_room (XMenu *menu)
1515{ 1738{
@@ -1533,6 +1756,7 @@ IT_menu_make_room (XMenu *menu)
1533} 1756}
1534 1757
1535/* Search the given menu structure for a given pane number. */ 1758/* Search the given menu structure for a given pane number. */
1759
1536static XMenu * 1760static XMenu *
1537IT_menu_search_pane (XMenu *menu, int pane) 1761IT_menu_search_pane (XMenu *menu, int pane)
1538{ 1762{
@@ -1541,15 +1765,17 @@ IT_menu_search_pane (XMenu *menu, int pane)
1541 1765
1542 for (i = 0; i < menu->count; i++) 1766 for (i = 0; i < menu->count; i++)
1543 if (menu->submenu[i]) 1767 if (menu->submenu[i])
1544 if (pane == menu->panenumber[i]) 1768 {
1545 return menu->submenu[i]; 1769 if (pane == menu->panenumber[i])
1546 else 1770 return menu->submenu[i];
1547 if ((try = IT_menu_search_pane (menu->submenu[i], pane))) 1771 else if ((try = IT_menu_search_pane (menu->submenu[i], pane)))
1548 return try; 1772 return try;
1773 }
1549 return (XMenu *) 0; 1774 return (XMenu *) 0;
1550} 1775}
1551 1776
1552/* Determine how much screen space a given menu needs. */ 1777/* Determine how much screen space a given menu needs. */
1778
1553static void 1779static void
1554IT_menu_calc_size (XMenu *menu, int *width, int *height) 1780IT_menu_calc_size (XMenu *menu, int *width, int *height)
1555{ 1781{
@@ -1571,6 +1797,7 @@ IT_menu_calc_size (XMenu *menu, int *width, int *height)
1571} 1797}
1572 1798
1573/* Display MENU at (X,Y) using FACES. */ 1799/* Display MENU at (X,Y) using FACES. */
1800
1574static void 1801static void
1575IT_menu_display (XMenu *menu, int y, int x, int *faces) 1802IT_menu_display (XMenu *menu, int y, int x, int *faces)
1576{ 1803{
@@ -1611,6 +1838,7 @@ IT_menu_display (XMenu *menu, int y, int x, int *faces)
1611} 1838}
1612 1839
1613/* Create a brand new menu structure. */ 1840/* Create a brand new menu structure. */
1841
1614XMenu * 1842XMenu *
1615XMenuCreate (Display *foo1, Window foo2, char *foo3) 1843XMenuCreate (Display *foo1, Window foo2, char *foo3)
1616{ 1844{
@@ -1620,6 +1848,7 @@ XMenuCreate (Display *foo1, Window foo2, char *foo3)
1620/* Create a new pane and place it on the outer-most level. It is not 1848/* Create a new pane and place it on the outer-most level. It is not
1621 clear that it should be placed out there, but I don't know what else 1849 clear that it should be placed out there, but I don't know what else
1622 to do. */ 1850 to do. */
1851
1623int 1852int
1624XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable) 1853XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable)
1625{ 1854{
@@ -1633,11 +1862,13 @@ XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable)
1633 menu->text[menu->count] = txt; 1862 menu->text[menu->count] = txt;
1634 menu->panenumber[menu->count] = ++menu->panecount; 1863 menu->panenumber[menu->count] = ++menu->panecount;
1635 menu->count++; 1864 menu->count++;
1636 if ((len = strlen (txt)) > menu->width) menu->width = len; 1865 if ((len = strlen (txt)) > menu->width)
1866 menu->width = len;
1637 return menu->panecount; 1867 return menu->panecount;
1638} 1868}
1639 1869
1640/* Create a new item in a menu pane. */ 1870/* Create a new item in a menu pane. */
1871
1641int 1872int
1642XMenuAddSelection (Display *bar, XMenu *menu, int pane, 1873XMenuAddSelection (Display *bar, XMenu *menu, int pane,
1643 int foo, char *txt, int enable) 1874 int foo, char *txt, int enable)
@@ -1652,11 +1883,13 @@ XMenuAddSelection (Display *bar, XMenu *menu, int pane,
1652 menu->text[menu->count] = txt; 1883 menu->text[menu->count] = txt;
1653 menu->panenumber[menu->count] = enable; 1884 menu->panenumber[menu->count] = enable;
1654 menu->count++; 1885 menu->count++;
1655 if ((len = strlen (txt)) > menu->width) menu->width = len; 1886 if ((len = strlen (txt)) > menu->width)
1887 menu->width = len;
1656 return XM_SUCCESS; 1888 return XM_SUCCESS;
1657} 1889}
1658 1890
1659/* Decide where the menu would be placed if requested at (X,Y). */ 1891/* Decide where the menu would be placed if requested at (X,Y). */
1892
1660void 1893void
1661XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y, 1894XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y,
1662 int *ulx, int *uly, int *width, int *height) 1895 int *ulx, int *uly, int *width, int *height)
@@ -1671,21 +1904,22 @@ XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y,
1671 *width += 2; 1904 *width += 2;
1672} 1905}
1673 1906
1674typedef struct 1907struct IT_menu_state
1675{ 1908{
1676 void *screen_behind; 1909 void *screen_behind;
1677 XMenu *menu; 1910 XMenu *menu;
1678 int pane; 1911 int pane;
1679 int x, y; 1912 int x, y;
1680} IT_menu_state; 1913};
1681 1914
1682 1915
1683/* Display menu, wait for user's response, and return that response. */ 1916/* Display menu, wait for user's response, and return that response. */
1917
1684int 1918int
1685XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, 1919XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
1686 int x0, int y0, unsigned ButtonMask, char **txt) 1920 int x0, int y0, unsigned ButtonMask, char **txt)
1687{ 1921{
1688 IT_menu_state *state; 1922 struct IT_menu_state *state;
1689 int statecount; 1923 int statecount;
1690 int x, y, i, b; 1924 int x, y, i, b;
1691 int screensize; 1925 int screensize;
@@ -1693,10 +1927,10 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
1693 int leave, result, onepane; 1927 int leave, result, onepane;
1694 1928
1695 /* Just in case we got here without a mouse present... */ 1929 /* Just in case we got here without a mouse present... */
1696 if (!have_mouse) 1930 if (have_mouse <= 0)
1697 return XM_IA_SELECT; 1931 return XM_IA_SELECT;
1698 1932
1699 state = alloca (menu->panecount * sizeof (IT_menu_state)); 1933 state = alloca (menu->panecount * sizeof (struct IT_menu_state));
1700 screensize = ScreenRows () * ScreenCols () * 2; 1934 screensize = ScreenRows () * ScreenCols () * 2;
1701 faces[0] 1935 faces[0]
1702 = compute_glyph_face (&the_only_frame, 1936 = compute_glyph_face (&the_only_frame,
@@ -1810,6 +2044,7 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
1810} 2044}
1811 2045
1812/* Dispose of a menu. */ 2046/* Dispose of a menu. */
2047
1813void 2048void
1814XMenuDestroy (Display *foo, XMenu *menu) 2049XMenuDestroy (Display *foo, XMenu *menu)
1815{ 2050{
@@ -1826,14 +2061,16 @@ XMenuDestroy (Display *foo, XMenu *menu)
1826 xfree (menu); 2061 xfree (menu);
1827} 2062}
1828 2063
1829int x_pixel_width (struct frame *f) 2064int
2065x_pixel_width (struct frame *f)
1830{ 2066{
1831 return FRAME_WIDTH(f); 2067 return FRAME_WIDTH (f);
1832} 2068}
1833 2069
1834int x_pixel_height (struct frame *f) 2070int
2071x_pixel_height (struct frame *f)
1835{ 2072{
1836 return FRAME_HEIGHT(f); 2073 return FRAME_HEIGHT (f);
1837} 2074}
1838#endif /* !HAVE_X_WINDOWS */ 2075#endif /* !HAVE_X_WINDOWS */
1839 2076