diff options
| author | Eli Zaretskii | 1997-11-10 14:49:40 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 1997-11-10 14:49:40 +0000 |
| commit | 039274cfc010c8d1466d78855aa1cba2b321c01e (patch) | |
| tree | 74a4c53c13abaead1abb3bb69c7a8911859c9274 /src/msdos.c | |
| parent | 9913653ae64fb7c178c5ab1ee477fb6b6a62399d (diff) | |
| download | emacs-039274cfc010c8d1466d78855aa1cba2b321c01e.tar.gz emacs-039274cfc010c8d1466d78855aa1cba2b321c01e.zip | |
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.
Diffstat (limited to 'src/msdos.c')
| -rw-r--r-- | src/msdos.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/src/msdos.c b/src/msdos.c index 9bd5e2dd6d2..5e9b9a1253c 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -308,6 +308,31 @@ struct x_output the_only_x_display; | |||
| 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; |
| @@ -316,6 +341,8 @@ dos_direct_output (y, x, buf, len) | |||
| 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) { |
| @@ -326,6 +353,9 @@ dos_direct_output (y, x, buf, len) | |||
| 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 |
| @@ -542,6 +572,11 @@ dos_set_window_size (rows, cols) | |||
| 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, |
| @@ -604,6 +639,7 @@ IT_write_glyphs (GLYPH *str, int len) | |||
| 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 | ||
| @@ -624,8 +660,9 @@ IT_write_glyphs (GLYPH *str, int len) | |||
| 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 | ||
| @@ -634,6 +671,7 @@ 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) |
| @@ -648,8 +686,9 @@ IT_clear_end_of_line (first_unused) | |||
| 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 |
| @@ -660,6 +699,8 @@ IT_clear_screen (void) | |||
| 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 | ||
| @@ -700,6 +741,8 @@ IT_display_cursor (int on) | |||
| 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 |
| @@ -824,12 +867,40 @@ IT_set_terminal_modes (void) | |||
| 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 | } |
| @@ -877,6 +948,8 @@ IT_reset_terminal_modes (void) | |||
| 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; |
| @@ -890,6 +963,9 @@ IT_reset_terminal_modes (void) | |||
| 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 | } |
| @@ -899,6 +975,9 @@ IT_reset_terminal_modes (void) | |||
| 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; |
| @@ -1031,7 +1110,10 @@ internal_terminal_init () | |||
| 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 */ |
| @@ -1086,7 +1168,7 @@ dos_get_saved_screen (screen, rows, cols) | |||
| 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 |
| @@ -2231,6 +2313,8 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 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]) |
| @@ -2266,6 +2350,8 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 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 */ |
| @@ -3443,6 +3529,10 @@ abort () | |||
| 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"); |