comparison src/msdos.c @ 12995:a3620c5ffad7

(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.
author Richard M. Stallman <rms@gnu.org>
date Sun, 03 Sep 1995 17:32:58 +0000
parents 1415c961bea6
children a656ccd43989
comparison
equal deleted inserted replaced
12994:bd38619285f7 12995:a3620c5ffad7
51 51
52 int have_mouse; /* Mouse present? */ 52 int have_mouse; /* Mouse present? */
53 static int mouse_last_x; 53 static int mouse_last_x;
54 static int mouse_last_y; 54 static 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
66 static void
67 mouse_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. */
58 int 71 int
59 dos_ttraw () 72 dos_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 (); 86
71 87 if (only_once)
72 inregs.x.ax = 0x4400; /* Get IOCTL status. */ 88 have_mouse = mouse_init1 ();
73 inregs.x.bx = 0x00; /* 0 = stdin. */ 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 }
82 102
83 /* Restore status of standard input and Ctrl-C checking. */ 103 /* Restore status of standard input and Ctrl-C checking. */
85 dos_ttcooked () 105 dos_ttcooked ()
86 { 106 {
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. */
94 inregs.x.dx = stdin_stat; 114 inregs.x.dx = stdin_stat;
95 intdos (&inregs, &outregs); 115 intdos (&inregs, &outregs);
96 return !outregs.x.cflag; 116 return !outregs.x.cflag;
117 }
118
119 /* generate a reliable event timestamp, KFS 1995-07-06 */
120
121 static unsigned long
122 event_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;
97 } 135 }
98 136
99 static unsigned short 137 static unsigned short
100 ibmpc_translate_map[] = 138 ibmpc_translate_map[] =
101 { 139 {
252 /* Get a char from keyboard. Function keys are put into the event queue. */ 290 /* Get a char from keyboard. Function keys are put into the event queue. */
253 static int 291 static int
254 dos_rawgetc () 292 dos_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);
264 ctrl_p = ((regs.h.al & 4) != 0); 301 ctrl_p = ((regs.h.al & 4) != 0);
265 shift_p = ((regs.h.al & 3) != 0); 302 shift_p = ((regs.h.al & 3) != 0);
286 /* Determine from the scan code if a keypad key was pressed. */ 323 /* Determine from the scan code if a keypad key was pressed. */
287 if (c >= '0' && c <= '9' && sc > 0xb) 324 if (c >= '0' && c <= '9' && sc > 0xb)
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;
302 case '/': 339 case '/':
303 sc = 0x35; 340 sc = 0x35;
310 347
311 if (c == 0 348 if (c == 0
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; 404 }
368 } 405
369 406 if (have_mouse > 0)
370 if (have_mouse)
371 { 407 {
372 int but, press, x, y, ok; 408 int but, press, x, y, ok;
373 409
374 /* Check for mouse movement *before* buttons. */ 410 /* Check for mouse movement *before* buttons. */
375 mouse_check_moved (); 411 mouse_check_moved ();
391 + (alt_p ? meta_modifier : 0) 427 + (alt_p ? meta_modifier : 0)
392 + (press ? down_modifier : up_modifier); 428 + (press ? down_modifier : up_modifier);
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 }
401 } 436 }
402 437
521 { 556 {
522 char *saveargv1, *saveargv2, **envv; 557 char *saveargv1, *saveargv2, **envv;
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. */
529 getwd (oldwd); 565 getwd (oldwd);
530 566
577 inbak = dup (0); 613 inbak = dup (0);
578 outbak = dup (1); 614 outbak = dup (1);
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)
595 { 648 {
596 argv[1] = saveargv1; 649 argv[1] = saveargv1;
627 int 680 int
628 sys_chdir (path) 681 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
646 void 708 #include "sysselect.h"
647 sleep_or_kbd_hit (secs, kbdok) 709
648 int secs, kbdok; 710 /* Only event queue is checked. */
649 { 711 int
650 long clnow, clthen; 712 sys_select (nfds, rfds, wfds, efds, timeout)
651 struct timeval t; 713 int nfds;
652 714 SELECT_TYPE *rfds, *wfds, *efds;
653 gettimeofday (&t, NULL); 715 EMACS_TIME *timeout;
654 clnow = t.tv_sec * 100 + t.tv_usec / 10000; 716 {
655 clthen = clnow + (100 * secs); 717 SELECT_TYPE orfds;
656 718 long timeoutval, clnow, cllast;
657 do 719 struct time t;
658 { 720
659 gettimeofday (&t, NULL); 721 FD_ZERO (&orfds);
660 clnow = t.tv_sec * 100 + t.tv_usec / 10000; 722 if (rfds)
661 if (kbdok && detect_input_pending ()) 723 {
662 return; 724 orfds = *rfds;
663 } 725 FD_ZERO (rfds);
664 while (clnow < clthen); 726 }
665 } 727 if (wfds)
728 FD_ZERO (wfds);
729 if (efds)
730 FD_ZERO (efds);
731
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)
738 {
739 while (! detect_input_pending ());
740 }
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;
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. */
668 static char emacsroot[MAXPATHLEN]; 767 static char emacsroot[MAXPATHLEN];
669 768
670 char * 769 char *
834 int x, y, c; 933 int x, y, c;
835 unsigned char *s; 934 unsigned char *s;
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
842 movl %%eax,%%edi 948 movl %%eax,%%edi
843 movb %0,%%ah 949 movb %0,%%ah
848 movw %%ax,%%gs:(%%edi) 954 movw %%ax,%%gs:(%%edi)
849 addl $2,%%edi 955 addl $2,%%edi
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
858 static int internal_terminal = 0; 964 static int internal_terminal = 0;
859 static int highlight; 965 static int highlight;
860 966
861 #undef fflush 967 #undef fflush
968
969 static int /* number of characters used by escape; -1 if incomplete */
970 flush_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 }
862 1067
863 int 1068 int
864 internal_flush (f) 1069 internal_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); 1148 }
959 ScreenSetCursor (y, x); 1149 fpurge (stdout);
960 if (have_mouse) mouse_on (); 1150 ScreenSetCursor (y, x);
961 } 1151 mouse_on ();
962 else
963 /* This is a call to the original fflush. */
964 fflush (f);
965 } 1152 }
966 1153
967 #ifndef HAVE_X_WINDOWS 1154 #ifndef HAVE_X_WINDOWS
968 static void 1155 static void
969 rien_du_tout () 1156 rien_du_tout ()
976 { 1163 {
977 if (visible_bell) 1164 if (visible_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
989 emulator. This way the mouse cursor won't blink. */ 1176 emulator. This way the mouse cursor won't blink. */
990 write (1, "\007", 1); 1177 write (1, "\007", 1);
1000 fp = FRAME_MODE_LINE_FACE (foo); 1187 fp = FRAME_MODE_LINE_FACE (foo);
1001 else if (face <= 0 || face >= FRAME_N_COMPUTED_FACES (foo)) 1188 else if (face <= 0 || face >= FRAME_N_COMPUTED_FACES (foo))
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));
1008 } 1199 }
1009 1200
1010 static 1201 static
1011 IT_write_glyphs (GLYPH *str, int len) 1202 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 }
1025 1223
1026 static 1224 static
1027 IT_clear_end_of_line (first_unused) 1225 IT_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 }
1032 1235
1033 static 1236 static
1034 IT_cursor_to (int y, int x) 1237 IT_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);
1039 putchar (x); 1246 putchar (x);
1040 } 1247 }
1155 /* Do we need the internal terminal? */ 1362 /* Do we need the internal terminal? */
1156 void 1363 void
1157 internal_terminal_init () 1364 internal_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;
1164 #endif 1372 #endif
1165 1373
1173 Vwindow_system_version = make_number (1); 1381 Vwindow_system_version = make_number (1);
1174 1382
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;
1181 1395
1182 init_frame_faces ((FRAME_PTR) &the_only_frame); 1396 init_frame_faces ((FRAME_PTR) &the_only_frame);
1310 void 1524 void
1311 mouse_on () 1525 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
1319 void 1536 void
1320 mouse_off () 1537 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
1328 void 1548 void
1329 mouse_moveto (x, y) 1549 mouse_moveto (x, y)
1330 int x, y; 1550 int x, y;
1362 if (b >= mouse_button_count) 1582 if (b >= mouse_button_count)
1363 return 0; 1583 return 0;
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);
1370 } 1594 }
1371 1595
1388 enum scroll_bar_part *part; 1612 enum scroll_bar_part *part;
1389 unsigned long *time; 1613 unsigned long *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
1407 void 1629 void
1408 mouse_check_moved () 1630 mouse_check_moved ()
1409 { 1631 {
1456 mouse_button_translate[0] = 0; 1678 mouse_button_translate[0] = 0;
1457 mouse_button_translate[1] = 1; 1679 mouse_button_translate[1] = 1;
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
1465 #ifndef HAVE_X_WINDOWS 1687 #ifndef HAVE_X_WINDOWS
1466 /* See xterm.c for more info. */ 1688 /* See xterm.c for more info. */
1508 return menu; 1730 return menu;
1509 } 1731 }
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
1513 static void 1736 static void
1514 IT_menu_make_room (XMenu *menu) 1737 IT_menu_make_room (XMenu *menu)
1515 { 1738 {
1516 if (menu->allocated == 0) 1739 if (menu->allocated == 0)
1517 { 1740 {
1531 = (int *) xrealloc (menu->panenumber, count * sizeof (int)); 1754 = (int *) xrealloc (menu->panenumber, count * sizeof (int));
1532 } 1755 }
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
1536 static XMenu * 1760 static XMenu *
1537 IT_menu_search_pane (XMenu *menu, int pane) 1761 IT_menu_search_pane (XMenu *menu, int pane)
1538 { 1762 {
1539 int i; 1763 int i;
1540 XMenu *try; 1764 XMenu *try;
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
1553 static void 1779 static void
1554 IT_menu_calc_size (XMenu *menu, int *width, int *height) 1780 IT_menu_calc_size (XMenu *menu, int *width, int *height)
1555 { 1781 {
1556 int i, h2, w2, maxsubwidth, maxheight; 1782 int i, h2, w2, maxsubwidth, maxheight;
1557 1783
1569 *width = menu->width + maxsubwidth; 1795 *width = menu->width + maxsubwidth;
1570 *height = maxheight; 1796 *height = maxheight;
1571 } 1797 }
1572 1798
1573 /* Display MENU at (X,Y) using FACES. */ 1799 /* Display MENU at (X,Y) using FACES. */
1800
1574 static void 1801 static void
1575 IT_menu_display (XMenu *menu, int y, int x, int *faces) 1802 IT_menu_display (XMenu *menu, int y, int x, int *faces)
1576 { 1803 {
1577 int i, j, face, width; 1804 int i, j, face, width;
1578 GLYPH *text, *p; 1805 GLYPH *text, *p;
1609 ScreenSetCursor (row, col); 1836 ScreenSetCursor (row, col);
1610 xfree (text); 1837 xfree (text);
1611 } 1838 }
1612 1839
1613 /* Create a brand new menu structure. */ 1840 /* Create a brand new menu structure. */
1841
1614 XMenu * 1842 XMenu *
1615 XMenuCreate (Display *foo1, Window foo2, char *foo3) 1843 XMenuCreate (Display *foo1, Window foo2, char *foo3)
1616 { 1844 {
1617 return IT_menu_create (); 1845 return IT_menu_create ();
1618 } 1846 }
1619 1847
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
1623 int 1852 int
1624 XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable) 1853 XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable)
1625 { 1854 {
1626 int len; 1855 int len;
1627 1856
1631 IT_menu_make_room (menu); 1860 IT_menu_make_room (menu);
1632 menu->submenu[menu->count] = IT_menu_create (); 1861 menu->submenu[menu->count] = IT_menu_create ();
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
1641 int 1872 int
1642 XMenuAddSelection (Display *bar, XMenu *menu, int pane, 1873 XMenuAddSelection (Display *bar, XMenu *menu, int pane,
1643 int foo, char *txt, int enable) 1874 int foo, char *txt, int enable)
1644 { 1875 {
1645 int len; 1876 int len;
1650 IT_menu_make_room (menu); 1881 IT_menu_make_room (menu);
1651 menu->submenu[menu->count] = (XMenu *) 0; 1882 menu->submenu[menu->count] = (XMenu *) 0;
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
1660 void 1893 void
1661 XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y, 1894 XMenuLocate (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)
1663 { 1896 {
1664 if (menu->count == 1 && menu->submenu[0]) 1897 if (menu->count == 1 && menu->submenu[0])
1669 *ulx = x + 1; 1902 *ulx = x + 1;
1670 *uly = y; 1903 *uly = y;
1671 *width += 2; 1904 *width += 2;
1672 } 1905 }
1673 1906
1674 typedef struct 1907 struct 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
1684 int 1918 int
1685 XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, 1919 XMenuActivate (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;
1692 int faces[4], selectface; 1926 int faces[4], selectface;
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,
1703 face_name_id_number 1937 face_name_id_number
1704 (&the_only_frame, 1938 (&the_only_frame,
1808 xfree (state[statecount].screen_behind); 2042 xfree (state[statecount].screen_behind);
1809 return result; 2043 return result;
1810 } 2044 }
1811 2045
1812 /* Dispose of a menu. */ 2046 /* Dispose of a menu. */
2047
1813 void 2048 void
1814 XMenuDestroy (Display *foo, XMenu *menu) 2049 XMenuDestroy (Display *foo, XMenu *menu)
1815 { 2050 {
1816 int i; 2051 int i;
1817 if (menu->allocated) 2052 if (menu->allocated)
1824 xfree (menu->panenumber); 2059 xfree (menu->panenumber);
1825 } 2060 }
1826 xfree (menu); 2061 xfree (menu);
1827 } 2062 }
1828 2063
1829 int x_pixel_width (struct frame *f) 2064 int
1830 { 2065 x_pixel_width (struct frame *f)
1831 return FRAME_WIDTH(f); 2066 {
1832 } 2067 return FRAME_WIDTH (f);
1833 2068 }
1834 int x_pixel_height (struct frame *f) 2069
1835 { 2070 int
1836 return FRAME_HEIGHT(f); 2071 x_pixel_height (struct frame *f)
2072 {
2073 return FRAME_HEIGHT (f);
1837 } 2074 }
1838 #endif /* !HAVE_X_WINDOWS */ 2075 #endif /* !HAVE_X_WINDOWS */
1839 2076
1840 #endif /* MSDOS */ 2077 #endif /* MSDOS */