Mercurial > emacs
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, ®s, ®s), | 1534 int86 (0x16, ®s, ®s), |
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 |