diff options
| author | Karl Heuer | 1996-11-19 07:42:09 +0000 |
|---|---|---|
| committer | Karl Heuer | 1996-11-19 07:42:09 +0000 |
| commit | fc171623b4478aa7b80d3c3ee66459e989574997 (patch) | |
| tree | 15c9234a49d9e2b6e17e7074fe0fb7eb8333fb72 /src | |
| parent | c7385664fde60a1fe4d617ccd6d19d83b355c3c2 (diff) | |
| download | emacs-fc171623b4478aa7b80d3c3ee66459e989574997.tar.gz emacs-fc171623b4478aa7b80d3c3ee66459e989574997.zip | |
[__DJGPP__ >= 2] (dos_direct_output): Faster method of
writing characters to the screen.
(SCREEN_SET_CURSOR): Remove.
(IT_display_cursor): New function, to turn the cursor on and off.
(IT_cmgoto): New function, sets the cursor to its final position
whenever frame update is complete.
(internal_terminal_init): Set IT_cmgoto as the hook to be called
when frame is up to date.
(dos_rawgetc): Call IT_cmgoto instead of the SCREEN_SET_CURSOR
macro (which is gone now).
(XMenuActivate): Turn off the cursor while the menu is displayed,
to prevent it from showing through the menu panes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/msdos.c | 99 |
1 files changed, 90 insertions, 9 deletions
diff --git a/src/msdos.c b/src/msdos.c index 89925cc7e36..9291dd08f26 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -36,6 +36,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 36 | #include <sys/stat.h> /* for _fixpath */ | 36 | #include <sys/stat.h> /* for _fixpath */ |
| 37 | #if __DJGPP__ >= 2 | 37 | #if __DJGPP__ >= 2 |
| 38 | #include <fcntl.h> | 38 | #include <fcntl.h> |
| 39 | #include <dpmi.h> /* for __dpmi_xxx stuff */ | ||
| 40 | #include <sys/farptr.h> /* for _farsetsel, _farnspokeb */ | ||
| 39 | #include <libc/dosio.h> /* for _USE_LFN */ | 41 | #include <libc/dosio.h> /* for _USE_LFN */ |
| 40 | #endif | 42 | #endif |
| 41 | 43 | ||
| @@ -47,6 +49,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 47 | #include "termopts.h" | 49 | #include "termopts.h" |
| 48 | #include "frame.h" | 50 | #include "frame.h" |
| 49 | #include "window.h" | 51 | #include "window.h" |
| 52 | #include "buffer.h" | ||
| 53 | #include "commands.h" | ||
| 50 | #include <go32.h> | 54 | #include <go32.h> |
| 51 | #include <pc.h> | 55 | #include <pc.h> |
| 52 | #include <ctype.h> | 56 | #include <ctype.h> |
| @@ -294,11 +298,6 @@ struct x_output the_only_x_display; | |||
| 294 | /* This is never dereferenced. */ | 298 | /* This is never dereferenced. */ |
| 295 | Display *x_current_display; | 299 | Display *x_current_display; |
| 296 | 300 | ||
| 297 | |||
| 298 | #define SCREEN_SET_CURSOR() \ | ||
| 299 | if (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y) \ | ||
| 300 | ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X) | ||
| 301 | |||
| 302 | static | 301 | static |
| 303 | dos_direct_output (y, x, buf, len) | 302 | dos_direct_output (y, x, buf, len) |
| 304 | int y; | 303 | int y; |
| @@ -307,11 +306,17 @@ dos_direct_output (y, x, buf, len) | |||
| 307 | int len; | 306 | int len; |
| 308 | { | 307 | { |
| 309 | int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); | 308 | int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); |
| 310 | 309 | ||
| 310 | #if (__DJGPP__ < 2) | ||
| 311 | while (--len >= 0) { | 311 | while (--len >= 0) { |
| 312 | dosmemput (buf++, 1, t); | 312 | dosmemput (buf++, 1, t); |
| 313 | t += 2; | 313 | t += 2; |
| 314 | } | 314 | } |
| 315 | #else | ||
| 316 | /* This is faster. */ | ||
| 317 | for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++) | ||
| 318 | _farnspokeb (t, *buf); | ||
| 319 | #endif | ||
| 315 | } | 320 | } |
| 316 | #endif | 321 | #endif |
| 317 | 322 | ||
| @@ -647,6 +652,76 @@ IT_cursor_to (int y, int x) | |||
| 647 | new_pos_Y = y; | 652 | new_pos_Y = y; |
| 648 | } | 653 | } |
| 649 | 654 | ||
| 655 | static int cursor_cleared; | ||
| 656 | |||
| 657 | static | ||
| 658 | IT_display_cursor (int on) | ||
| 659 | { | ||
| 660 | if (on && cursor_cleared) | ||
| 661 | { | ||
| 662 | ScreenSetCursor (current_pos_Y, current_pos_X); | ||
| 663 | cursor_cleared = 0; | ||
| 664 | } | ||
| 665 | else if (!on && !cursor_cleared) | ||
| 666 | { | ||
| 667 | ScreenSetCursor (-1, -1); | ||
| 668 | cursor_cleared = 1; | ||
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 672 | /* Emacs calls cursor-movement functions a lot when it updates the | ||
| 673 | display (probably a legacy of old terminals where you cannot | ||
| 674 | update a screen line without first moving the cursor there). | ||
| 675 | However, cursor movement is expensive on MSDOS (it calls a slow | ||
| 676 | BIOS function and requires 2 mode switches), while actual screen | ||
| 677 | updates access the video memory directly and don't depend on | ||
| 678 | cursor position. To avoid slowing down the redisplay, we cheat: | ||
| 679 | all functions that move the cursor only set internal variables | ||
| 680 | which record the cursor position, whereas the cursor is only | ||
| 681 | moved to its final position whenever screen update is complete. | ||
| 682 | |||
| 683 | `IT_cmgoto' is called from the keyboard reading loop and when the | ||
| 684 | frame update is complete. This means that we are ready for user | ||
| 685 | input, so we update the cursor position to show where the point is, | ||
| 686 | and also make the mouse pointer visible. | ||
| 687 | |||
| 688 | Special treatment is required when the cursor is in the echo area, | ||
| 689 | to put the cursor at the end of the text displayed there. */ | ||
| 690 | |||
| 691 | static | ||
| 692 | IT_cmgoto (f) | ||
| 693 | FRAME_PTR f; | ||
| 694 | { | ||
| 695 | /* Only set the cursor to where it should be if the display is | ||
| 696 | already in sync with the window contents. */ | ||
| 697 | int update_cursor_pos = MODIFF == unchanged_modified; | ||
| 698 | |||
| 699 | /* If we are in the echo area, put the cursor at the end of text. */ | ||
| 700 | if (!update_cursor_pos | ||
| 701 | && XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top) <= new_pos_Y) | ||
| 702 | { | ||
| 703 | new_pos_X = FRAME_DESIRED_GLYPHS (f)->used[new_pos_Y]; | ||
| 704 | FRAME_CURSOR_X (f) = new_pos_X; | ||
| 705 | update_cursor_pos = 1; | ||
| 706 | } | ||
| 707 | |||
| 708 | if (update_cursor_pos | ||
| 709 | && (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y)) | ||
| 710 | { | ||
| 711 | ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X); | ||
| 712 | if (termscript) | ||
| 713 | fprintf (termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y); | ||
| 714 | } | ||
| 715 | |||
| 716 | /* Maybe cursor is invisible, so make it visible. */ | ||
| 717 | IT_display_cursor (1); | ||
| 718 | |||
| 719 | /* Mouse pointer should be always visible if we are waiting for | ||
| 720 | keyboard input. */ | ||
| 721 | if (!mouse_visible) | ||
| 722 | mouse_on (); | ||
| 723 | } | ||
| 724 | |||
| 650 | static | 725 | static |
| 651 | IT_reassert_line_highlight (new, vpos) | 726 | IT_reassert_line_highlight (new, vpos) |
| 652 | int new, vpos; | 727 | int new, vpos; |
| @@ -963,6 +1038,7 @@ internal_terminal_init () | |||
| 963 | update_begin_hook = IT_update_begin; | 1038 | update_begin_hook = IT_update_begin; |
| 964 | update_end_hook = IT_update_end; | 1039 | update_end_hook = IT_update_end; |
| 965 | reassert_line_highlight_hook = IT_reassert_line_highlight; | 1040 | reassert_line_highlight_hook = IT_reassert_line_highlight; |
| 1041 | frame_up_to_date_hook = IT_cmgoto; /* position cursor when update is done */ | ||
| 966 | 1042 | ||
| 967 | /* These hooks are called by term.c without being checked. */ | 1043 | /* These hooks are called by term.c without being checked. */ |
| 968 | set_terminal_modes_hook = IT_set_terminal_modes; | 1044 | set_terminal_modes_hook = IT_set_terminal_modes; |
| @@ -1448,10 +1524,10 @@ dos_rawgetc () | |||
| 1448 | union REGS regs; | 1524 | union REGS regs; |
| 1449 | 1525 | ||
| 1450 | #ifndef HAVE_X_WINDOWS | 1526 | #ifndef HAVE_X_WINDOWS |
| 1451 | SCREEN_SET_CURSOR (); | 1527 | /* Maybe put the cursor where it should be. */ |
| 1452 | if (!mouse_visible) mouse_on (); | 1528 | IT_cmgoto (selected_frame); |
| 1453 | #endif | 1529 | #endif |
| 1454 | 1530 | ||
| 1455 | /* The following condition is equivalent to `kbhit ()', except that | 1531 | /* The following condition is equivalent to `kbhit ()', except that |
| 1456 | it uses the bios to do its job. This pleases DESQview/X. */ | 1532 | it uses the bios to do its job. This pleases DESQview/X. */ |
| 1457 | while ((regs.h.ah = extended_kbd ? 0x11 : 0x01), | 1533 | while ((regs.h.ah = extended_kbd ? 0x11 : 0x01), |
| @@ -2036,6 +2112,10 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 2036 | mouse_off (); | 2112 | mouse_off (); |
| 2037 | ScreenRetrieve (state[0].screen_behind = xmalloc (screensize)); | 2113 | ScreenRetrieve (state[0].screen_behind = xmalloc (screensize)); |
| 2038 | 2114 | ||
| 2115 | /* Turn off the cursor. Otherwise it shows through the menu | ||
| 2116 | panes, which is ugly. */ | ||
| 2117 | IT_display_cursor (0); | ||
| 2118 | |||
| 2039 | IT_menu_display (menu, y0 - 1, x0 - 1, title_faces); /* display menu title */ | 2119 | IT_menu_display (menu, y0 - 1, x0 - 1, title_faces); /* display menu title */ |
| 2040 | if (buffers_num_deleted) | 2120 | if (buffers_num_deleted) |
| 2041 | menu->text[0][7] = ' '; | 2121 | menu->text[0][7] = ' '; |
| @@ -2123,6 +2203,7 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 2123 | ScreenUpdate (state[0].screen_behind); | 2203 | ScreenUpdate (state[0].screen_behind); |
| 2124 | while (statecount--) | 2204 | while (statecount--) |
| 2125 | xfree (state[statecount].screen_behind); | 2205 | xfree (state[statecount].screen_behind); |
| 2206 | IT_display_cursor (1); /* turn cursor back on */ | ||
| 2126 | return result; | 2207 | return result; |
| 2127 | } | 2208 | } |
| 2128 | 2209 | ||