comparison src/msdos.c @ 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 84440bd95727
children 5c681a822a49
comparison
equal deleted inserted replaced
16597:ebdcc5509856 16598:4b0b6719bbd2
34 #include <dos.h> 34 #include <dos.h>
35 #include <errno.h> 35 #include <errno.h>
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
42 #include "dosfns.h" 44 #include "dosfns.h"
43 #include "msdos.h" 45 #include "msdos.h"
45 #include "termhooks.h" 47 #include "termhooks.h"
46 #include "dispextern.h" 48 #include "dispextern.h"
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>
53 /* #include <process.h> */ 57 /* #include <process.h> */
54 /* Damn that local process.h! Instead we can define P_WAIT ourselves. */ 58 /* Damn that local process.h! Instead we can define P_WAIT ourselves. */
292 struct x_output the_only_x_display; 296 struct x_output the_only_x_display;
293 297
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;
305 int x; 304 int x;
306 char *buf; 305 char *buf;
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
318 /* Flash the screen as a substitute for BEEPs. */ 323 /* Flash the screen as a substitute for BEEPs. */
319 324
645 fprintf (termscript, "\n<XY=%dx%d>", x, y); 650 fprintf (termscript, "\n<XY=%dx%d>", x, y);
646 new_pos_X = x; 651 new_pos_X = 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;
653 { 728 {
654 highlight = new; 729 highlight = new;
961 clear_frame_hook = IT_clear_screen; 1036 clear_frame_hook = IT_clear_screen;
962 change_line_highlight_hook = IT_change_line_highlight; 1037 change_line_highlight_hook = IT_change_line_highlight;
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;
969 reset_terminal_modes_hook = IT_reset_terminal_modes; 1045 reset_terminal_modes_hook = IT_reset_terminal_modes;
970 set_terminal_window_hook = IT_set_terminal_window; 1046 set_terminal_window_hook = IT_set_terminal_window;
1446 { 1522 {
1447 struct input_event event; 1523 struct input_event event;
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),
1458 int86 (0x16, &regs, &regs), 1534 int86 (0x16, &regs, &regs),
1459 (regs.x.flags & 0x40) == 0) 1535 (regs.x.flags & 0x40) == 0)
2034 } 2110 }
2035 state[0].menu = menu; 2111 state[0].menu = menu;
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] = ' ';
2042 if ((onepane = menu->count == 1 && menu->submenu[0])) 2122 if ((onepane = menu->count == 1 && menu->submenu[0]))
2043 { 2123 {
2121 2201
2122 mouse_off (); 2202 mouse_off ();
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
2129 /* Dispose of a menu. */ 2210 /* Dispose of a menu. */
2130 2211