diff options
| author | Richard M. Stallman | 1995-09-03 17:32:58 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-09-03 17:32:58 +0000 |
| commit | aee81730019fba3d28a288fd843921671826c523 (patch) | |
| tree | 2de6649b513e93126b536f5c1785f7e28e2e34b6 /src | |
| parent | c70c27055d0cd10097196099b5429af2e9638d08 (diff) | |
| download | emacs-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.c | 665 |
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? */ | |||
| 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 (); | ||
| 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 | |||
| 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; | ||
| 135 | } | ||
| 136 | |||
| 99 | static unsigned short | 137 | static unsigned short |
| 100 | ibmpc_translate_map[] = | 138 | ibmpc_translate_map[] = |
| 101 | { | 139 | { |
| @@ -254,10 +292,9 @@ 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); |
| @@ -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 |
| 646 | void | 708 | #include "sysselect.h" |
| 647 | sleep_or_kbd_hit (secs, kbdok) | 709 | |
| 648 | int secs, kbdok; | 710 | /* Only event queue is checked. */ |
| 711 | int | ||
| 712 | sys_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. */ |
| 668 | static char emacsroot[MAXPATHLEN]; | 767 | static 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 | ||
| 858 | static int internal_terminal = 0; | 964 | static int internal_terminal = 0; |
| @@ -860,108 +966,189 @@ static int highlight; | |||
| 860 | 966 | ||
| 861 | #undef fflush | 967 | #undef fflush |
| 862 | 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 | } | ||
| 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); | ||
| 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) | |||
| 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 | } |
| @@ -1033,6 +1236,10 @@ IT_clear_end_of_line (first_unused) | |||
| 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); |
| @@ -1157,7 +1364,8 @@ 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; |
| @@ -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, ®s, ®s); | 1530 | { |
| 1531 | regs.x.ax = 0x0001; | ||
| 1532 | int86 (0x33, ®s, ®s); | ||
| 1533 | } | ||
| 1317 | } | 1534 | } |
| 1318 | 1535 | ||
| 1319 | void | 1536 | void |
| @@ -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, ®s, ®s); | 1542 | { |
| 1543 | regs.x.ax = 0x0002; | ||
| 1544 | int86 (0x33, ®s, ®s); | ||
| 1545 | } | ||
| 1326 | } | 1546 | } |
| 1327 | 1547 | ||
| 1328 | void | 1548 | void |
| @@ -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, ®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); |
| @@ -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, ®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 |
| @@ -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 | |||
| 1513 | static void | 1736 | static void |
| 1514 | IT_menu_make_room (XMenu *menu) | 1737 | IT_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 | |||
| 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 | { |
| @@ -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 | |||
| 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 | { |
| @@ -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 | |||
| 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 | { |
| @@ -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 | |||
| 1614 | XMenu * | 1842 | XMenu * |
| 1615 | XMenuCreate (Display *foo1, Window foo2, char *foo3) | 1843 | XMenuCreate (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 | |||
| 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 | { |
| @@ -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 | |||
| 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) |
| @@ -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 | |||
| 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) |
| @@ -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 | ||
| 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; |
| @@ -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 | |||
| 1813 | void | 2048 | void |
| 1814 | XMenuDestroy (Display *foo, XMenu *menu) | 2049 | XMenuDestroy (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 | ||
| 1829 | int x_pixel_width (struct frame *f) | 2064 | int |
| 2065 | x_pixel_width (struct frame *f) | ||
| 1830 | { | 2066 | { |
| 1831 | return FRAME_WIDTH(f); | 2067 | return FRAME_WIDTH (f); |
| 1832 | } | 2068 | } |
| 1833 | 2069 | ||
| 1834 | int x_pixel_height (struct frame *f) | 2070 | int |
| 2071 | x_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 | ||