Mercurial > emacs
comparison src/msdos.c @ 28092:ce3bf4da00a9
(vga_installed): New function, code moved from
dos_set_window_size.
(Qbar, Qcursor_type, outside_cursor): New variables.
(syms_of_msdos): Intern and staticpro them.
(dos_ttraw) [__DJGPP__ >= 2, !HAVE_X_WINDOWS]: Save the cursor
shape used outside Emacs when called for the first time.
(dos_ttcooked) [__DJGPP__ >= 2, !HAVE_X_WINDOWS]: Restore the
cursor shape used outside Emacs.
(msdos_set_cursor_shape, IT_set_cursor_type): New functions.
(IT_frame_up_to_date): Call IT_set_cursor_type, in case the cursor
type has changed.
(IT_set_frame_parameters): Call IT_set_cursor_type if the frame
parameters specify the cursor. Make qreverse a global
variable (renamed to Qreverse).
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sun, 12 Mar 2000 12:32:17 +0000 |
parents | 5b87cdbef5a8 |
children | 4bba3027ae58 |
comparison
equal
deleted
inserted
replaced
28091:d28d789a8521 | 28092:ce3bf4da00a9 |
---|---|
340 | 340 |
341 static clock_t startup_time; | 341 static clock_t startup_time; |
342 | 342 |
343 static int term_setup_done; | 343 static int term_setup_done; |
344 | 344 |
345 static unsigned short outside_cursor; | |
346 | |
345 /* Similar to the_only_frame. */ | 347 /* Similar to the_only_frame. */ |
346 struct x_output the_only_x_display; | 348 struct x_output the_only_x_display; |
347 | 349 |
348 /* Support for DOS/V (allows Japanese characters to be displayed on | 350 /* Support for DOS/V (allows Japanese characters to be displayed on |
349 standard, non-Japanese, ATs). Only supported for DJGPP v2 and later. */ | 351 standard, non-Japanese, ATs). Only supported for DJGPP v2 and later. */ |
353 /* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ | 355 /* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ |
354 static unsigned short screen_virtual_segment = 0; | 356 static unsigned short screen_virtual_segment = 0; |
355 static unsigned short screen_virtual_offset = 0; | 357 static unsigned short screen_virtual_offset = 0; |
356 /* A flag to control how to display unibyte 8-bit characters. */ | 358 /* A flag to control how to display unibyte 8-bit characters. */ |
357 extern int unibyte_display_via_language_environment; | 359 extern int unibyte_display_via_language_environment; |
360 | |
361 Lisp_Object Qbar; | |
358 | 362 |
359 #if __DJGPP__ > 1 | 363 #if __DJGPP__ > 1 |
360 /* Update the screen from a part of relocated DOS/V screen buffer which | 364 /* Update the screen from a part of relocated DOS/V screen buffer which |
361 begins at OFFSET and includes COUNT characters. */ | 365 begins at OFFSET and includes COUNT characters. */ |
362 static void | 366 static void |
483 regs.x.ax = 0x1003; | 487 regs.x.ax = 0x1003; |
484 int86 (0x10, ®s, ®s); | 488 int86 (0x10, ®s, ®s); |
485 } | 489 } |
486 } | 490 } |
487 | 491 |
492 /* Return non-zero if the system has a VGA adapter. */ | |
493 static int | |
494 vga_installed (void) | |
495 { | |
496 union REGS regs; | |
497 | |
498 regs.x.ax = 0x1a00; | |
499 int86 (0x10, ®s, ®s); | |
500 if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13) | |
501 return 1; | |
502 return 0; | |
503 } | |
504 | |
488 /* Set the screen dimensions so that it can show no less than | 505 /* Set the screen dimensions so that it can show no less than |
489 ROWS x COLS frame. */ | 506 ROWS x COLS frame. */ |
490 | 507 |
491 void | 508 void |
492 dos_set_window_size (rows, cols) | 509 dos_set_window_size (rows, cols) |
500 int current_rows = ScreenRows (), current_cols = ScreenCols (); | 517 int current_rows = ScreenRows (), current_cols = ScreenCols (); |
501 | 518 |
502 if (*rows == current_rows && *cols == current_cols) | 519 if (*rows == current_rows && *cols == current_cols) |
503 return; | 520 return; |
504 | 521 |
505 /* Do we have a VGA? */ | |
506 regs.x.ax = 0x1a00; | |
507 int86 (0x10, ®s, ®s); | |
508 if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13) | |
509 have_vga = 1; | |
510 | |
511 mouse_off (); | 522 mouse_off (); |
523 have_vga = vga_installed (); | |
512 | 524 |
513 /* If the user specified a special video mode for these dimensions, | 525 /* If the user specified a special video mode for these dimensions, |
514 use that mode. */ | 526 use that mode. */ |
515 sprintf (video_name, "screen-dimensions-%dx%d", *rows, *cols); | 527 sprintf (video_name, "screen-dimensions-%dx%d", *rows, *cols); |
516 video_mode = XSYMBOL (Fintern_soft (build_string (video_name), | 528 video_mode = XSYMBOL (Fintern_soft (build_string (video_name), |
652 mouse_get_xy (&x, &y); | 664 mouse_get_xy (&x, &y); |
653 if (y != new_pos_Y || x < new_pos_X) | 665 if (y != new_pos_Y || x < new_pos_X) |
654 return; | 666 return; |
655 | 667 |
656 mouse_off (); | 668 mouse_off (); |
669 } | |
670 | |
671 #define DEFAULT_CURSOR_START (-1) | |
672 #define DEFAULT_CURSOR_WIDTH (-1) | |
673 #define BOX_CURSOR_WIDTH (-32) | |
674 | |
675 /* Set cursor to begin at scan line START_LINE in the character cell | |
676 and extend for WIDTH scan lines. Scan lines are counted from top | |
677 of the character cell, starting from zero. */ | |
678 static void | |
679 msdos_set_cursor_shape (struct frame *f, int start_line, int width) | |
680 { | |
681 #if __DJGPP__ > 1 | |
682 unsigned desired_cursor; | |
683 __dpmi_regs regs; | |
684 int max_line, top_line, bot_line; | |
685 | |
686 /* Avoid the costly BIOS call if F isn't the currently selected | |
687 frame. Allow for NULL as unconditionally meaning the selected | |
688 frame. */ | |
689 if (f && f != SELECTED_FRAME()) | |
690 return; | |
691 | |
692 /* The character cell size in scan lines is stored at 40:85 in the | |
693 BIOS data area. */ | |
694 max_line = _farpeekw (_dos_ds, 0x485) - 1; | |
695 switch (max_line) | |
696 { | |
697 default: /* this relies on CGA cursor emulation being ON! */ | |
698 case 7: | |
699 bot_line = 7; | |
700 break; | |
701 case 9: | |
702 bot_line = 9; | |
703 break; | |
704 case 13: | |
705 bot_line = 12; | |
706 break; | |
707 case 15: | |
708 bot_line = 14; | |
709 break; | |
710 } | |
711 | |
712 if (width < 0) | |
713 { | |
714 if (width == BOX_CURSOR_WIDTH) | |
715 { | |
716 top_line = 0; | |
717 bot_line = max_line; | |
718 } | |
719 else if (start_line != DEFAULT_CURSOR_START) | |
720 { | |
721 top_line = start_line; | |
722 bot_line = top_line - width - 1; | |
723 } | |
724 else if (width != DEFAULT_CURSOR_WIDTH) | |
725 { | |
726 top_line = 0; | |
727 bot_line = -1 - width; | |
728 } | |
729 else | |
730 top_line = bot_line + 1; | |
731 } | |
732 else if (width == 0) | |
733 { | |
734 /* [31, 0] seems to DTRT for all screen sizes. */ | |
735 top_line = 31; | |
736 bot_line = 0; | |
737 } | |
738 else /* WIDTH is positive */ | |
739 { | |
740 if (start_line != DEFAULT_CURSOR_START) | |
741 bot_line = start_line; | |
742 top_line = bot_line - (width - 1); | |
743 } | |
744 | |
745 /* If the current cursor shape is already what they want, we are | |
746 history here. */ | |
747 desired_cursor = ((top_line & 0x1f) << 8) | (bot_line & 0x1f); | |
748 if (desired_cursor == _farpeekw (_dos_ds, 0x460)) | |
749 return; | |
750 | |
751 regs.h.ah = 1; | |
752 regs.x.cx = desired_cursor; | |
753 __dpmi_int (0x10, ®s); | |
754 #endif /* __DJGPP__ > 1 */ | |
755 } | |
756 | |
757 static void | |
758 IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type) | |
759 { | |
760 if (EQ (cursor_type, Qbar)) | |
761 { | |
762 /* Just BAR means the normal EGA/VGA cursor. */ | |
763 msdos_set_cursor_shape (f, DEFAULT_CURSOR_START, DEFAULT_CURSOR_WIDTH); | |
764 } | |
765 else if (CONSP (cursor_type) && EQ (XCAR (cursor_type), Qbar)) | |
766 { | |
767 Lisp_Object bar_parms = XCDR (cursor_type); | |
768 int width; | |
769 | |
770 if (INTEGERP (bar_parms)) | |
771 { | |
772 /* Feature: negative WIDTH means cursor at the top | |
773 of the character cell, zero means invisible cursor. */ | |
774 width = XINT (bar_parms); | |
775 msdos_set_cursor_shape (f, width >= 0 ? DEFAULT_CURSOR_START : 0, | |
776 width); | |
777 } | |
778 else if (CONSP (bar_parms) | |
779 && INTEGERP (XCAR (bar_parms)) | |
780 && INTEGERP (XCDR (bar_parms))) | |
781 { | |
782 int start_line = XINT (XCDR (bar_parms)); | |
783 | |
784 width = XINT (XCAR (bar_parms)); | |
785 msdos_set_cursor_shape (f, start_line, width); | |
786 } | |
787 } | |
788 else | |
789 /* Treat anything unknown as "box cursor". This includes nil, so | |
790 that a frame which doesn't specify a cursor type gets a box, | |
791 which is the default in Emacs. */ | |
792 msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH); | |
657 } | 793 } |
658 | 794 |
659 static void | 795 static void |
660 IT_ring_bell (void) | 796 IT_ring_bell (void) |
661 { | 797 { |
1754 { | 1890 { |
1755 highlight = 0; | 1891 highlight = 0; |
1756 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0; | 1892 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0; |
1757 } | 1893 } |
1758 | 1894 |
1895 Lisp_Object Qcursor_type; | |
1896 | |
1759 static void | 1897 static void |
1760 IT_frame_up_to_date (struct frame *f) | 1898 IT_frame_up_to_date (struct frame *f) |
1761 { | 1899 { |
1762 struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 1900 struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
1763 | 1901 |
1771 dpyinfo->mouse_face_mouse_y); | 1909 dpyinfo->mouse_face_mouse_y); |
1772 dpyinfo->mouse_face_deferred_gc = 0; | 1910 dpyinfo->mouse_face_deferred_gc = 0; |
1773 UNBLOCK_INPUT; | 1911 UNBLOCK_INPUT; |
1774 } | 1912 } |
1775 | 1913 |
1914 /* Set the cursor type to whatever they wanted. */ | |
1915 IT_set_cursor_type (f, Fcdr (Fassq (Qcursor_type, f->param_alist))); | |
1916 | |
1776 IT_cmgoto (f); /* position cursor when update is done */ | 1917 IT_cmgoto (f); /* position cursor when update is done */ |
1777 } | 1918 } |
1778 | 1919 |
1779 /* Copy LEN glyphs displayed on a single line whose vertical position | 1920 /* Copy LEN glyphs displayed on a single line whose vertical position |
1780 is YPOS, beginning at horizontal position XFROM to horizontal | 1921 is YPOS, beginning at horizontal position XFROM to horizontal |
1845 | 1986 |
1846 /* This was copied from xfns.c */ | 1987 /* This was copied from xfns.c */ |
1847 | 1988 |
1848 Lisp_Object Qbackground_color; | 1989 Lisp_Object Qbackground_color; |
1849 Lisp_Object Qforeground_color; | 1990 Lisp_Object Qforeground_color; |
1991 Lisp_Object Qreverse; | |
1850 extern Lisp_Object Qtitle; | 1992 extern Lisp_Object Qtitle; |
1851 | 1993 |
1852 /* IT_set_terminal_modes is called when emacs is started, | 1994 /* IT_set_terminal_modes is called when emacs is started, |
1853 resumed, and whenever the screen is redrawn! */ | 1995 resumed, and whenever the screen is redrawn! */ |
1854 | 1996 |
2038 int i, j; | 2180 int i, j; |
2039 Lisp_Object *parms | 2181 Lisp_Object *parms |
2040 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); | 2182 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); |
2041 Lisp_Object *values | 2183 Lisp_Object *values |
2042 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); | 2184 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); |
2043 Lisp_Object qreverse = intern ("reverse"); | |
2044 /* Do we have to reverse the foreground and background colors? */ | 2185 /* Do we have to reverse the foreground and background colors? */ |
2045 int reverse = EQ (Fcdr (Fassq (qreverse, f->param_alist)), Qt); | 2186 int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt); |
2046 int was_reverse = reverse; | 2187 int was_reverse = reverse; |
2047 int redraw = 0, fg_set = 0, bg_set = 0; | 2188 int redraw = 0, fg_set = 0, bg_set = 0; |
2048 unsigned long orig_fg; | 2189 unsigned long orig_fg; |
2049 unsigned long orig_bg; | 2190 unsigned long orig_bg; |
2050 | 2191 |
2077 for (i = 0; i < j; i++) | 2218 for (i = 0; i < j; i++) |
2078 { | 2219 { |
2079 Lisp_Object prop = parms[i]; | 2220 Lisp_Object prop = parms[i]; |
2080 Lisp_Object val = values[i]; | 2221 Lisp_Object val = values[i]; |
2081 | 2222 |
2082 if (EQ (prop, qreverse)) | 2223 if (EQ (prop, Qreverse)) |
2083 reverse = EQ (val, Qt); | 2224 reverse = EQ (val, Qt); |
2084 } | 2225 } |
2085 | 2226 |
2086 if (termscript && reverse && !was_reverse) | 2227 if (termscript && reverse && !was_reverse) |
2087 fprintf (termscript, "<INVERSE-VIDEO>\n"); | 2228 fprintf (termscript, "<INVERSE-VIDEO>\n"); |
2135 else if (EQ (prop, Qtitle)) | 2276 else if (EQ (prop, Qtitle)) |
2136 { | 2277 { |
2137 x_set_title (f, val); | 2278 x_set_title (f, val); |
2138 if (termscript) | 2279 if (termscript) |
2139 fprintf (termscript, "<TITLE: %s>\n", XSTRING (val)->data); | 2280 fprintf (termscript, "<TITLE: %s>\n", XSTRING (val)->data); |
2281 } | |
2282 else if (EQ (prop, Qcursor_type)) | |
2283 { | |
2284 IT_set_cursor_type (f, val); | |
2285 if (termscript) | |
2286 fprintf (termscript, "<CTYPE: %s>\n", | |
2287 EQ (val, Qbar) || CONSP (val) && EQ (XCAR (val), Qbar) | |
2288 ? "bar" : "box"); | |
2140 } | 2289 } |
2141 store_frame_param (f, prop, val); | 2290 store_frame_param (f, prop, val); |
2142 } | 2291 } |
2143 | 2292 |
2144 /* If they specified "reverse", but not the colors, we need to swap | 2293 /* If they specified "reverse", but not the colors, we need to swap |
4265 mouse_button_translate[1] = 1; | 4414 mouse_button_translate[1] = 1; |
4266 } | 4415 } |
4267 mouse_position_hook = &mouse_get_pos; | 4416 mouse_position_hook = &mouse_get_pos; |
4268 mouse_init (); | 4417 mouse_init (); |
4269 } | 4418 } |
4419 | |
4420 #ifndef HAVE_X_WINDOWS | |
4421 #if __DJGPP__ >= 2 | |
4422 /* Save the cursor shape used outside Emacs. */ | |
4423 outside_cursor = _farpeekw (_dos_ds, 0x460); | |
4424 #endif | |
4425 #endif | |
4270 } | 4426 } |
4271 | 4427 |
4272 first_time = 0; | 4428 first_time = 0; |
4273 | 4429 |
4274 #if __DJGPP__ >= 2 | 4430 #if __DJGPP__ >= 2 |
4309 | 4465 |
4310 setcbrk (break_stat); | 4466 setcbrk (break_stat); |
4311 mouse_off (); | 4467 mouse_off (); |
4312 | 4468 |
4313 #if __DJGPP__ >= 2 | 4469 #if __DJGPP__ >= 2 |
4470 | |
4471 #ifndef HAVE_X_WINDOWS | |
4472 /* Restore the cursor shape we found on startup. */ | |
4473 if (outside_cursor) | |
4474 { | |
4475 inregs.h.ah = 1; | |
4476 inregs.x.cx = outside_cursor; | |
4477 int86 (0x10, &inregs, &outregs); | |
4478 } | |
4479 #endif | |
4314 | 4480 |
4315 return (setmode (fileno (stdin), stdin_stat) != -1); | 4481 return (setmode (fileno (stdin), stdin_stat) != -1); |
4316 | 4482 |
4317 #else /* not __DJGPP__ >= 2 */ | 4483 #else /* not __DJGPP__ >= 2 */ |
4318 | 4484 |
4902 /* The following three are from xfns.c: */ | 5068 /* The following three are from xfns.c: */ |
4903 Qbackground_color = intern ("background-color"); | 5069 Qbackground_color = intern ("background-color"); |
4904 staticpro (&Qbackground_color); | 5070 staticpro (&Qbackground_color); |
4905 Qforeground_color = intern ("foreground-color"); | 5071 Qforeground_color = intern ("foreground-color"); |
4906 staticpro (&Qforeground_color); | 5072 staticpro (&Qforeground_color); |
5073 Qbar = intern ("bar"); | |
5074 staticpro (&Qbar); | |
5075 Qcursor_type = intern ("cursor-type"); | |
5076 staticpro (&Qcursor_type); | |
5077 Qreverse = intern ("reverse"); | |
5078 staticpro (&Qreverse); | |
4907 | 5079 |
4908 DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph, | 5080 DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph, |
4909 "*Glyph to display instead of chars not supported by current codepage.\n\ | 5081 "*Glyph to display instead of chars not supported by current codepage.\n\ |
4910 | 5082 |
4911 This variable is used only by MSDOS terminals."); | 5083 This variable is used only by MSDOS terminals."); |