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, &regs);
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, &regs);
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);