Mercurial > emacs
changeset 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 | 5bf13ca1dbac |
children | 25b1541c8219 |
files | src/msdos.c |
diffstat | 1 files changed, 97 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/msdos.c Mon Nov 10 12:37:34 1997 +0000 +++ b/src/msdos.c Mon Nov 10 14:49:40 1997 +0000 @@ -308,6 +308,31 @@ /* This is never dereferenced. */ Display *x_current_display; +/* Support for DOS/V (allows Japanese characters to be displayed on + standard, non-Japanese, ATs). Only supported for DJGPP v2 and later. */ + +/* Holds the address of the text-mode screen buffer. */ +static unsigned long screen_old_address = 0; +/* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ +static unsigned short screen_virtual_segment = 0; +static unsigned short screen_virtual_offset = 0; + +#if __DJGPP__ > 1 +/* Update the screen from a part of relocated DOS/V screen buffer which + begins at OFFSET and includes COUNT characters. */ +static void +dosv_refresh_virtual_screen (int offset, int count) +{ + __dpmi_regs regs; + + regs.h.ah = 0xff; /* update relocated screen */ + regs.x.es = screen_virtual_segment; + regs.x.di = screen_virtual_offset + offset; + regs.x.cx = count; + __dpmi_int (0x10, ®s); +} +#endif + static dos_direct_output (y, x, buf, len) int y; @@ -316,6 +341,8 @@ int len; { int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); + int t0 = t; + int l0 = len; #if (__DJGPP__ < 2) while (--len >= 0) { @@ -326,6 +353,9 @@ /* This is faster. */ for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++) _farnspokeb (t, *buf); + + if (screen_virtual_segment) + dosv_refresh_virtual_screen (t0, l0); #endif } #endif @@ -542,6 +572,11 @@ /* Enable bright background colors. */ bright_bg (); + + /* FIXME: I'm not sure the above will run at all on DOS/V. But let's + be defensive anyway. */ + if (screen_virtual_segment) + dosv_refresh_virtual_screen (0, *cols * *rows); } /* If we write a character in the position where the mouse is, @@ -604,6 +639,7 @@ int newface; int ch, l = len; unsigned char *buf, *bp; + int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); if (len == 0) return; @@ -624,8 +660,9 @@ } mouse_off_maybe (); - dosmemput (buf, 2 * len, - (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); + dosmemput (buf, 2 * len, (int)ScreenPrimary + offset); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (offset, len); new_pos_X += len; } @@ -634,6 +671,7 @@ { char *spaces, *sp; int i, j; + int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); IT_set_face (0); if (termscript) @@ -648,8 +686,9 @@ } mouse_off_maybe (); - dosmemput (spaces, i, - (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); + dosmemput (spaces, i, (int)ScreenPrimary + offset); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (offset, i / 2); } static @@ -660,6 +699,8 @@ IT_set_face (0); mouse_off (); ScreenClear (); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (0, screen_size); new_pos_X = new_pos_Y = 0; } @@ -700,6 +741,8 @@ ScreenSetCursor (-1, -1); cursor_cleared = 1; } + if (screen_virtual_segment) + dosv_refresh_virtual_screen (2 * (current_pos_X + screen_size_X * current_pos_Y), 1); } /* Emacs calls cursor-movement functions a lot when it updates the @@ -824,12 +867,40 @@ startup_screen_size_Y = screen_size_Y; startup_screen_attrib = ScreenAttrib; +#if __DJGPP__ > 1 + /* Is DOS/V (or any other RSIS software which relocates + the screen) installed? */ + { + unsigned short es_value; + __dpmi_regs regs; + + regs.h.ah = 0xfe; /* get relocated screen address */ + if (ScreenPrimary == 0xb0000UL || ScreenPrimary == 0xb8000UL) + regs.x.es = (ScreenPrimary >> 4) & 0xffff; + else if (screen_old_address) /* already switched to Japanese mode once */ + regs.x.es = (screen_old_address >> 4) & 0xffff; + else + regs.x.es = ScreenMode () == 7 ? 0xb000 : 0xb800; + regs.x.di = 0; + es_value = regs.x.es; + __dpmi_int (0x10, ®s); + + if (regs.x.es != es_value && regs.x.es != (ScreenPrimary >> 4) & 0xffff) + { + screen_old_address = ScreenPrimary; + screen_virtual_segment = regs.x.es; + screen_virtual_offset = regs.x.di; + ScreenPrimary = (screen_virtual_segment << 4) + screen_virtual_offset; + } + } +#endif /* __DJGPP__ > 1 */ + ScreenGetCursor (&startup_pos_Y, &startup_pos_X); ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2)); if (termscript) fprintf (termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n", - screen_size_X, screen_size_Y); + screen_size_X, screen_size_Y); bright_bg (); } @@ -877,6 +948,8 @@ ScreenAttrib = startup_screen_attrib; ScreenClear (); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (0, screen_size); if (update_row_len > saved_row_len) update_row_len = saved_row_len; @@ -890,6 +963,9 @@ while (current_rows--) { dosmemput (saved_row, update_row_len, display_row_start); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (display_row_start - ScreenPrimary, + update_row_len / 2); saved_row += saved_row_len; display_row_start += to_next_row; } @@ -899,6 +975,9 @@ cursor_pos_Y = startup_pos_Y; ScreenSetCursor (cursor_pos_Y, cursor_pos_X); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (2*(cursor_pos_X+cursor_pos_Y*screen_size_X), + 1); xfree (startup_screen_buffer); term_setup_done = 0; @@ -1031,7 +1110,10 @@ Vwindow_system = intern ("pc"); Vwindow_system_version = make_number (1); - + + /* If Emacs was dumped on DOS/V machine, forget the stale VRAM address. */ + screen_old_address = 0; + bzero (&the_only_x_display, sizeof the_only_x_display); the_only_x_display.background_pixel = 7; /* White */ the_only_x_display.foreground_pixel = 0; /* Black */ @@ -1086,7 +1168,7 @@ *screen = startup_screen_buffer; *cols = startup_screen_size_X; *rows = startup_screen_size_Y; - return 1; + return *screen != (char *)0; #else return 0; #endif @@ -2231,6 +2313,8 @@ statecount--; mouse_off (); ScreenUpdate (state[statecount].screen_behind); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (0, screen_size); xfree (state[statecount].screen_behind); } if (i == statecount - 1 && state[i].menu->submenu[dy]) @@ -2266,6 +2350,8 @@ mouse_off (); ScreenUpdate (state[0].screen_behind); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (0, screen_size); while (statecount--) xfree (state[statecount].screen_behind); IT_display_cursor (1); /* turn cursor back on */ @@ -3443,6 +3529,10 @@ ScreenSetCursor (10, 0); cputs ("\r\n\nEmacs aborted!\r\n"); #if __DJGPP__ > 1 +#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 + if (screen_virtual_segment) + dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X); +#endif /* __DJGPP_MINOR__ < 2 */ /* Generate traceback, so we could tell whodunit. */ signal (SIGINT, SIG_DFL); __asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception");