Mercurial > emacs
changeset 16598:4b0b6719bbd2
[__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.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Tue, 19 Nov 1996 07:42:09 +0000 |
parents | ebdcc5509856 |
children | ae726fd5403b |
files | src/msdos.c |
diffstat | 1 files changed, 90 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/msdos.c Tue Nov 19 07:38:29 1996 +0000 +++ b/src/msdos.c Tue Nov 19 07:42:09 1996 +0000 @@ -36,6 +36,8 @@ #include <sys/stat.h> /* for _fixpath */ #if __DJGPP__ >= 2 #include <fcntl.h> +#include <dpmi.h> /* for __dpmi_xxx stuff */ +#include <sys/farptr.h> /* for _farsetsel, _farnspokeb */ #include <libc/dosio.h> /* for _USE_LFN */ #endif @@ -47,6 +49,8 @@ #include "termopts.h" #include "frame.h" #include "window.h" +#include "buffer.h" +#include "commands.h" #include <go32.h> #include <pc.h> #include <ctype.h> @@ -294,11 +298,6 @@ /* This is never dereferenced. */ Display *x_current_display; - -#define SCREEN_SET_CURSOR() \ - if (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y) \ - ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X) - static dos_direct_output (y, x, buf, len) int y; @@ -307,11 +306,17 @@ int len; { int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); - + +#if (__DJGPP__ < 2) while (--len >= 0) { dosmemput (buf++, 1, t); t += 2; } +#else + /* This is faster. */ + for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++) + _farnspokeb (t, *buf); +#endif } #endif @@ -647,6 +652,76 @@ new_pos_Y = y; } +static int cursor_cleared; + +static +IT_display_cursor (int on) +{ + if (on && cursor_cleared) + { + ScreenSetCursor (current_pos_Y, current_pos_X); + cursor_cleared = 0; + } + else if (!on && !cursor_cleared) + { + ScreenSetCursor (-1, -1); + cursor_cleared = 1; + } +} + +/* Emacs calls cursor-movement functions a lot when it updates the + display (probably a legacy of old terminals where you cannot + update a screen line without first moving the cursor there). + However, cursor movement is expensive on MSDOS (it calls a slow + BIOS function and requires 2 mode switches), while actual screen + updates access the video memory directly and don't depend on + cursor position. To avoid slowing down the redisplay, we cheat: + all functions that move the cursor only set internal variables + which record the cursor position, whereas the cursor is only + moved to its final position whenever screen update is complete. + + `IT_cmgoto' is called from the keyboard reading loop and when the + frame update is complete. This means that we are ready for user + input, so we update the cursor position to show where the point is, + and also make the mouse pointer visible. + + Special treatment is required when the cursor is in the echo area, + to put the cursor at the end of the text displayed there. */ + +static +IT_cmgoto (f) + FRAME_PTR f; +{ + /* Only set the cursor to where it should be if the display is + already in sync with the window contents. */ + int update_cursor_pos = MODIFF == unchanged_modified; + + /* If we are in the echo area, put the cursor at the end of text. */ + if (!update_cursor_pos + && XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top) <= new_pos_Y) + { + new_pos_X = FRAME_DESIRED_GLYPHS (f)->used[new_pos_Y]; + FRAME_CURSOR_X (f) = new_pos_X; + update_cursor_pos = 1; + } + + if (update_cursor_pos + && (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y)) + { + ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X); + if (termscript) + fprintf (termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y); + } + + /* Maybe cursor is invisible, so make it visible. */ + IT_display_cursor (1); + + /* Mouse pointer should be always visible if we are waiting for + keyboard input. */ + if (!mouse_visible) + mouse_on (); +} + static IT_reassert_line_highlight (new, vpos) int new, vpos; @@ -963,6 +1038,7 @@ update_begin_hook = IT_update_begin; update_end_hook = IT_update_end; reassert_line_highlight_hook = IT_reassert_line_highlight; + frame_up_to_date_hook = IT_cmgoto; /* position cursor when update is done */ /* These hooks are called by term.c without being checked. */ set_terminal_modes_hook = IT_set_terminal_modes; @@ -1448,10 +1524,10 @@ union REGS regs; #ifndef HAVE_X_WINDOWS - SCREEN_SET_CURSOR (); - if (!mouse_visible) mouse_on (); + /* Maybe put the cursor where it should be. */ + IT_cmgoto (selected_frame); #endif - + /* The following condition is equivalent to `kbhit ()', except that it uses the bios to do its job. This pleases DESQview/X. */ while ((regs.h.ah = extended_kbd ? 0x11 : 0x01), @@ -2036,6 +2112,10 @@ mouse_off (); ScreenRetrieve (state[0].screen_behind = xmalloc (screensize)); + /* Turn off the cursor. Otherwise it shows through the menu + panes, which is ugly. */ + IT_display_cursor (0); + IT_menu_display (menu, y0 - 1, x0 - 1, title_faces); /* display menu title */ if (buffers_num_deleted) menu->text[0][7] = ' '; @@ -2123,6 +2203,7 @@ ScreenUpdate (state[0].screen_behind); while (statecount--) xfree (state[statecount].screen_behind); + IT_display_cursor (1); /* turn cursor back on */ return result; }