Mercurial > emacs
comparison src/msdos.c @ 20240:963e9cda8f04
Support for Japanese display on DOS/V systems.
(screen_old_address, screen_virtual_segment,
screen_virtual_offset): New variables.
(dosv_refresh_virtual_screen): New function.
(dos_direct_output, dos_set_window_size, IT_write_glyphs,
IT_clear_end_of_line, IT_clear_screen, IT_display_cursor,
IT_reset_terminal_modes, XMenuActivate, abort): Call
dosv_refresh_virtual_screen if under DOS/V.
(IT_set_terminal_modes): If under DOS/V, update the address of
primary screen buffer.
(internal_terminal_init): Zero out screen_old_address, in case
Emacs was dumped under DOS/V.
(dos_get_saved_screen): Return failure indication if no screen was
saved.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Mon, 10 Nov 1997 14:49:40 +0000 |
parents | 65c394bb8b17 |
children | e6d49d55ea7e |
comparison
equal
deleted
inserted
replaced
20239:5bf13ca1dbac | 20240:963e9cda8f04 |
---|---|
306 struct x_output the_only_x_display; | 306 struct x_output the_only_x_display; |
307 | 307 |
308 /* This is never dereferenced. */ | 308 /* This is never dereferenced. */ |
309 Display *x_current_display; | 309 Display *x_current_display; |
310 | 310 |
311 /* Support for DOS/V (allows Japanese characters to be displayed on | |
312 standard, non-Japanese, ATs). Only supported for DJGPP v2 and later. */ | |
313 | |
314 /* Holds the address of the text-mode screen buffer. */ | |
315 static unsigned long screen_old_address = 0; | |
316 /* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ | |
317 static unsigned short screen_virtual_segment = 0; | |
318 static unsigned short screen_virtual_offset = 0; | |
319 | |
320 #if __DJGPP__ > 1 | |
321 /* Update the screen from a part of relocated DOS/V screen buffer which | |
322 begins at OFFSET and includes COUNT characters. */ | |
323 static void | |
324 dosv_refresh_virtual_screen (int offset, int count) | |
325 { | |
326 __dpmi_regs regs; | |
327 | |
328 regs.h.ah = 0xff; /* update relocated screen */ | |
329 regs.x.es = screen_virtual_segment; | |
330 regs.x.di = screen_virtual_offset + offset; | |
331 regs.x.cx = count; | |
332 __dpmi_int (0x10, ®s); | |
333 } | |
334 #endif | |
335 | |
311 static | 336 static |
312 dos_direct_output (y, x, buf, len) | 337 dos_direct_output (y, x, buf, len) |
313 int y; | 338 int y; |
314 int x; | 339 int x; |
315 char *buf; | 340 char *buf; |
316 int len; | 341 int len; |
317 { | 342 { |
318 int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); | 343 int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); |
344 int t0 = t; | |
345 int l0 = len; | |
319 | 346 |
320 #if (__DJGPP__ < 2) | 347 #if (__DJGPP__ < 2) |
321 while (--len >= 0) { | 348 while (--len >= 0) { |
322 dosmemput (buf++, 1, t); | 349 dosmemput (buf++, 1, t); |
323 t += 2; | 350 t += 2; |
324 } | 351 } |
325 #else | 352 #else |
326 /* This is faster. */ | 353 /* This is faster. */ |
327 for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++) | 354 for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++) |
328 _farnspokeb (t, *buf); | 355 _farnspokeb (t, *buf); |
356 | |
357 if (screen_virtual_segment) | |
358 dosv_refresh_virtual_screen (t0, l0); | |
329 #endif | 359 #endif |
330 } | 360 } |
331 #endif | 361 #endif |
332 | 362 |
333 /* Flash the screen as a substitute for BEEPs. */ | 363 /* Flash the screen as a substitute for BEEPs. */ |
540 *rows = ScreenRows (); | 570 *rows = ScreenRows (); |
541 *cols = ScreenCols (); | 571 *cols = ScreenCols (); |
542 | 572 |
543 /* Enable bright background colors. */ | 573 /* Enable bright background colors. */ |
544 bright_bg (); | 574 bright_bg (); |
575 | |
576 /* FIXME: I'm not sure the above will run at all on DOS/V. But let's | |
577 be defensive anyway. */ | |
578 if (screen_virtual_segment) | |
579 dosv_refresh_virtual_screen (0, *cols * *rows); | |
545 } | 580 } |
546 | 581 |
547 /* If we write a character in the position where the mouse is, | 582 /* If we write a character in the position where the mouse is, |
548 the mouse cursor may need to be refreshed. */ | 583 the mouse cursor may need to be refreshed. */ |
549 | 584 |
602 IT_write_glyphs (GLYPH *str, int len) | 637 IT_write_glyphs (GLYPH *str, int len) |
603 { | 638 { |
604 int newface; | 639 int newface; |
605 int ch, l = len; | 640 int ch, l = len; |
606 unsigned char *buf, *bp; | 641 unsigned char *buf, *bp; |
642 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); | |
607 | 643 |
608 if (len == 0) return; | 644 if (len == 0) return; |
609 | 645 |
610 buf = bp = alloca (len * 2); | 646 buf = bp = alloca (len * 2); |
611 | 647 |
622 fputc (ch, termscript); | 658 fputc (ch, termscript); |
623 str++; | 659 str++; |
624 } | 660 } |
625 | 661 |
626 mouse_off_maybe (); | 662 mouse_off_maybe (); |
627 dosmemput (buf, 2 * len, | 663 dosmemput (buf, 2 * len, (int)ScreenPrimary + offset); |
628 (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); | 664 if (screen_virtual_segment) |
665 dosv_refresh_virtual_screen (offset, len); | |
629 new_pos_X += len; | 666 new_pos_X += len; |
630 } | 667 } |
631 | 668 |
632 static | 669 static |
633 IT_clear_end_of_line (first_unused) | 670 IT_clear_end_of_line (first_unused) |
634 { | 671 { |
635 char *spaces, *sp; | 672 char *spaces, *sp; |
636 int i, j; | 673 int i, j; |
674 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); | |
637 | 675 |
638 IT_set_face (0); | 676 IT_set_face (0); |
639 if (termscript) | 677 if (termscript) |
640 fprintf (termscript, "<CLR:EOL>"); | 678 fprintf (termscript, "<CLR:EOL>"); |
641 i = (j = screen_size_X - new_pos_X) * 2; | 679 i = (j = screen_size_X - new_pos_X) * 2; |
646 *sp++ = ' '; | 684 *sp++ = ' '; |
647 *sp++ = ScreenAttrib; | 685 *sp++ = ScreenAttrib; |
648 } | 686 } |
649 | 687 |
650 mouse_off_maybe (); | 688 mouse_off_maybe (); |
651 dosmemput (spaces, i, | 689 dosmemput (spaces, i, (int)ScreenPrimary + offset); |
652 (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); | 690 if (screen_virtual_segment) |
691 dosv_refresh_virtual_screen (offset, i / 2); | |
653 } | 692 } |
654 | 693 |
655 static | 694 static |
656 IT_clear_screen (void) | 695 IT_clear_screen (void) |
657 { | 696 { |
658 if (termscript) | 697 if (termscript) |
659 fprintf (termscript, "<CLR:SCR>"); | 698 fprintf (termscript, "<CLR:SCR>"); |
660 IT_set_face (0); | 699 IT_set_face (0); |
661 mouse_off (); | 700 mouse_off (); |
662 ScreenClear (); | 701 ScreenClear (); |
702 if (screen_virtual_segment) | |
703 dosv_refresh_virtual_screen (0, screen_size); | |
663 new_pos_X = new_pos_Y = 0; | 704 new_pos_X = new_pos_Y = 0; |
664 } | 705 } |
665 | 706 |
666 static | 707 static |
667 IT_clear_to_end (void) | 708 IT_clear_to_end (void) |
698 else if (!on && !cursor_cleared) | 739 else if (!on && !cursor_cleared) |
699 { | 740 { |
700 ScreenSetCursor (-1, -1); | 741 ScreenSetCursor (-1, -1); |
701 cursor_cleared = 1; | 742 cursor_cleared = 1; |
702 } | 743 } |
744 if (screen_virtual_segment) | |
745 dosv_refresh_virtual_screen (2 * (current_pos_X + screen_size_X * current_pos_Y), 1); | |
703 } | 746 } |
704 | 747 |
705 /* Emacs calls cursor-movement functions a lot when it updates the | 748 /* Emacs calls cursor-movement functions a lot when it updates the |
706 display (probably a legacy of old terminals where you cannot | 749 display (probably a legacy of old terminals where you cannot |
707 update a screen line without first moving the cursor there). | 750 update a screen line without first moving the cursor there). |
822 | 865 |
823 startup_screen_size_X = screen_size_X; | 866 startup_screen_size_X = screen_size_X; |
824 startup_screen_size_Y = screen_size_Y; | 867 startup_screen_size_Y = screen_size_Y; |
825 startup_screen_attrib = ScreenAttrib; | 868 startup_screen_attrib = ScreenAttrib; |
826 | 869 |
870 #if __DJGPP__ > 1 | |
871 /* Is DOS/V (or any other RSIS software which relocates | |
872 the screen) installed? */ | |
873 { | |
874 unsigned short es_value; | |
875 __dpmi_regs regs; | |
876 | |
877 regs.h.ah = 0xfe; /* get relocated screen address */ | |
878 if (ScreenPrimary == 0xb0000UL || ScreenPrimary == 0xb8000UL) | |
879 regs.x.es = (ScreenPrimary >> 4) & 0xffff; | |
880 else if (screen_old_address) /* already switched to Japanese mode once */ | |
881 regs.x.es = (screen_old_address >> 4) & 0xffff; | |
882 else | |
883 regs.x.es = ScreenMode () == 7 ? 0xb000 : 0xb800; | |
884 regs.x.di = 0; | |
885 es_value = regs.x.es; | |
886 __dpmi_int (0x10, ®s); | |
887 | |
888 if (regs.x.es != es_value && regs.x.es != (ScreenPrimary >> 4) & 0xffff) | |
889 { | |
890 screen_old_address = ScreenPrimary; | |
891 screen_virtual_segment = regs.x.es; | |
892 screen_virtual_offset = regs.x.di; | |
893 ScreenPrimary = (screen_virtual_segment << 4) + screen_virtual_offset; | |
894 } | |
895 } | |
896 #endif /* __DJGPP__ > 1 */ | |
897 | |
827 ScreenGetCursor (&startup_pos_Y, &startup_pos_X); | 898 ScreenGetCursor (&startup_pos_Y, &startup_pos_X); |
828 ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2)); | 899 ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2)); |
829 | 900 |
830 if (termscript) | 901 if (termscript) |
831 fprintf (termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n", | 902 fprintf (termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n", |
832 screen_size_X, screen_size_Y); | 903 screen_size_X, screen_size_Y); |
833 | 904 |
834 bright_bg (); | 905 bright_bg (); |
835 } | 906 } |
836 | 907 |
837 /* IT_reset_terminal_modes is called when emacs is | 908 /* IT_reset_terminal_modes is called when emacs is |
875 the current) with the color attribute saved at startup. The cursor | 946 the current) with the color attribute saved at startup. The cursor |
876 is also restored within the visible dimensions. */ | 947 is also restored within the visible dimensions. */ |
877 | 948 |
878 ScreenAttrib = startup_screen_attrib; | 949 ScreenAttrib = startup_screen_attrib; |
879 ScreenClear (); | 950 ScreenClear (); |
951 if (screen_virtual_segment) | |
952 dosv_refresh_virtual_screen (0, screen_size); | |
880 | 953 |
881 if (update_row_len > saved_row_len) | 954 if (update_row_len > saved_row_len) |
882 update_row_len = saved_row_len; | 955 update_row_len = saved_row_len; |
883 if (current_rows > startup_screen_size_Y) | 956 if (current_rows > startup_screen_size_Y) |
884 current_rows = startup_screen_size_Y; | 957 current_rows = startup_screen_size_Y; |
888 update_row_len / 2, current_rows); | 961 update_row_len / 2, current_rows); |
889 | 962 |
890 while (current_rows--) | 963 while (current_rows--) |
891 { | 964 { |
892 dosmemput (saved_row, update_row_len, display_row_start); | 965 dosmemput (saved_row, update_row_len, display_row_start); |
966 if (screen_virtual_segment) | |
967 dosv_refresh_virtual_screen (display_row_start - ScreenPrimary, | |
968 update_row_len / 2); | |
893 saved_row += saved_row_len; | 969 saved_row += saved_row_len; |
894 display_row_start += to_next_row; | 970 display_row_start += to_next_row; |
895 } | 971 } |
896 if (startup_pos_X < cursor_pos_X) | 972 if (startup_pos_X < cursor_pos_X) |
897 cursor_pos_X = startup_pos_X; | 973 cursor_pos_X = startup_pos_X; |
898 if (startup_pos_Y < cursor_pos_Y) | 974 if (startup_pos_Y < cursor_pos_Y) |
899 cursor_pos_Y = startup_pos_Y; | 975 cursor_pos_Y = startup_pos_Y; |
900 | 976 |
901 ScreenSetCursor (cursor_pos_Y, cursor_pos_X); | 977 ScreenSetCursor (cursor_pos_Y, cursor_pos_X); |
978 if (screen_virtual_segment) | |
979 dosv_refresh_virtual_screen (2*(cursor_pos_X+cursor_pos_Y*screen_size_X), | |
980 1); | |
902 xfree (startup_screen_buffer); | 981 xfree (startup_screen_buffer); |
903 | 982 |
904 term_setup_done = 0; | 983 term_setup_done = 0; |
905 } | 984 } |
906 | 985 |
1029 return; | 1108 return; |
1030 } | 1109 } |
1031 | 1110 |
1032 Vwindow_system = intern ("pc"); | 1111 Vwindow_system = intern ("pc"); |
1033 Vwindow_system_version = make_number (1); | 1112 Vwindow_system_version = make_number (1); |
1034 | 1113 |
1114 /* If Emacs was dumped on DOS/V machine, forget the stale VRAM address. */ | |
1115 screen_old_address = 0; | |
1116 | |
1035 bzero (&the_only_x_display, sizeof the_only_x_display); | 1117 bzero (&the_only_x_display, sizeof the_only_x_display); |
1036 the_only_x_display.background_pixel = 7; /* White */ | 1118 the_only_x_display.background_pixel = 7; /* White */ |
1037 the_only_x_display.foreground_pixel = 0; /* Black */ | 1119 the_only_x_display.foreground_pixel = 0; /* Black */ |
1038 bright_bg (); | 1120 bright_bg (); |
1039 colors = getenv ("EMACSCOLORS"); | 1121 colors = getenv ("EMACSCOLORS"); |
1084 { | 1166 { |
1085 #ifndef HAVE_X_WINDOWS | 1167 #ifndef HAVE_X_WINDOWS |
1086 *screen = startup_screen_buffer; | 1168 *screen = startup_screen_buffer; |
1087 *cols = startup_screen_size_X; | 1169 *cols = startup_screen_size_X; |
1088 *rows = startup_screen_size_Y; | 1170 *rows = startup_screen_size_Y; |
1089 return 1; | 1171 return *screen != (char *)0; |
1090 #else | 1172 #else |
1091 return 0; | 1173 return 0; |
1092 #endif | 1174 #endif |
1093 } | 1175 } |
1094 | 1176 |
2229 while (i != statecount - 1) | 2311 while (i != statecount - 1) |
2230 { | 2312 { |
2231 statecount--; | 2313 statecount--; |
2232 mouse_off (); | 2314 mouse_off (); |
2233 ScreenUpdate (state[statecount].screen_behind); | 2315 ScreenUpdate (state[statecount].screen_behind); |
2316 if (screen_virtual_segment) | |
2317 dosv_refresh_virtual_screen (0, screen_size); | |
2234 xfree (state[statecount].screen_behind); | 2318 xfree (state[statecount].screen_behind); |
2235 } | 2319 } |
2236 if (i == statecount - 1 && state[i].menu->submenu[dy]) | 2320 if (i == statecount - 1 && state[i].menu->submenu[dy]) |
2237 { | 2321 { |
2238 IT_menu_display (state[i].menu, | 2322 IT_menu_display (state[i].menu, |
2264 } | 2348 } |
2265 } | 2349 } |
2266 | 2350 |
2267 mouse_off (); | 2351 mouse_off (); |
2268 ScreenUpdate (state[0].screen_behind); | 2352 ScreenUpdate (state[0].screen_behind); |
2353 if (screen_virtual_segment) | |
2354 dosv_refresh_virtual_screen (0, screen_size); | |
2269 while (statecount--) | 2355 while (statecount--) |
2270 xfree (state[statecount].screen_behind); | 2356 xfree (state[statecount].screen_behind); |
2271 IT_display_cursor (1); /* turn cursor back on */ | 2357 IT_display_cursor (1); /* turn cursor back on */ |
2272 return result; | 2358 return result; |
2273 } | 2359 } |
3441 { | 3527 { |
3442 dos_ttcooked (); | 3528 dos_ttcooked (); |
3443 ScreenSetCursor (10, 0); | 3529 ScreenSetCursor (10, 0); |
3444 cputs ("\r\n\nEmacs aborted!\r\n"); | 3530 cputs ("\r\n\nEmacs aborted!\r\n"); |
3445 #if __DJGPP__ > 1 | 3531 #if __DJGPP__ > 1 |
3532 #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 | |
3533 if (screen_virtual_segment) | |
3534 dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X); | |
3535 #endif /* __DJGPP_MINOR__ < 2 */ | |
3446 /* Generate traceback, so we could tell whodunit. */ | 3536 /* Generate traceback, so we could tell whodunit. */ |
3447 signal (SIGINT, SIG_DFL); | 3537 signal (SIGINT, SIG_DFL); |
3448 __asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception"); | 3538 __asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception"); |
3449 #endif | 3539 #endif |
3450 exit (2); | 3540 exit (2); |