Mercurial > emacs
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, ®s, ®s); | 300 int86 (0x16, ®s, ®s); |
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, ®s, ®s); | 1530 { |
1531 regs.x.ax = 0x0001; | |
1532 int86 (0x33, ®s, ®s); | |
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, ®s, ®s); | 1542 { |
1543 regs.x.ax = 0x0002; | |
1544 int86 (0x33, ®s, ®s); | |
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, ®s, ®s); | 1586 int86 (0x33, ®s, ®s); |
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, ®s, ®s); | 1619 int86 (0x33, ®s, ®s); |
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 */ |