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."); |
