1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20
21
22
23
24
25
26 #include <config.h>
27
28 #ifdef MSDOS
29 #include <setjmp.h>
30 #include "lisp.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <time.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <dos.h>
37 #include <errno.h>
38 #include <string.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 #include <dir.h>
42 #pragma pack(0)
43 #include <fcntl.h>
44 #include <io.h>
45 #include <dpmi.h>
46 #include <sys/farptr.h>
47 #include <libc/dosio.h>
48 #include <conio.h>
49
50 #include "msdos.h"
51 #include "systime.h"
52 #include "frame.h"
53 #include "termhooks.h"
54 #include "termchar.h"
55 #include "dispextern.h"
56 #include "dosfns.h"
57 #include "termopts.h"
58 #include "character.h"
59 #include "coding.h"
60 #include "disptab.h"
61 #include "window.h"
62 #include "buffer.h"
63 #include "commands.h"
64 #include "blockinput.h"
65 #include "keyboard.h"
66 #include "intervals.h"
67 #include <go32.h>
68 #include <pc.h>
69 #include <ctype.h>
70
71
72 #define P_WAIT 1
73
74 #ifndef _USE_LFN
75 #define _USE_LFN 0
76 #endif
77
78 #ifndef _dos_ds
79 #define _dos_ds _go32_info_block.selector_for_linear_memory
80 #endif
81
82 #include <signal.h>
83 #include "syssignal.h"
84
85 #ifndef SYSTEM_MALLOC
86
87 #ifdef GNU_MALLOC
88
89 90 91 92
93 #include <crt0.h>
94
95 #ifdef REL_ALLOC
96 int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
97 #else
98 int _crt0_startup_flags = (_CRT0_FLAG_UNIX_SBRK | _CRT0_FLAG_FILL_SBRK_MEMORY);
99 #endif
100 #endif
101
102 #endif
103
104 static unsigned long
105 event_timestamp ()
106 {
107 struct time t;
108 unsigned long s;
109
110 gettime (&t);
111 s = t.ti_min;
112 s *= 60;
113 s += t.ti_sec;
114 s *= 1000;
115 s += t.ti_hund * 10;
116
117 return s;
118 }
119
120
121 122 123 124 125
126
127 128
129 #define NUM_MOUSE_BUTTONS (5)
130
131 int have_mouse;
132 static int mouse_visible;
133
134 static int mouse_last_x;
135 static int mouse_last_y;
136
137 static int mouse_button_translate[NUM_MOUSE_BUTTONS];
138 static int mouse_button_count;
139
140 void
141 mouse_on ()
142 {
143 union REGS regs;
144
145 if (have_mouse > 0 && !mouse_visible)
146 {
147 struct tty_display_info *tty = CURTTY ();
148
149 if (tty->termscript)
150 fprintf (tty->termscript, "<M_ON>");
151 regs.x.ax = 0x0001;
152 int86 (0x33, ®s, ®s);
153 mouse_visible = 1;
154 }
155 }
156
157 void
158 mouse_off ()
159 {
160 union REGS regs;
161
162 if (have_mouse > 0 && mouse_visible)
163 {
164 struct tty_display_info *tty = CURTTY ();
165
166 if (tty->termscript)
167 fprintf (tty->termscript, "<M_OFF>");
168 regs.x.ax = 0x0002;
169 int86 (0x33, ®s, ®s);
170 mouse_visible = 0;
171 }
172 }
173
174 static void
175 mouse_setup_buttons (int n_buttons)
176 {
177 if (n_buttons == 3)
178 {
179 mouse_button_count = 3;
180 mouse_button_translate[0] = 0;
181 mouse_button_translate[1] = 2;
182 mouse_button_translate[2] = 1;
183 }
184 else
185 {
186 mouse_button_count = 2;
187 mouse_button_translate[0] = 0;
188 mouse_button_translate[1] = 1;
189 }
190 }
191
192 DEFUN ("msdos-set-mouse-buttons", Fmsdos_set_mouse_buttons, Smsdos_set_mouse_buttons,
193 1, 1, "NSet number of mouse buttons to: ",
194 doc: 195 196 197 )
198 (nbuttons)
199 Lisp_Object nbuttons;
200 {
201 int n;
202
203 CHECK_NUMBER (nbuttons);
204 n = XINT (nbuttons);
205 if (n < 2 || n > 3)
206 xsignal2 (Qargs_out_of_range,
207 build_string ("only 2 or 3 mouse buttons are supported"),
208 nbuttons);
209 mouse_setup_buttons (n);
210 return Qnil;
211 }
212
213 static void
214 mouse_get_xy (int *x, int *y)
215 {
216 union REGS regs;
217
218 regs.x.ax = 0x0003;
219 int86 (0x33, ®s, ®s);
220 *x = regs.x.cx / 8;
221 *y = regs.x.dx / 8;
222 }
223
224 void
225 mouse_moveto (x, y)
226 int x, y;
227 {
228 union REGS regs;
229 struct tty_display_info *tty = CURTTY ();
230
231 if (tty->termscript)
232 fprintf (tty->termscript, "<M_XY=%dx%d>", x, y);
233 regs.x.ax = 0x0004;
234 mouse_last_x = regs.x.cx = x * 8;
235 mouse_last_y = regs.x.dx = y * 8;
236 int86 (0x33, ®s, ®s);
237 }
238
239 static int
240 mouse_pressed (b, xp, yp)
241 int b, *xp, *yp;
242 {
243 union REGS regs;
244
245 if (b >= mouse_button_count)
246 return 0;
247 regs.x.ax = 0x0005;
248 regs.x.bx = mouse_button_translate[b];
249 int86 (0x33, ®s, ®s);
250 if (regs.x.bx)
251 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
252 return (regs.x.bx != 0);
253 }
254
255 static int
256 mouse_released (b, xp, yp)
257 int b, *xp, *yp;
258 {
259 union REGS regs;
260
261 if (b >= mouse_button_count)
262 return 0;
263 regs.x.ax = 0x0006;
264 regs.x.bx = mouse_button_translate[b];
265 int86 (0x33, ®s, ®s);
266 if (regs.x.bx)
267 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
268 return (regs.x.bx != 0);
269 }
270
271 static int
272 mouse_button_depressed (b, xp, yp)
273 int b, *xp, *yp;
274 {
275 union REGS regs;
276
277 if (b >= mouse_button_count)
278 return 0;
279 regs.x.ax = 0x0003;
280 int86 (0x33, ®s, ®s);
281 if ((regs.x.bx & (1 << mouse_button_translate[b])) != 0)
282 {
283 *xp = regs.x.cx / 8;
284 *yp = regs.x.dx / 8;
285 return 1;
286 }
287 return 0;
288 }
289
290 void
291 mouse_get_pos (f, insist, bar_window, part, x, y, time)
292 FRAME_PTR *f;
293 int insist;
294 Lisp_Object *bar_window, *x, *y;
295 enum scroll_bar_part *part;
296 unsigned long *time;
297 {
298 int ix, iy;
299 Lisp_Object frame, tail;
300
301
302 FOR_EACH_FRAME (tail, frame)
303 XFRAME (frame)->mouse_moved = 0;
304
305 *f = SELECTED_FRAME();
306 *bar_window = Qnil;
307 mouse_get_xy (&ix, &iy);
308 *time = event_timestamp ();
309 *x = make_number (mouse_last_x = ix);
310 *y = make_number (mouse_last_y = iy);
311 }
312
313 static void
314 mouse_check_moved ()
315 {
316 int x, y;
317
318 mouse_get_xy (&x, &y);
319 SELECTED_FRAME()->mouse_moved |= (x != mouse_last_x || y != mouse_last_y);
320 mouse_last_x = x;
321 mouse_last_y = y;
322 }
323
324 325
326 static void
327 mouse_clear_clicks (void)
328 {
329 int b;
330
331 for (b = 0; b < mouse_button_count; b++)
332 {
333 int dummy_x, dummy_y;
334
335 (void) mouse_pressed (b, &dummy_x, &dummy_y);
336 (void) mouse_released (b, &dummy_x, &dummy_y);
337 }
338 }
339
340 void
341 mouse_init ()
342 {
343 union REGS regs;
344 struct tty_display_info *tty = CURTTY ();
345
346 if (tty->termscript)
347 fprintf (tty->termscript, "<M_INIT>");
348
349 regs.x.ax = 0x0021;
350 int86 (0x33, ®s, ®s);
351
352 353 354 355
356 mouse_clear_clicks ();
357
358 regs.x.ax = 0x0007;
359 regs.x.cx = 0;
360 regs.x.dx = 8 * (ScreenCols () - 1);
361 int86 (0x33, ®s, ®s);
362
363 regs.x.ax = 0x0008;
364 regs.x.cx = 0;
365 regs.x.dx = 8 * (ScreenRows () - 1);
366 int86 (0x33, ®s, ®s);
367
368 mouse_moveto (0, 0);
369 mouse_visible = 0;
370 }
371
372 373 374
375
376 static int internal_terminal = 0;
377
378 #ifndef HAVE_X_WINDOWS
379 extern unsigned char ScreenAttrib;
380 static int screen_face;
381
382 static int screen_size_X;
383 static int screen_size_Y;
384 static int screen_size;
385
386 static int current_pos_X;
387 static int current_pos_Y;
388 static int new_pos_X;
389 static int new_pos_Y;
390
391 static void *startup_screen_buffer;
392 static int startup_screen_size_X;
393 static int startup_screen_size_Y;
394 static int startup_pos_X;
395 static int startup_pos_Y;
396 static unsigned char startup_screen_attrib;
397
398 static clock_t startup_time;
399
400 static int term_setup_done;
401
402 static unsigned short outside_cursor;
403
404
405 struct tty_display_info the_only_display_info;
406
407 408
409
410
411 static unsigned long screen_old_address = 0;
412
413 static unsigned short screen_virtual_segment = 0;
414 static unsigned short screen_virtual_offset = 0;
415
416 extern int unibyte_display_via_language_environment;
417
418 extern Lisp_Object Qcursor_type;
419 extern Lisp_Object Qbar, Qhbar;
420
421 422
423 static int initial_screen_colors[2];
424
425 426
427 static void
428 dosv_refresh_virtual_screen (int offset, int count)
429 {
430 __dpmi_regs regs;
431
432 if (offset < 0 || count < 0)
433 return;
434
435 regs.h.ah = 0xff;
436 regs.x.es = screen_virtual_segment;
437 regs.x.di = screen_virtual_offset + offset;
438 regs.x.cx = count;
439 __dpmi_int (0x10, ®s);
440 }
441
442 static void
443 dos_direct_output (y, x, buf, len)
444 int x, y;
445 char *buf;
446 int len;
447 {
448 int t0 = 2 * (x + y * screen_size_X);
449 int t = t0 + (int) ScreenPrimary;
450 int l0 = len;
451
452
453 for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++)
454 _farnspokeb (t, *buf);
455
456 if (screen_virtual_segment)
457 dosv_refresh_virtual_screen (t0, l0);
458 }
459 #endif
460
461 #ifndef HAVE_X_WINDOWS
462
463 static int blink_bit = -1;
464
465
466 static void
467 bright_bg (void)
468 {
469 union REGS regs;
470
471 472
473 if (blink_bit == -1)
474 blink_bit = (_farpeekb (_dos_ds, 0x465) & 0x20) == 0x20;
475
476 regs.h.bl = 0;
477 regs.x.ax = 0x1003;
478 int86 (0x10, ®s, ®s);
479 }
480
481 482
483 static void
484 maybe_enable_blinking (void)
485 {
486 if (blink_bit == 1)
487 {
488 union REGS regs;
489
490 regs.h.bl = 1;
491 regs.x.ax = 0x1003;
492 int86 (0x10, ®s, ®s);
493 }
494 }
495
496
497 static int
498 vga_installed (void)
499 {
500 union REGS regs;
501
502 regs.x.ax = 0x1a00;
503 int86 (0x10, ®s, ®s);
504 if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13)
505 return 1;
506 return 0;
507 }
508
509 510
511
512 void
513 dos_set_window_size (rows, cols)
514 int *rows, *cols;
515 {
516 char video_name[30];
517 union REGS regs;
518 Lisp_Object video_mode;
519 int video_mode_value, have_vga = 0;
520 int current_rows = ScreenRows (), current_cols = ScreenCols ();
521
522 if (*rows == current_rows && *cols == current_cols)
523 return;
524
525 mouse_off ();
526 have_vga = vga_installed ();
527
528 529
530 sprintf (video_name, "screen-dimensions-%dx%d", *rows, *cols);
531 video_mode = Fsymbol_value (Fintern_soft (build_string (video_name), Qnil));
532
533 if (INTEGERP (video_mode)
534 && (video_mode_value = XINT (video_mode)) > 0)
535 {
536 regs.x.ax = video_mode_value;
537 int86 (0x10, ®s, ®s);
538
539 if (have_mouse)
540 {
541 542 543
544 regs.x.ax = 0;
545 int86 (0x33, ®s, ®s);
546 }
547 }
548
549 550
551 else
552 {
553 static struct {
554 int rows, need_vga;
555 } std_dimension[] = {
556 {25, 0},
557 {28, 1},
558 {35, 0},
559 {40, 1},
560 {43, 0},
561 {50, 1}
562 };
563 int i = 0;
564
565 while (i < sizeof (std_dimension) / sizeof (std_dimension[0]))
566 {
567 if (std_dimension[i].need_vga <= have_vga
568 && std_dimension[i].rows >= *rows)
569 {
570 if (std_dimension[i].rows != current_rows
571 || *cols != current_cols)
572 _set_screen_lines (std_dimension[i].rows);
573 break;
574 }
575 i++;
576 }
577 }
578
579
580 if (have_mouse)
581 {
582 mouse_init ();
583 mouse_on ();
584 }
585
586
587 *rows = ScreenRows ();
588 *cols = ScreenCols ();
589
590
591 screen_size_X = *cols;
592 screen_size_Y = *rows;
593 screen_size = *cols * *rows;
594
595
596 if (current_rows != *rows || current_cols != *cols)
597 {
598 struct frame *f = SELECTED_FRAME();
599 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
600 Lisp_Object window = dpyinfo->mouse_face_window;
601
602 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
603 {
604 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
605 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
606 dpyinfo->mouse_face_window = Qnil;
607 }
608 }
609
610
611 bright_bg ();
612
613 614
615 if (screen_virtual_segment)
616 dosv_refresh_virtual_screen (0, *cols * *rows);
617 }
618
619 620
621
622 static void
623 mouse_off_maybe ()
624 {
625 int x, y;
626
627 if (!mouse_visible)
628 return;
629
630 mouse_get_xy (&x, &y);
631 if (y != new_pos_Y || x < new_pos_X)
632 return;
633
634 mouse_off ();
635 }
636
637 #define DEFAULT_CURSOR_START (-1)
638 #define DEFAULT_CURSOR_WIDTH (-1)
639 #define BOX_CURSOR_WIDTH (-32)
640
641 642 643
644 static void
645 msdos_set_cursor_shape (struct frame *f, int start_line, int width)
646 {
647 unsigned desired_cursor;
648 __dpmi_regs regs;
649 int max_line, top_line, bot_line;
650 struct tty_display_info *tty = FRAME_TTY (f);
651
652 653 654
655 if (f && f != SELECTED_FRAME())
656 return;
657
658 if (tty->termscript)
659 fprintf (tty->termscript, "\nCURSOR SHAPE=(%d,%d)", start_line, width);
660
661 662
663 max_line = _farpeekw (_dos_ds, 0x485) - 1;
664 switch (max_line)
665 {
666 default:
667 case 7:
668 bot_line = 7;
669 break;
670 case 9:
671 bot_line = 9;
672 break;
673 case 13:
674 bot_line = 12;
675 break;
676 case 15:
677 bot_line = 14;
678 break;
679 }
680
681 if (width < 0)
682 {
683 if (width == BOX_CURSOR_WIDTH)
684 {
685 top_line = 0;
686 bot_line = max_line;
687 }
688 else if (start_line != DEFAULT_CURSOR_START)
689 {
690 top_line = start_line;
691 bot_line = top_line - width - 1;
692 }
693 else if (width != DEFAULT_CURSOR_WIDTH)
694 {
695 top_line = 0;
696 bot_line = -1 - width;
697 }
698 else
699 top_line = bot_line + 1;
700 }
701 else if (width == 0)
702 {
703
704 top_line = 31;
705 bot_line = 0;
706 }
707 else
708 {
709 if (start_line != DEFAULT_CURSOR_START)
710 bot_line = start_line;
711 top_line = bot_line - (width - 1);
712 }
713
714 715
716 desired_cursor = ((top_line & 0x1f) << 8) | (bot_line & 0x1f);
717 if (desired_cursor == _farpeekw (_dos_ds, 0x460))
718 return;
719
720 regs.h.ah = 1;
721 regs.x.cx = desired_cursor;
722 __dpmi_int (0x10, ®s);
723 }
724
725 static void
726 IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type)
727 {
728 if (EQ (cursor_type, Qbar) || EQ (cursor_type, Qhbar))
729 {
730
731 msdos_set_cursor_shape (f, DEFAULT_CURSOR_START, DEFAULT_CURSOR_WIDTH);
732 }
733 else if (CONSP (cursor_type)
734 && (EQ (XCAR (cursor_type), Qbar)
735 || EQ (XCAR (cursor_type), Qhbar)))
736 {
737 Lisp_Object bar_parms = XCDR (cursor_type);
738 int width;
739
740 if (INTEGERP (bar_parms))
741 {
742 743
744 width = XINT (bar_parms);
745 msdos_set_cursor_shape (f, width >= 0 ? DEFAULT_CURSOR_START : 0,
746 width);
747 }
748 else if (CONSP (bar_parms)
749 && INTEGERP (XCAR (bar_parms))
750 && INTEGERP (XCDR (bar_parms)))
751 {
752 int start_line = XINT (XCDR (bar_parms));
753
754 width = XINT (XCAR (bar_parms));
755 msdos_set_cursor_shape (f, start_line, width);
756 }
757 }
758 else
759 {
760 761 762
763 msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH);
764 }
765 }
766
767 static void
768 IT_ring_bell (struct frame *f)
769 {
770 if (visible_bell)
771 {
772 mouse_off ();
773 ScreenVisualBell ();
774 }
775 else
776 {
777 union REGS inregs, outregs;
778 inregs.h.ah = 2;
779 inregs.h.dl = 7;
780 intdos (&inregs, &outregs);
781 }
782 }
783
784 785 786 787 788
789 static void
790 IT_set_face (int face)
791 {
792 struct frame *sf = SELECTED_FRAME();
793 struct face *fp = FACE_FROM_ID (sf, face);
794 struct face *dfp = FACE_FROM_ID (sf, DEFAULT_FACE_ID);
795 unsigned long fg, bg, dflt_fg, dflt_bg;
796 struct tty_display_info *tty = FRAME_TTY (sf);
797
798 if (!fp)
799 {
800 fp = dfp;
801 802
803 if (!fp)
804 abort ();
805 }
806 screen_face = face;
807 fg = fp->foreground;
808 bg = fp->background;
809 dflt_fg = dfp->foreground;
810 dflt_bg = dfp->background;
811
812 813 814 815
816 if (fg == FACE_TTY_DEFAULT_COLOR || fg == FACE_TTY_DEFAULT_FG_COLOR)
817 fg = FRAME_FOREGROUND_PIXEL (sf);
818 else if (fg == FACE_TTY_DEFAULT_BG_COLOR)
819 fg = FRAME_BACKGROUND_PIXEL (sf);
820 if (bg == FACE_TTY_DEFAULT_COLOR || bg == FACE_TTY_DEFAULT_BG_COLOR)
821 bg = FRAME_BACKGROUND_PIXEL (sf);
822 else if (bg == FACE_TTY_DEFAULT_FG_COLOR)
823 bg = FRAME_FOREGROUND_PIXEL (sf);
824
825
826 if (fp->tty_reverse_p && (fg == dflt_fg && bg == dflt_bg))
827 {
828 unsigned long tem = fg;
829
830 fg = bg;
831 bg = tem;
832 }
833
834 if (inverse_video)
835 {
836 unsigned long tem2 = fg;
837
838 fg = bg;
839 bg = tem2;
840 }
841 if (tty->termscript)
842 fprintf (tty->termscript, "<FACE %d: %d/%d[FG:%d/BG:%d]>", face,
843 fp->foreground, fp->background, fg, bg);
844 if (fg >= 0 && fg < 16)
845 {
846 ScreenAttrib &= 0xf0;
847 ScreenAttrib |= fg;
848 }
849 if (bg >= 0 && bg < 16)
850 {
851 ScreenAttrib &= 0x0f;
852 ScreenAttrib |= ((bg & 0x0f) << 4);
853 }
854 }
855
856 857 858
859 #define MAX_SCREEN_BUF 160*2
860
861 Lisp_Object Vdos_unsupported_char_glyph;
862 extern unsigned char *encode_terminal_code (struct glyph *, int,
863 struct coding_system *);
864 static void
865 IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
866 {
867 unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp;
868 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
869 register int sl = str_len;
870 struct tty_display_info *tty = FRAME_TTY (f);
871 struct frame *sf;
872 unsigned char *conversion_buffer;
873
874 875
876 int convert_unibyte_characters
877 = (NILP (current_buffer->enable_multibyte_characters)
878 && unibyte_display_via_language_environment);
879
880 881 882
883 struct coding_system *coding = FRAME_TERMINAL_CODING (f);
884
885 if (!(coding->common_flags & CODING_REQUIRE_ENCODING_MASK))
886 coding = &safe_terminal_coding;
887
888 if (str_len <= 0) return;
889
890 sf = SELECTED_FRAME();
891
892 893 894 895 896
897 IT_set_face (DEFAULT_FACE_ID);
898
899 900
901 coding->mode &= ~CODING_MODE_LAST_BLOCK;
902 screen_bp = &screen_buf[0];
903 while (sl > 0)
904 {
905 int cf;
906 int n;
907
908 909
910 cf = str->face_id;
911 if (cf != screen_face)
912 IT_set_face (cf);
913
914
915 for (n = 1; n < sl; ++n)
916 if (str[n].face_id != cf)
917 break;
918
919 if (n >= sl)
920
921 coding->mode |= CODING_MODE_LAST_BLOCK;
922
923 conversion_buffer = encode_terminal_code (str, n, coding);
924 if (coding->produced > 0)
925 {
926
927 for (bp = conversion_buffer; coding->produced--; bp++)
928 {
929 930
931 if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2)
932 {
933 *screen_bp++ = (unsigned char)*bp;
934 *screen_bp++ = ScreenAttrib;
935 }
936 if (tty->termscript)
937 fputc (*bp, tty->termscript);
938 }
939 }
940
941 str += n;
942 sl -= n;
943 }
944
945
946 mouse_off_maybe ();
947 dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
948 if (screen_virtual_segment)
949 dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2);
950 new_pos_X += (screen_bp - screen_buf) / 2;
951 }
952
953 954 955
956
957
958 static Lisp_Object last_mouse_window;
959
960 static int mouse_preempted = 0;
961
962 963
964 static void
965 IT_set_mouse_pointer (int mode)
966 {
967 968 969 970 971 972
973 }
974
975 976
977 static void
978 show_mouse_face (struct tty_display_info *dpyinfo, int hl)
979 {
980 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
981 struct frame *f = XFRAME (WINDOW_FRAME (w));
982 int i;
983 struct face *fp;
984 struct tty_display_info *tty = FRAME_TTY (f);
985
986
987 988
989 if (w->current_matrix == NULL)
990 goto set_cursor_shape;
991
992 993
994 if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
995 goto set_cursor_shape;
996
997
998 if (hl > 0)
999 {
1000 if (dpyinfo->mouse_face_hidden)
1001 goto set_cursor_shape;
1002
1003 fp = FACE_FROM_ID (SELECTED_FRAME(), dpyinfo->mouse_face_face_id);
1004 if (!fp)
1005 goto set_cursor_shape;
1006 }
1007
1008
1009 for (i = dpyinfo->mouse_face_beg_row;
1010 i <= dpyinfo->mouse_face_end_row;
1011 i++)
1012 {
1013 int start_hpos, end_hpos;
1014 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
1015
1016
1017 if (!row->enabled_p)
1018 continue;
1019
1020
1021 if (i == dpyinfo->mouse_face_beg_row)
1022 start_hpos = dpyinfo->mouse_face_beg_col;
1023 else
1024 start_hpos = 0;
1025
1026 if (i == dpyinfo->mouse_face_end_row)
1027 end_hpos = dpyinfo->mouse_face_end_col;
1028 else
1029 end_hpos = row->used[TEXT_AREA];
1030
1031 if (end_hpos <= start_hpos)
1032 continue;
1033 1034
1035 row->mouse_face_p = hl > 0;
1036 if (hl > 0)
1037 {
1038 int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
1039 int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
1040 int nglyphs = end_hpos - start_hpos;
1041 int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
1042 int start_offset = offset;
1043
1044 if (tty->termscript)
1045 fprintf (tty->termscript, "\n<MH+ %d-%d:%d>",
1046 kstart, kstart + nglyphs - 1, vpos);
1047
1048 mouse_off ();
1049 IT_set_face (dpyinfo->mouse_face_face_id);
1050 1051 1052 1053 1054 1055
1056 _farsetsel (_dos_ds);
1057 while (nglyphs--)
1058 {
1059 _farnspokeb (offset, ScreenAttrib);
1060 offset += 2;
1061 }
1062 if (screen_virtual_segment)
1063 dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
1064 mouse_on ();
1065 }
1066 else
1067 {
1068 1069 1070 1071
1072 int nglyphs = end_hpos - start_hpos;
1073 int save_x = new_pos_X, save_y = new_pos_Y;
1074
1075 if (end_hpos >= row->used[TEXT_AREA])
1076 nglyphs = row->used[TEXT_AREA] - start_hpos;
1077
1078 1079 1080
1081 new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
1082 new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
1083
1084 if (tty->termscript)
1085 fprintf (tty->termscript, "<MH- %d-%d:%d>",
1086 new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
1087 IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
1088 if (tty->termscript)
1089 fputs ("\n", tty->termscript);
1090 new_pos_X = save_x;
1091 new_pos_Y = save_y;
1092 }
1093 }
1094
1095 set_cursor_shape:
1096
1097 IT_set_mouse_pointer (hl);
1098 }
1099
1100 1101
1102 static void
1103 clear_mouse_face (struct tty_display_info *dpyinfo)
1104 {
1105 if (!dpyinfo->mouse_face_hidden && ! NILP (dpyinfo->mouse_face_window))
1106 show_mouse_face (dpyinfo, 0);
1107
1108 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
1109 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
1110 dpyinfo->mouse_face_window = Qnil;
1111 }
1112
1113 1114 1115 1116
1117 static int
1118 fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
1119 {
1120 int i, lastcol, line_start_position, maybe_next_line_p = 0;
1121 int yb = window_text_bottom_y (w);
1122 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
1123
1124 while (row->y < yb)
1125 {
1126 if (row->used[TEXT_AREA])
1127 line_start_position = row->glyphs[TEXT_AREA]->charpos;
1128 else
1129 line_start_position = 0;
1130
1131 if (line_start_position > pos)
1132 break;
1133 1134
1135 else if (line_start_position == pos
1136 && pos == BUF_ZV (XBUFFER (w->buffer)))
1137 {
1138 maybe_next_line_p = 1;
1139 break;
1140 }
1141 else if (line_start_position > 0)
1142 best_row = row;
1143
1144 1145
1146 if (row->y + 1 >= yb)
1147 break;
1148
1149 ++row;
1150 }
1151
1152
1153 lastcol = 0;
1154 row = best_row;
1155 for (i = 0; i < row->used[TEXT_AREA]; i++)
1156 {
1157 struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
1158 int charpos;
1159
1160 charpos = glyph->charpos;
1161 if (charpos == pos)
1162 {
1163 *hpos = i;
1164 *vpos = row->y;
1165 return 1;
1166 }
1167 else if (charpos > pos)
1168 break;
1169 else if (charpos > 0)
1170 lastcol = i;
1171 }
1172
1173 1174 1175
1176 if (maybe_next_line_p)
1177 {
1178 ++row;
1179 lastcol = 0;
1180 }
1181
1182 *vpos = row->y;
1183 *hpos = lastcol + 1;
1184 return 0;
1185 }
1186
1187 1188 1189 1190 1191
1192 static void
1193 IT_note_mode_line_highlight (struct window *w, int x, int mode_line_p)
1194 {
1195 struct frame *f = XFRAME (w->frame);
1196 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1197 struct glyph_row *row;
1198
1199 if (mode_line_p)
1200 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1201 else
1202 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1203
1204 if (row->enabled_p)
1205 {
1206 extern Lisp_Object Qhelp_echo;
1207 struct glyph *glyph, *end;
1208 Lisp_Object help, map;
1209
1210
1211 glyph = (row->glyphs[TEXT_AREA]
1212 + x
1213
1214 - WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w));
1215 end = glyph + row->used[TEXT_AREA];
1216 if (glyph < end
1217 && STRINGP (glyph->object)
1218 && STRING_INTERVALS (glyph->object)
1219 && glyph->charpos >= 0
1220 && glyph->charpos < SCHARS (glyph->object))
1221 {
1222 1223 1224
1225 help = Fget_text_property (make_number (glyph->charpos),
1226 Qhelp_echo, glyph->object);
1227 if (!NILP (help))
1228 {
1229 help_echo_string = help;
1230 XSETWINDOW (help_echo_window, w);
1231 help_echo_object = glyph->object;
1232 help_echo_pos = glyph->charpos;
1233 }
1234 }
1235 }
1236 }
1237
1238 1239 1240 1241
1242 static void
1243 IT_note_mouse_highlight (struct frame *f, int x, int y)
1244 {
1245 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1246 enum window_part part = ON_NOTHING;
1247 Lisp_Object window;
1248 struct window *w;
1249
1250
1251 if (mouse_preempted)
1252 return;
1253
1254 if (NILP (Vmouse_highlight)
1255 || !f->glyphs_initialized_p)
1256 return;
1257
1258 dpyinfo->mouse_face_mouse_x = x;
1259 dpyinfo->mouse_face_mouse_y = y;
1260 dpyinfo->mouse_face_mouse_frame = f;
1261
1262 if (dpyinfo->mouse_face_defer)
1263 return;
1264
1265 if (gc_in_progress)
1266 {
1267 dpyinfo->mouse_face_deferred_gc = 1;
1268 return;
1269 }
1270
1271
1272 window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
1273
1274
1275 if (! EQ (window, dpyinfo->mouse_face_window))
1276 clear_mouse_face (dpyinfo);
1277
1278
1279 if (!WINDOWP (window))
1280 return;
1281
1282
1283 w = XWINDOW (window);
1284
1285 if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
1286 {
1287
1288 IT_note_mode_line_highlight (w, x, part == ON_MODE_LINE);
1289 return;
1290 }
1291
1292 IT_set_mouse_pointer (0);
1293
1294 1295
1296 if (part == ON_TEXT
1297 && EQ (w->window_end_valid, w->buffer)
1298 && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
1299 && (XFASTINT (w->last_overlay_modified)
1300 == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
1301 {
1302 int pos, i, nrows = w->current_matrix->nrows;
1303 struct glyph_row *row;
1304 struct glyph *glyph;
1305
1306
1307 glyph = NULL;
1308 if (y >= 0 && y < nrows)
1309 {
1310 row = MATRIX_ROW (w->current_matrix, y);
1311 1312
1313 for (i = 0; i <= y; i++)
1314 if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
1315 break;
1316 if (i > y
1317 && row->displays_text_p
1318 && x < window_box_width (w, TEXT_AREA))
1319 {
1320 glyph = row->glyphs[TEXT_AREA];
1321 if (x >= row->used[TEXT_AREA])
1322 glyph = NULL;
1323 else
1324 {
1325 glyph += x;
1326 if (!BUFFERP (glyph->object))
1327 glyph = NULL;
1328 }
1329 }
1330 }
1331
1332
1333 if (glyph == NULL)
1334 {
1335 clear_mouse_face (dpyinfo);
1336 return;
1337 }
1338
1339 if (!BUFFERP (glyph->object))
1340 abort ();
1341 pos = glyph->charpos;
1342
1343
1344 {
1345 extern Lisp_Object Qmouse_face;
1346 Lisp_Object mouse_face, overlay, position, *overlay_vec;
1347 int noverlays, obegv, ozv;
1348 struct buffer *obuf;
1349
1350
1351 if (pos > BUF_Z (XBUFFER (w->buffer)))
1352 return;
1353
1354 1355
1356 obuf = current_buffer;
1357 current_buffer = XBUFFER (w->buffer);
1358 obegv = BEGV;
1359 ozv = ZV;
1360 BEGV = BEG;
1361 ZV = Z;
1362
1363
1364 XSETINT (position, pos);
1365
1366
1367 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
1368
1369 noverlays = sort_overlays (overlay_vec, noverlays, w);
1370
1371
1372 if (! (EQ (window, dpyinfo->mouse_face_window)
1373 && y >= dpyinfo->mouse_face_beg_row
1374 && y <= dpyinfo->mouse_face_end_row
1375 && (y > dpyinfo->mouse_face_beg_row
1376 || x >= dpyinfo->mouse_face_beg_col)
1377 && (y < dpyinfo->mouse_face_end_row
1378 || x < dpyinfo->mouse_face_end_col
1379 || dpyinfo->mouse_face_past_end)))
1380 {
1381
1382 clear_mouse_face (dpyinfo);
1383
1384
1385 overlay = Qnil;
1386 for (i = noverlays - 1; i >= 0; --i)
1387 {
1388 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
1389 if (!NILP (mouse_face))
1390 {
1391 overlay = overlay_vec[i];
1392 break;
1393 }
1394 }
1395
1396
1397 if (NILP (overlay))
1398 mouse_face = Fget_text_property (position, Qmouse_face,
1399 w->buffer);
1400
1401
1402 if (! NILP (overlay))
1403 {
1404 1405
1406 Lisp_Object before, after;
1407 EMACS_INT ignore;
1408
1409 before = Foverlay_start (overlay);
1410 after = Foverlay_end (overlay);
1411
1412 fast_find_position (w, XFASTINT (before),
1413 &dpyinfo->mouse_face_beg_col,
1414 &dpyinfo->mouse_face_beg_row);
1415 dpyinfo->mouse_face_past_end
1416 = !fast_find_position (w, XFASTINT (after),
1417 &dpyinfo->mouse_face_end_col,
1418 &dpyinfo->mouse_face_end_row);
1419 dpyinfo->mouse_face_window = window;
1420 dpyinfo->mouse_face_face_id
1421 = face_at_buffer_position (w, pos, 0, 0,
1422 &ignore, pos + 1,
1423 !dpyinfo->mouse_face_hidden,
1424 -1);
1425
1426
1427 show_mouse_face (dpyinfo, 1);
1428 }
1429
1430 else if (! NILP (mouse_face))
1431 {
1432 1433
1434 Lisp_Object before, after, beginning, end;
1435 EMACS_INT ignore;
1436
1437 beginning = Fmarker_position (w->start);
1438 XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
1439 - XFASTINT (w->window_end_pos)));
1440 before
1441 = Fprevious_single_property_change (make_number (pos + 1),
1442 Qmouse_face,
1443 w->buffer, beginning);
1444 after
1445 = Fnext_single_property_change (position, Qmouse_face,
1446 w->buffer, end);
1447
1448 fast_find_position (w, XFASTINT (before),
1449 &dpyinfo->mouse_face_beg_col,
1450 &dpyinfo->mouse_face_beg_row);
1451 dpyinfo->mouse_face_past_end
1452 = !fast_find_position (w, XFASTINT (after),
1453 &dpyinfo->mouse_face_end_col,
1454 &dpyinfo->mouse_face_end_row);
1455 dpyinfo->mouse_face_window = window;
1456 dpyinfo->mouse_face_face_id
1457 = face_at_buffer_position (w, pos, 0, 0,
1458 &ignore, pos + 1,
1459 !dpyinfo->mouse_face_hidden,
1460 -1);
1461
1462
1463 show_mouse_face (dpyinfo, 1);
1464 }
1465 }
1466
1467
1468 {
1469 Lisp_Object help;
1470 extern Lisp_Object Qhelp_echo;
1471
1472
1473 help = Qnil;
1474 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
1475 {
1476 overlay = overlay_vec[i];
1477 help = Foverlay_get (overlay, Qhelp_echo);
1478 }
1479
1480 if (!NILP (help))
1481 {
1482 help_echo_string = help;
1483 help_echo_window = window;
1484 help_echo_object = overlay;
1485 help_echo_pos = pos;
1486 }
1487
1488 else if (NILP (help)
1489 && ((STRINGP (glyph->object)
1490 && glyph->charpos >= 0
1491 && glyph->charpos < SCHARS (glyph->object))
1492 || (BUFFERP (glyph->object)
1493 && glyph->charpos >= BEGV
1494 && glyph->charpos < ZV)))
1495 {
1496 help = Fget_text_property (make_number (glyph->charpos),
1497 Qhelp_echo, glyph->object);
1498 if (!NILP (help))
1499 {
1500 help_echo_string = help;
1501 help_echo_window = window;
1502 help_echo_object = glyph->object;
1503 help_echo_pos = glyph->charpos;
1504 }
1505 }
1506 }
1507
1508 BEGV = obegv;
1509 ZV = ozv;
1510 current_buffer = obuf;
1511 }
1512 }
1513 }
1514
1515 static void
1516 IT_clear_end_of_line (struct frame *f, int first_unused)
1517 {
1518 char *spaces, *sp;
1519 int i, j, offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
1520 extern int fatal_error_in_progress;
1521 struct tty_display_info *tty = FRAME_TTY (f);
1522
1523 if (new_pos_X >= first_unused || fatal_error_in_progress)
1524 return;
1525
1526 IT_set_face (0);
1527 i = (j = first_unused - new_pos_X) * 2;
1528 if (tty->termscript)
1529 fprintf (tty->termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused);
1530 spaces = sp = alloca (i);
1531
1532 while (--j >= 0)
1533 {
1534 *sp++ = ' ';
1535 *sp++ = ScreenAttrib;
1536 }
1537
1538 mouse_off_maybe ();
1539 dosmemput (spaces, i, (int)ScreenPrimary + offset);
1540 if (screen_virtual_segment)
1541 dosv_refresh_virtual_screen (offset, i / 2);
1542
1543 1544
1545 new_pos_X = first_unused;
1546 }
1547
1548 static void
1549 IT_clear_screen (struct frame *f)
1550 {
1551 struct tty_display_info *tty = FRAME_TTY (f);
1552
1553 if (tty->termscript)
1554 fprintf (tty->termscript, "<CLR:SCR>");
1555 1556 1557 1558 1559 1560
1561 if (FACE_FROM_ID (SELECTED_FRAME (), DEFAULT_FACE_ID) == NULL)
1562 ScreenAttrib = (initial_screen_colors[0] << 4) | initial_screen_colors[1];
1563 else
1564 IT_set_face (0);
1565 mouse_off ();
1566 ScreenClear ();
1567 if (screen_virtual_segment)
1568 dosv_refresh_virtual_screen (0, screen_size);
1569 new_pos_X = new_pos_Y = 0;
1570 }
1571
1572 static void
1573 IT_clear_to_end (struct frame *f)
1574 {
1575 struct tty_display_info *tty = FRAME_TTY (f);
1576
1577 if (tty->termscript)
1578 fprintf (tty->termscript, "<CLR:EOS>");
1579
1580 while (new_pos_Y < screen_size_Y) {
1581 new_pos_X = 0;
1582 IT_clear_end_of_line (f, screen_size_X);
1583 new_pos_Y++;
1584 }
1585 }
1586
1587 static void
1588 IT_cursor_to (struct frame *f, int y, int x)
1589 {
1590 struct tty_display_info *tty = FRAME_TTY (f);
1591
1592 if (tty->termscript)
1593 fprintf (tty->termscript, "\n<XY=%dx%d>", x, y);
1594 new_pos_X = x;
1595 new_pos_Y = y;
1596 }
1597
1598 static int cursor_cleared;
1599
1600 static void
1601 IT_display_cursor (int on)
1602 {
1603 struct tty_display_info *tty = CURTTY ();
1604
1605 if (on && cursor_cleared)
1606 {
1607 ScreenSetCursor (current_pos_Y, current_pos_X);
1608 cursor_cleared = 0;
1609 if (tty->termscript)
1610 fprintf (tty->termscript, "\nCURSOR ON");
1611 }
1612 else if (!on && !cursor_cleared)
1613 {
1614 ScreenSetCursor (-1, -1);
1615 cursor_cleared = 1;
1616 if (tty->termscript)
1617 fprintf (tty->termscript, "\nCURSOR OFF");
1618 }
1619 }
1620
1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638
1639
1640 static void
1641 IT_cmgoto (FRAME_PTR f)
1642 {
1643 1644
1645 int update_cursor_pos = 1;
1646 struct tty_display_info *tty = FRAME_TTY (f);
1647
1648 1649
1650 #if 0
1651 static int previous_pos_X = -1;
1652
1653 update_cursor_pos = 1;
1654
1655 1656 1657
1658 if (update_cursor_pos && previous_pos_X >= 0)
1659 previous_pos_X = -1;
1660 1661
1662 if (!update_cursor_pos
1663 && WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f))) <= new_pos_Y)
1664 {
1665 int tem_X = current_pos_X, dummy;
1666
1667 if (echo_area_glyphs)
1668 {
1669 tem_X = echo_area_glyphs_length;
1670 1671 1672
1673 if (previous_pos_X == -1)
1674 ScreenGetCursor (&dummy, &previous_pos_X);
1675 }
1676 else if (previous_pos_X >= 0)
1677 {
1678 1679
1680 tem_X = previous_pos_X;
1681 previous_pos_X = -1;
1682 }
1683
1684 if (current_pos_X != tem_X)
1685 {
1686 new_pos_X = tem_X;
1687 update_cursor_pos = 1;
1688 }
1689 }
1690 #endif
1691
1692 if (update_cursor_pos
1693 && (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y))
1694 {
1695 ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X);
1696 if (tty->termscript)
1697 fprintf (tty->termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y);
1698 }
1699
1700
1701 IT_display_cursor (1);
1702
1703 1704
1705 if (!mouse_visible)
1706 mouse_on ();
1707 }
1708
1709 static void
1710 IT_update_begin (struct frame *f)
1711 {
1712 struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
1713 struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame;
1714
1715 if (display_info->termscript)
1716 fprintf (display_info->termscript, "\n\n<UPDATE_BEGIN");
1717
1718 BLOCK_INPUT;
1719
1720 if (f && f == mouse_face_frame)
1721 {
1722
1723 display_info->mouse_face_defer = 1;
1724
1725 1726
1727 if (FRAME_GARBAGED_P (f))
1728 display_info->mouse_face_window = Qnil;
1729
1730 1731 1732 1733
1734 if (!NILP (display_info->mouse_face_window)
1735 && WINDOWP (display_info->mouse_face_window))
1736 {
1737 struct window *w = XWINDOW (display_info->mouse_face_window);
1738 int i;
1739
1740 1741 1742
1743 if (NILP (w->buffer))
1744 display_info->mouse_face_window = Qnil;
1745 else
1746 {
1747 for (i = 0; i < w->desired_matrix->nrows; ++i)
1748 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i)
1749 && MATRIX_ROW (w->current_matrix, i)->mouse_face_p)
1750 break;
1751 }
1752
1753 if (NILP (w->buffer) || i < w->desired_matrix->nrows)
1754 clear_mouse_face (display_info);
1755 }
1756 }
1757 else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
1758 {
1759 1760
1761 display_info->mouse_face_beg_row = display_info->mouse_face_beg_col = -1;
1762 display_info->mouse_face_end_row = display_info->mouse_face_end_col = -1;
1763 display_info->mouse_face_window = Qnil;
1764 display_info->mouse_face_deferred_gc = 0;
1765 display_info->mouse_face_mouse_frame = NULL;
1766 }
1767
1768 UNBLOCK_INPUT;
1769 }
1770
1771 static void
1772 IT_update_end (struct frame *f)
1773 {
1774 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1775
1776 if (dpyinfo->termscript)
1777 fprintf (dpyinfo->termscript, "\n<UPDATE_END\n");
1778 dpyinfo->mouse_face_defer = 0;
1779 }
1780
1781 static void
1782 IT_frame_up_to_date (struct frame *f)
1783 {
1784 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1785 Lisp_Object new_cursor, frame_desired_cursor;
1786 struct window *sw;
1787
1788 if (dpyinfo->mouse_face_deferred_gc
1789 || (f && f == dpyinfo->mouse_face_mouse_frame))
1790 {
1791 BLOCK_INPUT;
1792 if (dpyinfo->mouse_face_mouse_frame)
1793 IT_note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
1794 dpyinfo->mouse_face_mouse_x,
1795 dpyinfo->mouse_face_mouse_y);
1796 dpyinfo->mouse_face_deferred_gc = 0;
1797 UNBLOCK_INPUT;
1798 }
1799
1800 1801 1802 1803 1804 1805
1806 sw = XWINDOW (f->selected_window);
1807 frame_desired_cursor = Fcdr (Fassq (Qcursor_type, f->param_alist));
1808 if (cursor_in_echo_area
1809 && FRAME_HAS_MINIBUF_P (f)
1810 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)
1811 && sw == XWINDOW (echo_area_window))
1812 new_cursor = frame_desired_cursor;
1813 else
1814 {
1815 struct buffer *b = XBUFFER (sw->buffer);
1816
1817 if (EQ (b->cursor_type, Qt))
1818 new_cursor = frame_desired_cursor;
1819 else if (NILP (b->cursor_type))
1820 new_cursor = Fcons (Qbar, make_number (0));
1821 else
1822 new_cursor = b->cursor_type;
1823 }
1824
1825 IT_set_cursor_type (f, new_cursor);
1826
1827 IT_cmgoto (f);
1828 }
1829
1830 1831 1832 1833
1834 static void
1835 IT_copy_glyphs (int xfrom, int xto, size_t len, int ypos)
1836 {
1837 1838
1839 int from = 2 * (xfrom + screen_size_X * ypos) + ScreenPrimary;
1840 int to = 2 * (xto + screen_size_X * ypos) + ScreenPrimary;
1841
1842 if (from == to || len <= 0)
1843 return;
1844
1845 _farsetsel (_dos_ds);
1846
1847 1848
1849 if (from > to)
1850 {
1851 for ( ; len; from += 2, to += 2, len--)
1852 _farnspokew (to, _farnspeekw (from));
1853 }
1854 else
1855 {
1856 from += (len - 1) * 2;
1857 to += (len - 1) * 2;
1858 for ( ; len; from -= 2, to -= 2, len--)
1859 _farnspokew (to, _farnspeekw (from));
1860 }
1861 if (screen_virtual_segment)
1862 dosv_refresh_virtual_screen (ypos * screen_size_X * 2, screen_size_X);
1863 }
1864
1865
1866 static void
1867 IT_insert_glyphs (f, start, len)
1868 struct frame *f;
1869 register struct glyph *start;
1870 register int len;
1871 {
1872 int shift_by_width = screen_size_X - (new_pos_X + len);
1873
1874 1875
1876 IT_copy_glyphs (new_pos_X, new_pos_X + len, shift_by_width, new_pos_Y);
1877
1878
1879 IT_write_glyphs (f, start, len);
1880 }
1881
1882 static void
1883 IT_delete_glyphs (f, n)
1884 struct frame *f;
1885 register int n;
1886 {
1887 abort ();
1888 }
1889
1890
1891 void
1892 x_set_menu_bar_lines (f, value, oldval)
1893 struct frame *f;
1894 Lisp_Object value, oldval;
1895 {
1896 set_menu_bar_lines (f, value, oldval);
1897 }
1898
1899
1900
1901 extern Lisp_Object Qbackground_color;
1902 extern Lisp_Object Qforeground_color;
1903 Lisp_Object Qreverse;
1904 extern Lisp_Object Qtitle;
1905
1906 1907
1908
1909 static void
1910 IT_set_terminal_modes (struct terminal *term)
1911 {
1912 struct tty_display_info *tty;
1913
1914 1915
1916 if (term->type == output_initial)
1917 return;
1918
1919 tty = term->display_info.tty;
1920
1921 if (tty->termscript)
1922 fprintf (tty->termscript, "\n<SET_TERM>");
1923
1924 screen_size_X = ScreenCols ();
1925 screen_size_Y = ScreenRows ();
1926 screen_size = screen_size_X * screen_size_Y;
1927
1928 new_pos_X = new_pos_Y = 0;
1929 current_pos_X = current_pos_Y = -1;
1930
1931 if (term_setup_done)
1932 return;
1933 term_setup_done = 1;
1934
1935 startup_screen_size_X = screen_size_X;
1936 startup_screen_size_Y = screen_size_Y;
1937 startup_screen_attrib = ScreenAttrib;
1938
1939 1940
1941 {
1942 unsigned short es_value;
1943 __dpmi_regs regs;
1944
1945 regs.h.ah = 0xfe;
1946 if (ScreenPrimary == 0xb0000UL || ScreenPrimary == 0xb8000UL)
1947 regs.x.es = (ScreenPrimary >> 4) & 0xffff;
1948 else if (screen_old_address)
1949 regs.x.es = (screen_old_address >> 4) & 0xffff;
1950 else
1951 regs.x.es = ScreenMode () == 7 ? 0xb000 : 0xb800;
1952 regs.x.di = 0;
1953 es_value = regs.x.es;
1954 __dpmi_int (0x10, ®s);
1955
1956 if (regs.x.es != es_value)
1957 {
1958 1959 1960 1961
1962 if (regs.x.es != (ScreenPrimary >> 4) & 0xffff)
1963 screen_old_address = ScreenPrimary;
1964 screen_virtual_segment = regs.x.es;
1965 screen_virtual_offset = regs.x.di;
1966 ScreenPrimary = (screen_virtual_segment << 4) + screen_virtual_offset;
1967 }
1968 }
1969
1970 ScreenGetCursor (&startup_pos_Y, &startup_pos_X);
1971 ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2));
1972
1973 bright_bg ();
1974 }
1975
1976 1977
1978
1979 static void
1980 IT_reset_terminal_modes (struct terminal *term)
1981 {
1982 int display_row_start = (int) ScreenPrimary;
1983 int saved_row_len = startup_screen_size_X * 2;
1984 int update_row_len = ScreenCols () * 2, current_rows = ScreenRows ();
1985 int to_next_row = update_row_len;
1986 unsigned char *saved_row = startup_screen_buffer;
1987 int cursor_pos_X = ScreenCols () - 1, cursor_pos_Y = ScreenRows () - 1;
1988 struct tty_display_info *tty = term->display_info.tty;
1989
1990 if (tty->termscript)
1991 fprintf (tty->termscript, "\n<RESET_TERM>");
1992
1993 if (!term_setup_done)
1994 return;
1995
1996 mouse_off ();
1997
1998 1999
2000 maybe_enable_blinking ();
2001
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
2013
2014 ScreenAttrib = startup_screen_attrib;
2015
2016 2017 2018
2019 if (clock () - startup_time >= 2*CLOCKS_PER_SEC)
2020 {
2021 ScreenClear ();
2022 if (screen_virtual_segment)
2023 dosv_refresh_virtual_screen (0, screen_size);
2024
2025 if (update_row_len > saved_row_len)
2026 update_row_len = saved_row_len;
2027 if (current_rows > startup_screen_size_Y)
2028 current_rows = startup_screen_size_Y;
2029
2030 if (tty->termscript)
2031 fprintf (tty->termscript, "<SCREEN RESTORED (dimensions=%dx%d)>\n",
2032 update_row_len / 2, current_rows);
2033
2034 while (current_rows--)
2035 {
2036 dosmemput (saved_row, update_row_len, display_row_start);
2037 if (screen_virtual_segment)
2038 dosv_refresh_virtual_screen (display_row_start - ScreenPrimary,
2039 update_row_len / 2);
2040 saved_row += saved_row_len;
2041 display_row_start += to_next_row;
2042 }
2043 }
2044 if (startup_pos_X < cursor_pos_X)
2045 cursor_pos_X = startup_pos_X;
2046 if (startup_pos_Y < cursor_pos_Y)
2047 cursor_pos_Y = startup_pos_Y;
2048
2049 ScreenSetCursor (cursor_pos_Y, cursor_pos_X);
2050 xfree (startup_screen_buffer);
2051 startup_screen_buffer = NULL;
2052
2053 term_setup_done = 0;
2054 }
2055
2056 static void
2057 IT_set_terminal_window (struct frame *f, int foo)
2058 {
2059 }
2060
2061 2062
2063 DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors,
2064 Smsdos_remember_default_colors, 1, 1, 0,
2065 doc: )
2066 (frame)
2067 Lisp_Object frame;
2068 {
2069 struct frame *f;
2070
2071 CHECK_FRAME (frame);
2072 f = XFRAME (frame);
2073
2074 2075 2076 2077
2078 initial_screen_colors[0] = FRAME_FOREGROUND_PIXEL (f);
2079 initial_screen_colors[1] = FRAME_BACKGROUND_PIXEL (f);
2080 }
2081
2082 void
2083 IT_set_frame_parameters (f, alist)
2084 struct frame *f;
2085 Lisp_Object alist;
2086 {
2087 Lisp_Object tail;
2088 int i, j, length = XINT (Flength (alist));
2089 Lisp_Object *parms
2090 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2091 Lisp_Object *values
2092 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2093
2094 int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt);
2095 int need_to_reverse, was_reverse = reverse;
2096 int redraw = 0, fg_set = 0, bg_set = 0;
2097 unsigned long orig_fg, orig_bg;
2098 Lisp_Object frame_bg, frame_fg;
2099 extern Lisp_Object Qdefault, QCforeground, QCbackground;
2100 struct tty_display_info *tty = FRAME_TTY (f);
2101
2102 2103
2104 if (EQ (alist, Vdefault_frame_alist)
2105 && initial_screen_colors[0] != -1 && initial_screen_colors[1] != -1)
2106 {
2107 FRAME_FOREGROUND_PIXEL (f) = initial_screen_colors[0];
2108 FRAME_BACKGROUND_PIXEL (f) = initial_screen_colors[1];
2109 init_frame_faces (f);
2110 }
2111 orig_fg = FRAME_FOREGROUND_PIXEL (f);
2112 orig_bg = FRAME_BACKGROUND_PIXEL (f);
2113 frame_fg = Fcdr (Fassq (Qforeground_color, f->param_alist));
2114 frame_bg = Fcdr (Fassq (Qbackground_color, f->param_alist));
2115 2116 2117
2118 if (NILP (frame_fg))
2119 frame_fg = build_string (unspecified_fg);
2120 if (NILP (frame_bg))
2121 frame_bg = build_string (unspecified_bg);
2122
2123
2124 i = 0;
2125 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2126 {
2127 Lisp_Object elt;
2128
2129 elt = Fcar (tail);
2130 parms[i] = Fcar (elt);
2131 CHECK_SYMBOL (parms[i]);
2132 values[i] = Fcdr (elt);
2133 i++;
2134 }
2135
2136 j = i;
2137
2138 for (i = 0; i < j; i++)
2139 {
2140 Lisp_Object prop, val;
2141
2142 prop = parms[i];
2143 val = values[i];
2144
2145 if (EQ (prop, Qreverse))
2146 reverse = EQ (val, Qt);
2147 }
2148
2149 need_to_reverse = reverse && !was_reverse;
2150 if (tty->termscript && need_to_reverse)
2151 fprintf (tty->termscript, "<INVERSE-VIDEO>\n");
2152
2153
2154 for (i--; i >= 0; i--)
2155 {
2156 Lisp_Object prop, val, frame;
2157
2158 prop = parms[i];
2159 val = values[i];
2160
2161 if (EQ (prop, Qforeground_color))
2162 {
2163 unsigned long new_color = load_color (f, NULL, val, need_to_reverse
2164 ? LFACE_BACKGROUND_INDEX
2165 : LFACE_FOREGROUND_INDEX);
2166 if (new_color != FACE_TTY_DEFAULT_COLOR
2167 && new_color != FACE_TTY_DEFAULT_FG_COLOR
2168 && new_color != FACE_TTY_DEFAULT_BG_COLOR)
2169 {
2170 FRAME_FOREGROUND_PIXEL (f) = new_color;
2171 2172
2173 XSETFRAME (frame, f);
2174 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
2175 val, frame);
2176 fg_set = 1;
2177 redraw = 1;
2178 if (tty->termscript)
2179 fprintf (tty->termscript, "<FGCOLOR %lu>\n", new_color);
2180 }
2181 }
2182 else if (EQ (prop, Qbackground_color))
2183 {
2184 unsigned long new_color = load_color (f, NULL, val, need_to_reverse
2185 ? LFACE_FOREGROUND_INDEX
2186 : LFACE_BACKGROUND_INDEX);
2187 if (new_color != FACE_TTY_DEFAULT_COLOR
2188 && new_color != FACE_TTY_DEFAULT_FG_COLOR
2189 && new_color != FACE_TTY_DEFAULT_BG_COLOR)
2190 {
2191 FRAME_BACKGROUND_PIXEL (f) = new_color;
2192 2193
2194 XSETFRAME (frame, f);
2195 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
2196 val, frame);
2197 bg_set = 1;
2198 redraw = 1;
2199 if (tty->termscript)
2200 fprintf (tty->termscript, "<BGCOLOR %lu>\n", new_color);
2201 }
2202 }
2203 else if (EQ (prop, Qtitle))
2204 {
2205 x_set_title (f, val);
2206 if (tty->termscript)
2207 fprintf (tty->termscript, "<TITLE: %s>\n", SDATA (val));
2208 }
2209 else if (EQ (prop, Qcursor_type))
2210 {
2211 IT_set_cursor_type (f, val);
2212 if (tty->termscript)
2213 fprintf (tty->termscript, "<CTYPE: %s>\n",
2214 EQ (val, Qbar) || EQ (val, Qhbar)
2215 || CONSP (val) && (EQ (XCAR (val), Qbar)
2216 || EQ (XCAR (val), Qhbar))
2217 ? "bar" : "box");
2218 }
2219 else if (EQ (prop, Qtty_type))
2220 {
2221 internal_terminal_init ();
2222 if (tty->termscript)
2223 fprintf (tty->termscript, "<TERM_INIT done, TTY_TYPE: %.*s>\n",
2224 SBYTES (val), SDATA (val));
2225 }
2226 store_frame_param (f, prop, val);
2227 }
2228
2229 2230
2231 if (need_to_reverse)
2232 {
2233 Lisp_Object frame;
2234
2235 if (!fg_set)
2236 {
2237 XSETFRAME (frame, f);
2238 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
2239 tty_color_name (f, orig_bg),
2240 frame);
2241 redraw = 1;
2242 }
2243 if (!bg_set)
2244 {
2245 XSETFRAME (frame, f);
2246 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
2247 tty_color_name (f, orig_fg),
2248 frame);
2249 redraw = 1;
2250 }
2251 }
2252
2253 if (redraw)
2254 {
2255 face_change_count++;
2256 if (f == SELECTED_FRAME())
2257 redraw_frame (f);
2258 }
2259 }
2260
2261 extern void init_frame_faces (FRAME_PTR);
2262
2263 #endif
2264
2265
2266
2267
2268 void
2269 internal_terminal_init ()
2270 {
2271 static int init_needed = 1;
2272 char *term = getenv ("TERM"), *colors;
2273 struct frame *sf = SELECTED_FRAME();
2274 struct tty_display_info *tty;
2275
2276 #ifdef HAVE_X_WINDOWS
2277 if (!inhibit_window_system)
2278 return;
2279 #endif
2280
2281
2282 if (sf->output_method == output_initial)
2283 return;
2284
2285 internal_terminal
2286 = (!noninteractive) && term && !strcmp (term, "internal");
2287
2288 #ifndef HAVE_X_WINDOWS
2289 if (!internal_terminal || inhibit_window_system)
2290 {
2291 sf->output_method = output_termcap;
2292 return;
2293 }
2294
2295 tty = FRAME_TTY (sf);
2296 current_kboard->Vwindow_system = Qpc;
2297 sf->output_method = output_msdos_raw;
2298 if (init_needed)
2299 {
2300 if (!tty->termscript && getenv ("EMACSTEST"))
2301 tty->termscript = fopen (getenv ("EMACSTEST"), "wt");
2302 if (tty->termscript)
2303 {
2304 time_t now = time (NULL);
2305 struct tm *tnow = localtime (&now);
2306 char tbuf[100];
2307
2308 strftime (tbuf, sizeof (tbuf) - 1, "%a %b %e %Y %H:%M:%S %Z", tnow);
2309 fprintf (tty->termscript, "\nEmacs session started at %s\n", tbuf);
2310 fprintf (tty->termscript, "=====================\n\n");
2311 }
2312
2313 Vinitial_window_system = Qpc;
2314 Vwindow_system_version = make_number (23);
2315 tty->terminal->type = output_msdos_raw;
2316
2317 2318
2319 screen_old_address = 0;
2320
2321
2322 initial_screen_colors[0] = initial_screen_colors[1] = -1;
2323
2324 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = 7;
2325 FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = 0;
2326 bright_bg ();
2327 colors = getenv ("EMACSCOLORS");
2328 if (colors && strlen (colors) >= 2)
2329 {
2330
2331 if (isdigit (colors[0]))
2332 colors[0] -= '0';
2333 else if (isxdigit (colors[0]))
2334 colors[0] -= (isupper (colors[0]) ? 'A' : 'a') - 10;
2335 if (colors[0] >= 0 && colors[0] < 16)
2336 FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = colors[0];
2337 if (isdigit (colors[1]))
2338 colors[1] -= '0';
2339 else if (isxdigit (colors[1]))
2340 colors[1] -= (isupper (colors[1]) ? 'A' : 'a') - 10;
2341 if (colors[1] >= 0 && colors[1] < 16)
2342 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
2343 }
2344 the_only_display_info.mouse_face_mouse_frame = NULL;
2345 the_only_display_info.mouse_face_deferred_gc = 0;
2346 the_only_display_info.mouse_face_beg_row =
2347 the_only_display_info.mouse_face_beg_col = -1;
2348 the_only_display_info.mouse_face_end_row =
2349 the_only_display_info.mouse_face_end_col = -1;
2350 the_only_display_info.mouse_face_face_id = DEFAULT_FACE_ID;
2351 the_only_display_info.mouse_face_window = Qnil;
2352 the_only_display_info.mouse_face_mouse_x =
2353 the_only_display_info.mouse_face_mouse_y = 0;
2354 the_only_display_info.mouse_face_defer = 0;
2355 the_only_display_info.mouse_face_hidden = 0;
2356
2357 if (have_mouse)
2358 {
2359 have_mouse = 1;
2360 mouse_visible = 0;
2361 mouse_setup_buttons (mouse_button_count);
2362 tty->terminal->mouse_position_hook = &mouse_get_pos;
2363 mouse_init ();
2364 }
2365
2366 if (tty->termscript && screen_size)
2367 fprintf (tty->termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n",
2368 screen_size_X, screen_size_Y);
2369
2370 init_frame_faces (sf);
2371 init_needed = 0;
2372 }
2373 #endif
2374 }
2375
2376 void
2377 initialize_msdos_display (struct terminal *term)
2378 {
2379 term->rif = 0;
2380 term->cursor_to_hook = term->raw_cursor_to_hook = IT_cursor_to;
2381 term->clear_to_end_hook = IT_clear_to_end;
2382 term->clear_frame_hook = IT_clear_screen;
2383 term->clear_end_of_line_hook = IT_clear_end_of_line;
2384 term->ins_del_lines_hook = 0;
2385 term->insert_glyphs_hook = IT_insert_glyphs;
2386 term->write_glyphs_hook = IT_write_glyphs;
2387 term->delete_glyphs_hook = IT_delete_glyphs;
2388 term->ring_bell_hook = IT_ring_bell;
2389 term->reset_terminal_modes_hook = IT_reset_terminal_modes;
2390 term->set_terminal_modes_hook = IT_set_terminal_modes;
2391 term->set_terminal_window_hook = IT_set_terminal_window;
2392 term->update_begin_hook = IT_update_begin;
2393 term->update_end_hook = IT_update_end;
2394 term->frame_up_to_date_hook = IT_frame_up_to_date;
2395 term->mouse_position_hook = 0;
2396 term->frame_rehighlight_hook = 0;
2397 term->frame_raise_lower_hook = 0;
2398 term->set_vertical_scroll_bar_hook = 0;
2399 term->condemn_scroll_bars_hook = 0;
2400 term->redeem_scroll_bar_hook = 0;
2401 term->judge_scroll_bars_hook = 0;
2402 term->read_socket_hook = &tty_read_avail_input;
2403 }
2404
2405 dos_get_saved_screen (screen, rows, cols)
2406 char **screen;
2407 int *rows;
2408 int *cols;
2409 {
2410 #ifndef HAVE_X_WINDOWS
2411 *screen = startup_screen_buffer;
2412 *cols = startup_screen_size_X;
2413 *rows = startup_screen_size_Y;
2414 return *screen != (char *)0;
2415 #else
2416 return 0;
2417 #endif
2418 }
2419
2420 #ifndef HAVE_X_WINDOWS
2421
2422
2423 void
2424 check_x (void)
2425 {
2426 if (! FRAME_MSDOS_P (SELECTED_FRAME()))
2427 error ("Not running under a window system");
2428 }
2429
2430 #endif
2431
2432
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
2443
2444 #define Ignore 0x0000
2445 #define Normal 0x0000
2446 #define FctKey 0x1000
2447 #define Special 0x2000
2448 #define ModFct 0x3000
2449 #define Map 0x4000
2450 #define KeyPad 0x5000
2451 #define Grey 0x6000
2452
2453 #define Alt 0x0100
2454 #define Ctrl 0x0200
2455 #define Shift 0x0400
2456
2457 static int extended_kbd;
2458
2459 struct kbd_translate {
2460 unsigned char sc;
2461 unsigned char ch;
2462 unsigned short code;
2463 };
2464
2465 struct dos_keyboard_map
2466 {
2467 char *unshifted;
2468 char *shifted;
2469 char *alt_gr;
2470 struct kbd_translate *translate_table;
2471 };
2472
2473
2474 static struct dos_keyboard_map us_keyboard = {
2475
2476
2477 "`1234567890-= qwertyuiop[] asdfghjkl;'\\ zxcvbnm,./ ",
2478
2479 "~!@#$%^&*()_+ QWERTYUIOP{} ASDFGHJKL:\"| ZXCVBNM<>? ",
2480 0,
2481 0
2482 };
2483
2484 static struct dos_keyboard_map fr_keyboard = {
2485
2486
2487 "\375&\202\",(-\212_\200\205)= azertyuiop^$ qsdfghjklm\227* wxcvbnm;:! ",
2488
2489 " 1234567890\370+ AZERTYUIOP\371\234 QSDFGHJKLM%\346 WXCVBN?./\365 ",
2490
2491 " ~#{[|`\\^@]} \317 ",
2492 0
2493 };
2494
2495 2496 2497 2498 2499 2500 2501
2502
2503 static struct kbd_translate it_kbd_translate_table[] = {
2504 { 0x56, 0x3c, Normal | 13 },
2505 { 0x56, 0x3e, Normal | 27 },
2506 { 0, 0, 0 }
2507 };
2508 static struct dos_keyboard_map it_keyboard = {
2509
2510
2511 "\\1234567890'\215< qwertyuiop\212+> asdfghjkl\225\205\227 zxcvbnm,.- ",
2512
2513 "|!\"\234$%&/()=?^> QWERTYUIOP\202* ASDFGHJKL\207\370\365 ZXCVBNM;:_ ",
2514
2515 " {}~` [] @# ",
2516 it_kbd_translate_table
2517 };
2518
2519 static struct dos_keyboard_map dk_keyboard = {
2520
2521
2522 "\2531234567890+| qwertyuiop\206~ asdfghjkl\221\233' zxcvbnm,.- ",
2523
2524 "\365!\"#$%&/()=?` QWERTYUIOP\217^ ASDFGHJKL\222\235* ZXCVBNM;:_ ",
2525
2526 " @\234$ {[]} | ",
2527 0
2528 };
2529
2530 static struct kbd_translate jp_kbd_translate_table[] = {
2531 { 0x73, 0x5c, Normal | 0 },
2532 { 0x73, 0x5f, Normal | 0 },
2533 { 0x73, 0x1c, Map | 0 },
2534 { 0x7d, 0x5c, Normal | 13 },
2535 { 0x7d, 0x7c, Normal | 13 },
2536 { 0x7d, 0x1c, Map | 13 },
2537 { 0, 0, 0 }
2538 };
2539 static struct dos_keyboard_map jp_keyboard = {
2540
2541
2542 "\\1234567890-^\\ qwertyuiop@[ asdfghjkl;:] zxcvbnm,./ ",
2543
2544 "_!\"#$%&'()~=~| QWERTYUIOP`{ ASDFGHJKL+*} ZXCVBNM<>? ",
2545 0,
2546 jp_kbd_translate_table
2547 };
2548
2549 static struct keyboard_layout_list
2550 {
2551 int country_code;
2552 struct dos_keyboard_map *keyboard_map;
2553 } keyboard_layout_list[] =
2554 {
2555 1, &us_keyboard,
2556 33, &fr_keyboard,
2557 39, &it_keyboard,
2558 45, &dk_keyboard,
2559 81, &jp_keyboard
2560 };
2561
2562 static struct dos_keyboard_map *keyboard;
2563 static int keyboard_map_all;
2564 static int international_keyboard;
2565
2566 int
2567 dos_set_keyboard (code, always)
2568 int code;
2569 int always;
2570 {
2571 int i;
2572 _go32_dpmi_registers regs;
2573
2574 2575 2576
2577 regs.x.ax = 0xad80;
2578 regs.x.ss = regs.x.sp = regs.x.flags = 0;
2579 _go32_dpmi_simulate_int (0x2f, ®s);
2580 if (regs.h.al == 0xff)
2581 international_keyboard = 1;
2582
2583
2584 keyboard = keyboard_layout_list[0].keyboard_map;
2585 keyboard_map_all = always;
2586 dos_keyboard_layout = 1;
2587
2588 for (i = 0; i < (sizeof (keyboard_layout_list)/sizeof (struct keyboard_layout_list)); i++)
2589 if (code == keyboard_layout_list[i].country_code)
2590 {
2591 keyboard = keyboard_layout_list[i].keyboard_map;
2592 keyboard_map_all = always;
2593 dos_keyboard_layout = code;
2594 return 1;
2595 }
2596 return 0;
2597 }
2598
2599 static struct
2600 {
2601 unsigned char char_code;
2602 unsigned char meta_code;
2603 unsigned char keypad_code;
2604 unsigned char editkey_code;
2605 } keypad_translate_map[] = {
2606 '0', '0', 0xb0, 0x63,
2607 '1', '1', 0xb1, 0x57,
2608 '2', '2', 0xb2, 0x54,
2609 '3', '3', 0xb3, 0x56,
2610 '4', '4', 0xb4, 0x51,
2611 '5', '5', 0xb5, 0xb5,
2612 '6', '6', 0xb6, 0x53,
2613 '7', '7', 0xb7, 0x50,
2614 '8', '8', 0xb8, 0x52,
2615 '9', '9', 0xb9, 0x55,
2616 '.', '-', 0xae, 0xff
2617 };
2618
2619 static struct
2620 {
2621 unsigned char char_code;
2622 unsigned char keypad_code;
2623 } grey_key_translate_map[] = {
2624 '/', 0xaf,
2625 '*', 0xaa,
2626 '-', 0xad,
2627 '+', 0xab,
2628 '\r', 0x8d
2629 };
2630
2631 static unsigned short
2632 ibmpc_translate_map[] =
2633 {
2634
2635 Normal | 0xff,
2636 Alt | ModFct | 0x1b,
2637 Normal | 1,
2638 Normal | 2,
2639 Normal | 3,
2640 Normal | 4,
2641 Normal | 5,
2642 Normal | 6,
2643 Normal | 7,
2644 Normal | 8,
2645 Normal | 9,
2646 Normal | 10,
2647 Normal | 11,
2648 Normal | 12,
2649 Special | 0x08,
2650 ModFct | 0x74,
2651
2652
2653 Map | 15,
2654 Map | 16,
2655 Map | 17,
2656 Map | 18,
2657 Map | 19,
2658 Map | 20,
2659 Map | 21,
2660 Map | 22,
2661 Map | 23,
2662 Map | 24,
2663 Map | 25,
2664 Map | 26,
2665 ModFct | 0x0d,
2666 Ignore,
2667 Map | 30,
2668 Map | 31,
2669
2670
2671 Map | 32,
2672 Map | 33,
2673 Map | 34,
2674 Map | 35,
2675 Map | 36,
2676 Map | 37,
2677 Map | 38,
2678 Map | 39,
2679 Map | 40,
2680 Map | 0,
2681 Ignore,
2682 Map | 41,
2683 Map | 45,
2684 Map | 46,
2685 Map | 47,
2686 Map | 48,
2687
2688
2689 Map | 49,
2690 Map | 50,
2691 Map | 51,
2692 Map | 52,
2693 Map | 53,
2694 Map | 54,
2695 Ignore,
2696 Grey | 1,
2697 Ignore,
2698 Normal | 55,
2699 Ignore,
2700 FctKey | 0xbe,
2701 FctKey | 0xbf,
2702 FctKey | 0xc0,
2703 FctKey | 0xc1,
2704 FctKey | 0xc2,
2705
2706
2707 FctKey | 0xc3,
2708 FctKey | 0xc4,
2709 FctKey | 0xc5,
2710 FctKey | 0xc6,
2711 FctKey | 0xc7,
2712 Ignore,
2713 Ignore,
2714 KeyPad | 7,
2715 KeyPad | 8,
2716 KeyPad | 9,
2717 Grey | 2,
2718 KeyPad | 4,
2719 KeyPad | 5,
2720 KeyPad | 6,
2721 Grey | 3,
2722 KeyPad | 1,
2723
2724
2725 KeyPad | 2,
2726 KeyPad | 3,
2727 KeyPad | 0,
2728 KeyPad | 10,
2729 Shift | FctKey | 0xbe,
2730 Shift | FctKey | 0xbf,
2731 Shift | FctKey | 0xc0,
2732 Shift | FctKey | 0xc1,
2733 Shift | FctKey | 0xc2,
2734 Shift | FctKey | 0xc3,
2735 Shift | FctKey | 0xc4,
2736 Shift | FctKey | 0xc5,
2737 Shift | FctKey | 0xc6,
2738 Shift | FctKey | 0xc7,
2739 Ctrl | FctKey | 0xbe,
2740 Ctrl | FctKey | 0xbf,
2741
2742
2743 Ctrl | FctKey | 0xc0,
2744 Ctrl | FctKey | 0xc1,
2745 Ctrl | FctKey | 0xc2,
2746 Ctrl | FctKey | 0xc3,
2747 Ctrl | FctKey | 0xc4,
2748 Ctrl | FctKey | 0xc5,
2749 Ctrl | FctKey | 0xc6,
2750 Ctrl | FctKey | 0xc7,
2751 Alt | FctKey | 0xbe,
2752 Alt | FctKey | 0xbf,
2753 Alt | FctKey | 0xc0,
2754 Alt | FctKey | 0xc1,
2755 Alt | FctKey | 0xc2,
2756 Alt | FctKey | 0xc3,
2757 Alt | FctKey | 0xc4,
2758 Alt | FctKey | 0xc5,
2759
2760
2761 Alt | FctKey | 0xc6,
2762 Alt | FctKey | 0xc7,
2763 Ctrl | FctKey | 0x6d,
2764 Ctrl | KeyPad | 4,
2765 Ctrl | KeyPad | 6,
2766 Ctrl | KeyPad | 1,
2767 Ctrl | KeyPad | 3,
2768 Ctrl | KeyPad | 7,
2769 Alt | Map | 1,
2770 Alt | Map | 2,
2771 Alt | Map | 3,
2772 Alt | Map | 4,
2773 Alt | Map | 5,
2774 Alt | Map | 6,
2775 Alt | Map | 7,
2776 Alt | Map | 8,
2777
2778
2779 Alt | Map | 9,
2780 Alt | Map | 10,
2781 Alt | Map | 11,
2782 Alt | Map | 12,
2783 Ctrl | KeyPad | 9,
2784 FctKey | 0xc8,
2785 FctKey | 0xc9,
2786 Shift | FctKey | 0xc8,
2787 Shift | FctKey | 0xc9,
2788 Ctrl | FctKey | 0xc8,
2789 Ctrl | FctKey | 0xc9,
2790 Alt | FctKey | 0xc8,
2791 Alt | FctKey | 0xc9,
2792 Ctrl | KeyPad | 8,
2793 Ctrl | Grey | 2,
2794 Ctrl | KeyPad | 5,
2795
2796
2797 Ctrl | Grey | 3,
2798 Ctrl | KeyPad | 2,
2799 Ctrl | KeyPad | 0,
2800 Ctrl | KeyPad | 10,
2801 Ctrl | FctKey | 0x09,
2802 Ctrl | Grey | 0,
2803 Ctrl | Grey | 1,
2804 Alt | FctKey | 0x50,
2805 Alt | FctKey | 0x52,
2806 Alt | FctKey | 0x55,
2807 Ignore,
2808 Alt | FctKey | 0x51,
2809 Ignore,
2810 Alt | FctKey | 0x53,
2811 Ignore,
2812 Alt | FctKey | 0x57,
2813
2814
2815 Alt | KeyPad | 2,
2816 Alt | KeyPad | 3,
2817 Alt | KeyPad | 0,
2818 Alt | KeyPad | 10,
2819 Alt | Grey | 0,
2820 Alt | FctKey | 0x09,
2821 Alt | Grey | 4
2822 };
2823
2824
2825 #define SHIFT_P 0x0003
2826 #define CTRL_P 0x0004
2827 #define ALT_P 0x0008
2828 #define SCRLOCK_P 0x0010
2829 #define NUMLOCK_P 0x0020
2830 #define CAPSLOCK_P 0x0040
2831 #define ALT_GR_P 0x0800
2832 #define SUPER_P 0x4000
2833 #define HYPER_P 0x8000
2834
2835 static int
2836 dos_get_modifiers (keymask)
2837 int *keymask;
2838 {
2839 union REGS regs;
2840 int mask, modifiers = 0;
2841
2842
2843 regs.h.ah = extended_kbd ? 0x12 : 0x02;
2844 int86 (0x16, ®s, ®s);
2845
2846 if (!extended_kbd)
2847 {
2848 mask = regs.h.al & (SHIFT_P | CTRL_P | ALT_P |
2849 SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P);
2850 }
2851 else
2852 {
2853 mask = regs.h.al & (SHIFT_P |
2854 SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P);
2855
2856
2857
2858
2859 if (regs.h.ah & 2)
2860 mask |= ALT_P;
2861
2862 if ((regs.h.ah & 8) != 0)
2863 {
2864 mask |= ALT_GR_P;
2865 if (dos_hyper_key == 1)
2866 {
2867 mask |= HYPER_P;
2868 modifiers |= hyper_modifier;
2869 }
2870 else if (dos_super_key == 1)
2871 {
2872 mask |= SUPER_P;
2873 modifiers |= super_modifier;
2874 }
2875 else if (!international_keyboard)
2876 {
2877 2878
2879 mask &= ~ALT_GR_P;
2880 mask |= ALT_P;
2881 }
2882 }
2883
2884 if (regs.h.ah & 1)
2885 mask |= CTRL_P;
2886
2887 if (regs.h.ah & 4)
2888 {
2889 if (dos_hyper_key == 2)
2890 {
2891 mask |= HYPER_P;
2892 modifiers |= hyper_modifier;
2893 }
2894 else if (dos_super_key == 2)
2895 {
2896 mask |= SUPER_P;
2897 modifiers |= super_modifier;
2898 }
2899 else
2900 mask |= CTRL_P;
2901 }
2902 }
2903
2904 if (mask & SHIFT_P)
2905 modifiers |= shift_modifier;
2906 if (mask & CTRL_P)
2907 modifiers |= ctrl_modifier;
2908 if (mask & ALT_P)
2909 modifiers |= meta_modifier;
2910
2911 if (keymask)
2912 *keymask = mask;
2913 return modifiers;
2914 }
2915
2916 #define NUM_RECENT_DOSKEYS (100)
2917 int recent_doskeys_index;
2918 int total_doskeys;
2919 Lisp_Object recent_doskeys;
2920
2921 DEFUN ("recent-doskeys", Frecent_doskeys, Srecent_doskeys, 0, 0, 0,
2922 doc: 2923 2924 )
2925 ()
2926 {
2927 Lisp_Object val, *keys = XVECTOR (recent_doskeys)->contents;
2928
2929 if (total_doskeys < NUM_RECENT_DOSKEYS)
2930 return Fvector (total_doskeys, keys);
2931 else
2932 {
2933 val = Fvector (NUM_RECENT_DOSKEYS, keys);
2934 bcopy (keys + recent_doskeys_index,
2935 XVECTOR (val)->contents,
2936 (NUM_RECENT_DOSKEYS - recent_doskeys_index) * sizeof (Lisp_Object));
2937 bcopy (keys,
2938 XVECTOR (val)->contents + NUM_RECENT_DOSKEYS - recent_doskeys_index,
2939 recent_doskeys_index * sizeof (Lisp_Object));
2940 return val;
2941 }
2942 }
2943
2944
2945 static int
2946 dos_rawgetc ()
2947 {
2948 struct input_event event;
2949 union REGS regs;
2950 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (SELECTED_FRAME());
2951 EVENT_INIT (event);
2952
2953 #ifndef HAVE_X_WINDOWS
2954
2955 IT_cmgoto (SELECTED_FRAME());
2956 #endif
2957
2958 2959
2960 while ((regs.h.ah = extended_kbd ? 0x11 : 0x01),
2961 int86 (0x16, ®s, ®s),
2962 (regs.x.flags & 0x40) == 0)
2963 {
2964 union REGS regs;
2965 register unsigned char c;
2966 int modifiers, sc, code = -1, mask, kp_mode;
2967
2968 regs.h.ah = extended_kbd ? 0x10 : 0x00;
2969 int86 (0x16, ®s, ®s);
2970 c = regs.h.al;
2971 sc = regs.h.ah;
2972
2973 total_doskeys += 2;
2974 XVECTOR (recent_doskeys)->contents[recent_doskeys_index++]
2975 = make_number (c);
2976 if (recent_doskeys_index == NUM_RECENT_DOSKEYS)
2977 recent_doskeys_index = 0;
2978 XVECTOR (recent_doskeys)->contents[recent_doskeys_index++]
2979 = make_number (sc);
2980 if (recent_doskeys_index == NUM_RECENT_DOSKEYS)
2981 recent_doskeys_index = 0;
2982
2983 modifiers = dos_get_modifiers (&mask);
2984
2985 #ifndef HAVE_X_WINDOWS
2986 if (!NILP (Vdos_display_scancodes))
2987 {
2988 char buf[11];
2989 sprintf (buf, "%02x:%02x*%04x",
2990 (unsigned) (sc&0xff), (unsigned) c, mask);
2991 dos_direct_output (screen_size_Y - 2, screen_size_X - 12, buf, 10);
2992 }
2993 #endif
2994
2995 if (sc == 0xe0)
2996 {
2997 switch (c)
2998 {
2999 case 10:
3000 code = Ctrl | Grey | 4;
3001 break;
3002 case 13:
3003 code = Grey | 4;
3004 break;
3005 case '/':
3006 code = Grey | 0;
3007 break;
3008 default:
3009 continue;
3010 };
3011 c = 0;
3012 }
3013 else
3014 {
3015
3016 if (keyboard->translate_table)
3017 {
3018 struct kbd_translate *p = keyboard->translate_table;
3019
3020 while (p->sc)
3021 {
3022 if (p->sc == sc && p->ch == c)
3023 {
3024 code = p->code;
3025 break;
3026 }
3027 p++;
3028 }
3029 }
3030 3031
3032 if (code == -1)
3033 {
3034 if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short)))
3035 continue;
3036 if ((code = ibmpc_translate_map[sc]) == Ignore)
3037 continue;
3038 }
3039 }
3040
3041 if (c == 0)
3042 {
3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053
3054 if ( (code & Alt)
3055 || ( (code & 0xf000) == Map && !international_keyboard))
3056 modifiers |= meta_modifier;
3057 if (code & Ctrl)
3058 modifiers |= ctrl_modifier;
3059 if (code & Shift)
3060 modifiers |= shift_modifier;
3061 }
3062
3063 switch (code & 0xf000)
3064 {
3065 case ModFct:
3066 if (c && !(mask & (SHIFT_P | ALT_P | CTRL_P | HYPER_P | SUPER_P)))
3067 return c;
3068 c = 0;
3069
3070 case FctKey:
3071 if (c != 0)
3072 return c;
3073
3074 case Special:
3075 code |= 0xff00;
3076 break;
3077
3078 case Normal:
3079 if (sc == 0)
3080 {
3081 if (c == 0)
3082 continue;
3083 return c;
3084 }
3085 if (!keyboard_map_all)
3086 {
3087 if (c != ' ')
3088 return c;
3089 code = c;
3090 break;
3091 }
3092
3093 case Map:
3094 if (c && !(mask & ALT_P) && !((mask & SHIFT_P) && (mask & CTRL_P)))
3095 if (!keyboard_map_all)
3096 return c;
3097
3098 code &= 0xff;
3099 if (mask & ALT_P && code <= 10 && code > 0 && dos_keypad_mode & 0x200)
3100 mask |= SHIFT_P;
3101
3102 if (mask & SHIFT_P)
3103 {
3104 code = keyboard->shifted[code];
3105 mask -= SHIFT_P;
3106 modifiers &= ~shift_modifier;
3107 }
3108 else
3109 if ((mask & ALT_GR_P) && keyboard->alt_gr && keyboard->alt_gr[code] != ' ')
3110 code = keyboard->alt_gr[code];
3111 else
3112 code = keyboard->unshifted[code];
3113 break;
3114
3115 case KeyPad:
3116 code &= 0xff;
3117 if (c == 0xe0)
3118 kp_mode = 3;
3119 else
3120 if ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P)
3121 kp_mode = dos_keypad_mode & 0x03;
3122 else
3123 kp_mode = (dos_keypad_mode >> 4) & 0x03;
3124
3125 switch (kp_mode)
3126 {
3127 case 0:
3128 if (code == 10 && dos_decimal_point)
3129 return dos_decimal_point;
3130 return keypad_translate_map[code].char_code;
3131
3132 case 1:
3133 code = 0xff00 | keypad_translate_map[code].keypad_code;
3134 break;
3135
3136 case 2:
3137 code = keypad_translate_map[code].meta_code;
3138 modifiers = meta_modifier;
3139 break;
3140
3141 case 3:
3142 code = 0xff00 | keypad_translate_map[code].editkey_code;
3143 break;
3144 }
3145 break;
3146
3147 case Grey:
3148 code &= 0xff;
3149 kp_mode = ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P) ? 0x04 : 0x40;
3150 if (dos_keypad_mode & kp_mode)
3151 code = 0xff00 | grey_key_translate_map[code].keypad_code;
3152 else
3153 code = grey_key_translate_map[code].char_code;
3154 break;
3155 }
3156
3157 make_event:
3158 if (code == 0)
3159 continue;
3160
3161 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
3162 {
3163 clear_mouse_face (dpyinfo);
3164 dpyinfo->mouse_face_hidden = 1;
3165 }
3166
3167 if (code >= 0x100)
3168 event.kind = NON_ASCII_KEYSTROKE_EVENT;
3169 else
3170 event.kind = ASCII_KEYSTROKE_EVENT;
3171 event.code = code;
3172 event.modifiers = modifiers;
3173 event.frame_or_window = selected_frame;
3174 event.arg = Qnil;
3175 event.timestamp = event_timestamp ();
3176 kbd_buffer_store_event (&event);
3177 }
3178
3179 if (have_mouse > 0 && !mouse_preempted)
3180 {
3181 int but, press, x, y, ok;
3182 int mouse_prev_x = mouse_last_x, mouse_prev_y = mouse_last_y;
3183 Lisp_Object mouse_window = Qnil;
3184
3185
3186 mouse_check_moved ();
3187
3188 3189
3190 if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y)
3191 {
3192 if (dpyinfo->mouse_face_hidden)
3193 {
3194 dpyinfo->mouse_face_hidden = 0;
3195 clear_mouse_face (dpyinfo);
3196 }
3197
3198
3199 if (!NILP (Vmouse_autoselect_window))
3200 {
3201 mouse_window = window_from_coordinates (SELECTED_FRAME(),
3202 mouse_last_x,
3203 mouse_last_y,
3204 0, 0, 0, 0);
3205 3206 3207 3208
3209 if (WINDOWP (mouse_window)
3210 && !EQ (mouse_window, last_mouse_window)
3211 && !EQ (mouse_window, selected_window))
3212 {
3213 event.kind = SELECT_WINDOW_EVENT;
3214 event.frame_or_window = mouse_window;
3215 event.arg = Qnil;
3216 event.timestamp = event_timestamp ();
3217 kbd_buffer_store_event (&event);
3218 }
3219 last_mouse_window = mouse_window;
3220 }
3221 else
3222 last_mouse_window = Qnil;
3223
3224 previous_help_echo_string = help_echo_string;
3225 help_echo_string = help_echo_object = help_echo_window = Qnil;
3226 help_echo_pos = -1;
3227 IT_note_mouse_highlight (SELECTED_FRAME(),
3228 mouse_last_x, mouse_last_y);
3229 3230
3231 if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
3232 {
3233 event.kind = HELP_EVENT;
3234 event.frame_or_window = selected_frame;
3235 event.arg = help_echo_object;
3236 event.x = WINDOWP (help_echo_window)
3237 ? help_echo_window : selected_frame;
3238 event.y = help_echo_string;
3239 event.timestamp = event_timestamp ();
3240 event.code = help_echo_pos;
3241 kbd_buffer_store_event (&event);
3242 }
3243 }
3244
3245 for (but = 0; but < NUM_MOUSE_BUTTONS; but++)
3246 for (press = 0; press < 2; press++)
3247 {
3248 int button_num = but;
3249
3250 if (press)
3251 ok = mouse_pressed (but, &x, &y);
3252 else
3253 ok = mouse_released (but, &x, &y);
3254 if (ok)
3255 {
3256 3257
3258 if (mouse_button_count == 2 && but < 2)
3259 {
3260 int x2, y2;
3261
3262 3263 3264
3265 if (press && mouse_pressed (1-but, &x2, &y2)
3266 || !press && mouse_released (1-but, &x2, &y2))
3267 button_num = 2;
3268 else
3269 {
3270 delay (100);
3271 if (press && mouse_pressed (1-but, &x2, &y2)
3272 || !press && mouse_released (1-but, &x2, &y2))
3273 button_num = 2;
3274 }
3275 }
3276
3277 event.kind = MOUSE_CLICK_EVENT;
3278 event.code = button_num;
3279 event.modifiers = dos_get_modifiers (0)
3280 | (press ? down_modifier : up_modifier);
3281 event.x = make_number (x);
3282 event.y = make_number (y);
3283 event.frame_or_window = selected_frame;
3284 event.arg = Qnil;
3285 event.timestamp = event_timestamp ();
3286 kbd_buffer_store_event (&event);
3287 }
3288 }
3289 }
3290
3291 return -1;
3292 }
3293
3294 static int prev_get_char = -1;
3295
3296
3297
3298 dos_keysns ()
3299 {
3300 if (prev_get_char != -1)
3301 return 1;
3302 else
3303 return ((prev_get_char = dos_rawgetc ()) != -1);
3304 }
3305
3306
3307
3308 dos_keyread ()
3309 {
3310 if (prev_get_char != -1)
3311 {
3312 int c = prev_get_char;
3313 prev_get_char = -1;
3314 return c;
3315 }
3316 else
3317 return dos_rawgetc ();
3318 }
3319
3320 #ifndef HAVE_X_WINDOWS
3321
3322 3323 3324 3325 3326 3327 3328
3329
3330
3331 static char *menu_help_message, *prev_menu_help_message;
3332 3333
3334 static int menu_help_paneno, menu_help_itemno;
3335
3336 static XMenu *
3337 IT_menu_create ()
3338 {
3339 XMenu *menu;
3340
3341 menu = (XMenu *) xmalloc (sizeof (XMenu));
3342 menu->allocated = menu->count = menu->panecount = menu->width = 0;
3343 return menu;
3344 }
3345
3346 3347
3348
3349 static void
3350 IT_menu_make_room (XMenu *menu)
3351 {
3352 if (menu->allocated == 0)
3353 {
3354 int count = menu->allocated = 10;
3355 menu->text = (char **) xmalloc (count * sizeof (char *));
3356 menu->submenu = (XMenu **) xmalloc (count * sizeof (XMenu *));
3357 menu->panenumber = (int *) xmalloc (count * sizeof (int));
3358 menu->help_text = (char **) xmalloc (count * sizeof (char *));
3359 }
3360 else if (menu->allocated == menu->count)
3361 {
3362 int count = menu->allocated = menu->allocated + 10;
3363 menu->text
3364 = (char **) xrealloc (menu->text, count * sizeof (char *));
3365 menu->submenu
3366 = (XMenu **) xrealloc (menu->submenu, count * sizeof (XMenu *));
3367 menu->panenumber
3368 = (int *) xrealloc (menu->panenumber, count * sizeof (int));
3369 menu->help_text
3370 = (char **) xrealloc (menu->help_text, count * sizeof (char *));
3371 }
3372 }
3373
3374
3375
3376 static XMenu *
3377 IT_menu_search_pane (XMenu *menu, int pane)
3378 {
3379 int i;
3380 XMenu *try;
3381
3382 for (i = 0; i < menu->count; i++)
3383 if (menu->submenu[i])
3384 {
3385 if (pane == menu->panenumber[i])
3386 return menu->submenu[i];
3387 if ((try = IT_menu_search_pane (menu->submenu[i], pane)))
3388 return try;
3389 }
3390 return (XMenu *) 0;
3391 }
3392
3393
3394
3395 static void
3396 IT_menu_calc_size (XMenu *menu, int *width, int *height)
3397 {
3398 int i, h2, w2, maxsubwidth, maxheight;
3399
3400 maxsubwidth = 0;
3401 maxheight = menu->count;
3402 for (i = 0; i < menu->count; i++)
3403 {
3404 if (menu->submenu[i])
3405 {
3406 IT_menu_calc_size (menu->submenu[i], &w2, &h2);
3407 if (w2 > maxsubwidth) maxsubwidth = w2;
3408 if (i + h2 > maxheight) maxheight = i + h2;
3409 }
3410 }
3411 *width = menu->width + maxsubwidth;
3412 *height = maxheight;
3413 }
3414
3415
3416
3417 #define BUILD_CHAR_GLYPH(GLYPH, CODE, FACE_ID, PADDING_P) \
3418 do \
3419 { \
3420 (GLYPH).type = CHAR_GLYPH; \
3421 SET_CHAR_GLYPH ((GLYPH), CODE, FACE_ID, PADDING_P); \
3422 (GLYPH).charpos = -1; \
3423 } \
3424 while (0)
3425
3426 static void
3427 IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
3428 {
3429 int i, j, face, width, mx, my, enabled, mousehere, row, col;
3430 struct glyph *text, *p;
3431 const unsigned char *q;
3432 struct frame *sf = SELECTED_FRAME();
3433
3434 menu_help_message = NULL;
3435
3436 width = menu->width;
3437 3438
3439 text = (struct glyph *) xmalloc ((width * 2 + 2) * sizeof (struct glyph));
3440 ScreenGetCursor (&row, &col);
3441 mouse_get_xy (&mx, &my);
3442 IT_update_begin (sf);
3443 for (i = 0; i < menu->count; i++)
3444 {
3445 int max_width = width + 2;
3446
3447 IT_cursor_to (sf, y + i, x);
3448 enabled
3449 = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
3450 mousehere = (y + i == my && x <= mx && mx < x + max_width);
3451 face = faces[enabled + mousehere * 2];
3452 3453
3454 if (disp_help && enabled + mousehere * 2 >= 2)
3455 {
3456 menu_help_message = menu->help_text[i];
3457 menu_help_paneno = pn - 1;
3458 menu_help_itemno = i;
3459 }
3460 p = text;
3461 BUILD_CHAR_GLYPH (*p, ' ', face, 0);
3462 p++;
3463 for (j = 0, q = menu->text[i]; *q; j++)
3464 {
3465 unsigned c = STRING_CHAR_ADVANCE (q);
3466
3467 if (c > 26)
3468 {
3469 BUILD_CHAR_GLYPH (*p, c, face, 0);
3470 p++;
3471 }
3472 else
3473 {
3474 BUILD_CHAR_GLYPH (*p, '^', face, 0);
3475 p++;
3476 j++;
3477 BUILD_CHAR_GLYPH (*p, c + 64, face, 0);
3478 p++;
3479 }
3480 }
3481
3482 if (x + max_width > screen_size_X)
3483 {
3484 max_width = screen_size_X - x;
3485 text[max_width - 1].u.ch = '$';
3486 }
3487 for (; j < max_width - 2; j++, p++)
3488 BUILD_CHAR_GLYPH (*p, ' ', face, 0);
3489
3490 3491
3492 BUILD_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0);
3493 p++;
3494 IT_write_glyphs (sf, text, max_width);
3495 }
3496 IT_update_end (sf);
3497 IT_cursor_to (sf, row, col);
3498 xfree (text);
3499 }
3500
3501
3502
3503
3504
3505 int
3506 have_menus_p () { return 1; }
3507
3508
3509
3510 XMenu *
3511 XMenuCreate (Display *foo1, Window foo2, char *foo3)
3512 {
3513 return IT_menu_create ();
3514 }
3515
3516 3517 3518
3519
3520 int
3521 XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable)
3522 {
3523 int len;
3524 char *p;
3525
3526 if (!enable)
3527 abort ();
3528
3529 IT_menu_make_room (menu);
3530 menu->submenu[menu->count] = IT_menu_create ();
3531 menu->text[menu->count] = txt;
3532 menu->panenumber[menu->count] = ++menu->panecount;
3533 menu->help_text[menu->count] = NULL;
3534 menu->count++;
3535
3536 3537
3538 for (len = strlen (txt), p = txt; *p; p++)
3539 if (*p < 27)
3540 len++;
3541
3542 if (len > menu->width)
3543 menu->width = len;
3544
3545 return menu->panecount;
3546 }
3547
3548
3549
3550 int
3551 XMenuAddSelection (Display *bar, XMenu *menu, int pane,
3552 int foo, char *txt, int enable, char *help_text)
3553 {
3554 int len;
3555 char *p;
3556
3557 if (pane)
3558 if (!(menu = IT_menu_search_pane (menu, pane)))
3559 return XM_FAILURE;
3560 IT_menu_make_room (menu);
3561 menu->submenu[menu->count] = (XMenu *) 0;
3562 menu->text[menu->count] = txt;
3563 menu->panenumber[menu->count] = enable;
3564 menu->help_text[menu->count] = help_text;
3565 menu->count++;
3566
3567 3568
3569 for (len = strlen (txt), p = txt; *p; p++)
3570 if (*p < 27)
3571 len++;
3572
3573 if (len > menu->width)
3574 menu->width = len;
3575
3576 return XM_SUCCESS;
3577 }
3578
3579
3580
3581 void
3582 XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y,
3583 int *ulx, int *uly, int *width, int *height)
3584 {
3585 IT_menu_calc_size (menu, width, height);
3586 *ulx = x + 1;
3587 *uly = y;
3588 *width += 2;
3589 }
3590
3591 struct IT_menu_state
3592 {
3593 void *screen_behind;
3594 XMenu *menu;
3595 int pane;
3596 int x, y;
3597 };
3598
3599
3600
3601
3602 int
3603 XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
3604 int x0, int y0, unsigned ButtonMask, char **txt,
3605 void (*help_callback)(char *, int, int))
3606 {
3607 struct IT_menu_state *state;
3608 int statecount, x, y, i, b, screensize, leave, result, onepane;
3609 int title_faces[4];
3610 int faces[4], buffers_num_deleted = 0;
3611 struct frame *sf = SELECTED_FRAME();
3612 Lisp_Object saved_echo_area_message, selectface;
3613
3614
3615 if (have_mouse <= 0)
3616 return XM_IA_SELECT;
3617 3618
3619 if (x0 <= 0)
3620 x0 = 1;
3621 if (y0 <= 0)
3622 y0 = 1;
3623
3624 3625
3626 mouse_preempted++;
3627
3628 state = alloca (menu->panecount * sizeof (struct IT_menu_state));
3629 screensize = screen_size * 2;
3630 faces[0]
3631 = lookup_derived_face (sf, intern ("msdos-menu-passive-face"),
3632 DEFAULT_FACE_ID, 1);
3633 faces[1]
3634 = lookup_derived_face (sf, intern ("msdos-menu-active-face"),
3635 DEFAULT_FACE_ID, 1);
3636 selectface = intern ("msdos-menu-select-face");
3637 faces[2] = lookup_derived_face (sf, selectface,
3638 faces[0], 1);
3639 faces[3] = lookup_derived_face (sf, selectface,
3640 faces[1], 1);
3641
3642 3643
3644 for (i = 0; i < 4; i++)
3645 title_faces[i] = faces[3];
3646
3647 statecount = 1;
3648
3649 3650 3651 3652 3653 3654
3655 if (strncmp (menu->text[0], "Buffers 1", 9) == 0)
3656 {
3657 menu->text[0][7] = '\0';
3658 buffers_num_deleted = 1;
3659 }
3660
3661 3662 3663
3664 saved_echo_area_message = Fcurrent_message ();
3665 state[0].menu = menu;
3666 mouse_off ();
3667 ScreenRetrieve (state[0].screen_behind = xmalloc (screensize));
3668
3669 3670
3671 IT_display_cursor (0);
3672
3673
3674 IT_menu_display (menu, y0 - 1, x0 - 1, 1, title_faces, 0);
3675 if (buffers_num_deleted)
3676 menu->text[0][7] = ' ';
3677 if ((onepane = menu->count == 1 && menu->submenu[0]))
3678 {
3679 menu->width = menu->submenu[0]->width;
3680 state[0].menu = menu->submenu[0];
3681 }
3682 else
3683 {
3684 state[0].menu = menu;
3685 }
3686 state[0].x = x0 - 1;
3687 state[0].y = y0;
3688 state[0].pane = onepane;
3689
3690 mouse_last_x = -1;
3691 leave = 0;
3692 while (!leave)
3693 {
3694 if (!mouse_visible) mouse_on ();
3695 mouse_check_moved ();
3696 if (sf->mouse_moved)
3697 {
3698 sf->mouse_moved = 0;
3699 result = XM_IA_SELECT;
3700 mouse_get_xy (&x, &y);
3701 for (i = 0; i < statecount; i++)
3702 if (state[i].x <= x && x < state[i].x + state[i].menu->width + 2)
3703 {
3704 int dy = y - state[i].y;
3705 if (0 <= dy && dy < state[i].menu->count)
3706 {
3707 if (!state[i].menu->submenu[dy])
3708 if (state[i].menu->panenumber[dy])
3709 result = XM_SUCCESS;
3710 else
3711 result = XM_IA_SELECT;
3712 *pane = state[i].pane - 1;
3713 *selidx = dy;
3714 3715 3716
3717 if (i != statecount - 2
3718 || state[i].menu->submenu[dy] != state[i+1].menu)
3719 while (i != statecount - 1)
3720 {
3721 statecount--;
3722 mouse_off ();
3723 ScreenUpdate (state[statecount].screen_behind);
3724 if (screen_virtual_segment)
3725 dosv_refresh_virtual_screen (0, screen_size);
3726 xfree (state[statecount].screen_behind);
3727 }
3728 if (i == statecount - 1 && state[i].menu->submenu[dy])
3729 {
3730 IT_menu_display (state[i].menu,
3731 state[i].y,
3732 state[i].x,
3733 state[i].pane,
3734 faces, 1);
3735 state[statecount].menu = state[i].menu->submenu[dy];
3736 state[statecount].pane = state[i].menu->panenumber[dy];
3737 mouse_off ();
3738 ScreenRetrieve (state[statecount].screen_behind
3739 = xmalloc (screensize));
3740 state[statecount].x
3741 = state[i].x + state[i].menu->width + 2;
3742 state[statecount].y = y;
3743 statecount++;
3744 }
3745 }
3746 }
3747 IT_menu_display (state[statecount - 1].menu,
3748 state[statecount - 1].y,
3749 state[statecount - 1].x,
3750 state[statecount - 1].pane,
3751 faces, 1);
3752 }
3753 else
3754 {
3755 if ((menu_help_message || prev_menu_help_message)
3756 && menu_help_message != prev_menu_help_message)
3757 {
3758 help_callback (menu_help_message,
3759 menu_help_paneno, menu_help_itemno);
3760 IT_display_cursor (0);
3761 prev_menu_help_message = menu_help_message;
3762 }
3763 3764
3765 __dpmi_yield ();
3766 }
3767 for (b = 0; b < mouse_button_count && !leave; b++)
3768 {
3769 3770 3771
3772 if (mouse_pressed (b, &x, &y))
3773 {
3774 while (mouse_button_depressed (b, &x, &y))
3775 __dpmi_yield ();
3776 leave = 1;
3777 }
3778 (void) mouse_released (b, &x, &y);
3779 }
3780 }
3781
3782 mouse_off ();
3783 ScreenUpdate (state[0].screen_behind);
3784 if (screen_virtual_segment)
3785 dosv_refresh_virtual_screen (0, screen_size);
3786
3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803
3804 if (! NILP (saved_echo_area_message))
3805 message_with_string ("%s", saved_echo_area_message, 0);
3806 message (0);
3807 while (statecount--)
3808 xfree (state[statecount].screen_behind);
3809 IT_display_cursor (1);
3810 3811 3812 3813 3814
3815 discard_mouse_events ();
3816 mouse_clear_clicks ();
3817 if (!kbd_buffer_events_waiting (1))
3818 clear_input_pending ();
3819
3820 mouse_preempted--;
3821 return result;
3822 }
3823
3824
3825
3826 void
3827 XMenuDestroy (Display *foo, XMenu *menu)
3828 {
3829 int i;
3830 if (menu->allocated)
3831 {
3832 for (i = 0; i < menu->count; i++)
3833 if (menu->submenu[i])
3834 XMenuDestroy (foo, menu->submenu[i]);
3835 xfree (menu->text);
3836 xfree (menu->submenu);
3837 xfree (menu->panenumber);
3838 xfree (menu->help_text);
3839 }
3840 xfree (menu);
3841 menu_help_message = prev_menu_help_message = NULL;
3842 }
3843
3844 int
3845 x_pixel_width (struct frame *f)
3846 {
3847 return FRAME_COLS (f);
3848 }
3849
3850 int
3851 x_pixel_height (struct frame *f)
3852 {
3853 return FRAME_LINES (f);
3854 }
3855 #endif
3856
3857
3858
3859 void msdos_downcase_filename (unsigned char *);
3860
3861
3862
3863 void
3864 dostounix_filename (p)
3865 register char *p;
3866 {
3867 msdos_downcase_filename (p);
3868
3869 while (*p)
3870 {
3871 if (*p == '\\')
3872 *p = '/';
3873 p++;
3874 }
3875 }
3876
3877
3878
3879 void
3880 unixtodos_filename (p)
3881 register char *p;
3882 {
3883 if (p[1] == ':' && *p >= 'A' && *p <= 'Z')
3884 {
3885 *p += 'a' - 'A';
3886 p += 2;
3887 }
3888
3889 while (*p)
3890 {
3891 if (*p == '/')
3892 *p = '\\';
3893 p++;
3894 }
3895 }
3896
3897
3898
3899 int
3900 getdefdir (drive, dst)
3901 int drive;
3902 char *dst;
3903 {
3904 char in_path[4], *p = in_path, e = errno;
3905
3906
3907 if (drive != 0)
3908 {
3909 *p++ = drive + 'A' - 1;
3910 *p++ = ':';
3911 }
3912
3913 *p++ = '.';
3914 *p = '\0';
3915 errno = 0;
3916 _fixpath (in_path, dst);
3917 3918
3919 if ((errno && errno != ENOSYS) || *dst == '\0')
3920 return 0;
3921
3922 msdos_downcase_filename (dst);
3923
3924 errno = e;
3925 return 1;
3926 }
3927
3928 char *
3929 emacs_root_dir (void)
3930 {
3931 static char root_dir[4];
3932
3933 sprintf (root_dir, "%c:/", 'A' + getdisk ());
3934 root_dir[0] = tolower (root_dir[0]);
3935 return root_dir;
3936 }
3937
3938
3939
3940 int
3941 crlf_to_lf (n, buf)
3942 register int n;
3943 register unsigned char *buf;
3944 {
3945 unsigned char *np = buf, *startp = buf, *endp = buf + n;
3946
3947 if (n == 0)
3948 return n;
3949 while (buf < endp - 1)
3950 {
3951 if (*buf == 0x0d)
3952 {
3953 if (*(++buf) != 0x0a)
3954 *np++ = 0x0d;
3955 }
3956 else
3957 *np++ = *buf++;
3958 }
3959 if (buf < endp)
3960 *np++ = *buf++;
3961 return np - startp;
3962 }
3963
3964 DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names,
3965 0, 0, 0,
3966 doc: )
3967 ()
3968 {
3969 return (_USE_LFN ? Qt : Qnil);
3970 }
3971
3972
3973
3974 void
3975 msdos_downcase_filename (p)
3976 register unsigned char *p;
3977 {
3978 3979 3980 3981 3982
3983 if (p[1] == ':' && *p >= 'A' && *p <= 'Z')
3984 {
3985 *p += 'a' - 'A';
3986 p += 2;
3987 }
3988
3989
3990 if (NILP (Fmsdos_long_file_names ()))
3991 for ( ; *p; p++)
3992 if (*p >= 'A' && *p <= 'Z')
3993 *p += 'a' - 'A';
3994 }
3995
3996 DEFUN ("msdos-downcase-filename", Fmsdos_downcase_filename, Smsdos_downcase_filename,
3997 1, 1, 0,
3998 doc: 3999 4000 4001 )
4002 (filename)
4003 Lisp_Object filename;
4004 {
4005 Lisp_Object tem;
4006
4007 if (! STRINGP (filename))
4008 return Qnil;
4009
4010 tem = Fcopy_sequence (filename);
4011 msdos_downcase_filename (SDATA (tem));
4012 return tem;
4013 }
4014
4015
4016
4017 static char emacsroot[MAXPATHLEN];
4018
4019 char *
4020 rootrelativepath (rel)
4021 char *rel;
4022 {
4023 static char result[MAXPATHLEN + 10];
4024
4025 strcpy (result, emacsroot);
4026 strcat (result, "/");
4027 strcat (result, rel);
4028 return result;
4029 }
4030
4031 4032 4033
4034
4035 void
4036 init_environment (argc, argv, skip_args)
4037 int argc;
4038 char **argv;
4039 int skip_args;
4040 {
4041 char *s, *t, *root;
4042 int len, i;
4043 static const char * const tempdirs[] = {
4044 "$TMPDIR", "$TEMP", "$TMP", "c:/"
4045 };
4046 const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]);
4047
4048 4049 4050 4051
4052 for (i = 0; i < imax ; i++)
4053 {
4054 const char *tmp = tempdirs[i];
4055 char buf[FILENAME_MAX];
4056
4057 if (*tmp == '$')
4058 {
4059 int tmp_len;
4060
4061 tmp = getenv (tmp + 1);
4062 if (!tmp)
4063 continue;
4064
4065 4066 4067
4068 tmp_len = strlen(tmp);
4069 if (tmp[tmp_len - 1] != '/' && tmp[tmp_len - 1] != '\\')
4070 {
4071 strcpy(buf, tmp);
4072 buf[tmp_len++] = '/', buf[tmp_len] = 0;
4073 tmp = buf;
4074 }
4075 }
4076
4077 4078 4079 4080
4081 if (tmp && access (tmp, D_OK) == 0)
4082 {
4083 setenv ("TMPDIR", tmp, 1);
4084 break;
4085 }
4086 }
4087 if (i >= imax)
4088 cmd_error_internal
4089 (Fcons (Qerror,
4090 Fcons (build_string ("no usable temporary directories found!!"),
4091 Qnil)),
4092 "While setting TMPDIR: ");
4093
4094 4095 4096 4097
4098 startup_time = clock ();
4099
4100 4101
4102 root = alloca (MAXPATHLEN + 20);
4103 _fixpath (argv[0], root);
4104 msdos_downcase_filename (root);
4105 len = strlen (root);
4106 while (len > 0 && root[len] != '/' && root[len] != ':')
4107 len--;
4108 root[len] = '\0';
4109 if (len > 4
4110 && (strcmp (root + len - 4, "/bin") == 0
4111 || strcmp (root + len - 4, "/src") == 0))
4112 root[len - 4] = '\0';
4113 else
4114 strcpy (root, "c:/emacs");
4115 len = strlen (root);
4116 strcpy (emacsroot, root);
4117
4118
4119 setenv ("HOME", root, 0);
4120
4121
4122 strcpy (root + len, "/bin");
4123 setenv ("EMACSPATH", root, 0);
4124
4125 4126
4127 setenv ("TERM", "internal", 0);
4128
4129 #ifdef HAVE_X_WINDOWS
4130
4131 setenv ("DISPLAY", "unix:0.0", 0);
4132 #endif
4133
4134 4135
4136 s = getenv ("COMSPEC");
4137 if (!s) s = "c:/command.com";
4138 t = alloca (strlen (s) + 1);
4139 strcpy (t, s);
4140 dostounix_filename (t);
4141 setenv ("SHELL", t, 0);
4142
4143
4144 s = getenv ("PATH");
4145 if (!s) s = "";
4146 t = alloca (strlen (s) + 3);
4147 4148
4149 strcat (strcpy (t, ".;"), s);
4150 dostounix_filename (t);
4151 setenv ("PATH", t, 1);
4152
4153
4154 setenv ("USER", "root", 0);
4155 setenv ("NAME", getenv ("USER"), 0);
4156
4157 4158 4159
4160 if (!getenv ("TZ"))
4161 switch (dos_country_code)
4162 {
4163 case 31:
4164 case 32:
4165 case 33:
4166 case 34:
4167 case 36:
4168 case 38:
4169 case 39:
4170 case 41:
4171 case 42:
4172 case 45:
4173 case 46:
4174 case 47:
4175 case 48:
4176 case 49:
4177 4178
4179 setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0);
4180 break;
4181 case 44:
4182 case 351:
4183 case 354:
4184 setenv ("TZ", "GMT+00", 0);
4185 break;
4186 case 81:
4187 case 82:
4188 setenv ("TZ", "JST-09", 0);
4189 break;
4190 case 90:
4191 case 358:
4192 setenv ("TZ", "EET-02", 0);
4193 break;
4194 case 972:
4195 4196 4197
4198 setenv ("TZ", "IST-02IDT-03,M4.1.6/00:00,M9.5.6/01:00", 0);
4199 break;
4200 }
4201 tzset ();
4202 }
4203
4204
4205
4206 static int break_stat;
4207 static int stdin_stat;
4208
4209 4210
4211
4212 int
4213 dos_ttraw (struct tty_display_info *tty)
4214 {
4215 union REGS inregs, outregs;
4216 static int first_time = 1;
4217
4218 4219
4220 if (tty->terminal->type == output_initial)
4221 return;
4222
4223 break_stat = getcbrk ();
4224 setcbrk (0);
4225
4226 if (first_time)
4227 {
4228 inregs.h.ah = 0xc0;
4229 int86 (0x15, &inregs, &outregs);
4230 extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0);
4231
4232 have_mouse = 0;
4233
4234 if (1
4235 #ifdef HAVE_X_WINDOWS
4236 && inhibit_window_system
4237 #endif
4238 )
4239 {
4240 inregs.x.ax = 0x0021;
4241 int86 (0x33, &inregs, &outregs);
4242 have_mouse = (outregs.x.ax & 0xffff) == 0xffff;
4243 if (!have_mouse)
4244 {
4245 4246 4247
4248 inregs.x.ax = 0x0000;
4249 int86 (0x33, &inregs, &outregs);
4250 have_mouse = (outregs.x.ax & 0xffff) == 0xffff;
4251 }
4252 if (have_mouse)
4253 mouse_button_count = outregs.x.bx;
4254
4255 #ifndef HAVE_X_WINDOWS
4256
4257 outside_cursor = _farpeekw (_dos_ds, 0x460);
4258 #endif
4259 }
4260
4261 first_time = 0;
4262
4263 stdin_stat = setmode (fileno (stdin), O_BINARY);
4264 return (stdin_stat != -1);
4265 }
4266 else
4267 return (setmode (fileno (stdin), O_BINARY) != -1);
4268 }
4269
4270
4271
4272 int
4273 dos_ttcooked ()
4274 {
4275 union REGS inregs, outregs;
4276
4277 setcbrk (break_stat);
4278 mouse_off ();
4279
4280 #ifndef HAVE_X_WINDOWS
4281
4282 if (outside_cursor)
4283 {
4284 inregs.h.ah = 1;
4285 inregs.x.cx = outside_cursor;
4286 int86 (0x10, &inregs, &outregs);
4287 }
4288 #endif
4289
4290 return (setmode (fileno (stdin), stdin_stat) != -1);
4291 }
4292
4293
4294 4295 4296
4297
4298 int
4299 run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
4300 unsigned char **argv;
4301 const char *working_dir;
4302 int tempin, tempout, temperr;
4303 char **envv;
4304 {
4305 char *saveargv1, *saveargv2, *lowcase_argv0, *pa, *pl;
4306 char oldwd[MAXPATHLEN + 1];
4307 int msshell, result = -1, inbak, outbak, errbak, x, y;
4308 Lisp_Object cmd;
4309
4310
4311 getwd (oldwd);
4312
4313 4314 4315
4316 lowcase_argv0 = alloca (strlen (argv[0]) + 1);
4317 for (pa = argv[0], pl = lowcase_argv0; *pa; pl++)
4318 {
4319 *pl = *pa++;
4320 if (*pl >= 'A' && *pl <= 'Z')
4321 *pl += 'a' - 'A';
4322 }
4323 *pl = '\0';
4324
4325 cmd = Ffile_name_nondirectory (build_string (lowcase_argv0));
4326 msshell = !NILP (Fmember (cmd, Fsymbol_value (intern ("msdos-shells"))))
4327 && !strcmp ("-c", argv[1]);
4328 if (msshell)
4329 {
4330 saveargv1 = argv[1];
4331 saveargv2 = argv[2];
4332 argv[1] = "/c";
4333 4334 4335
4336 if (argv[2] && argv[3])
4337 {
4338 char *p = alloca (strlen (argv[2]) + 1);
4339
4340 strcpy (argv[2] = p, saveargv2);
4341 while (*p && isspace (*p))
4342 p++;
4343 while (*p)
4344 {
4345 if (*p == '/')
4346 *p++ = '\\';
4347 else
4348 p++;
4349 }
4350 }
4351 }
4352
4353 chdir (working_dir);
4354 inbak = dup (0);
4355 outbak = dup (1);
4356 errbak = dup (2);
4357 if (inbak < 0 || outbak < 0 || errbak < 0)
4358 goto done;
4359
4360 if (have_mouse > 0)
4361 mouse_get_xy (&x, &y);
4362
4363 if (!noninteractive)
4364 dos_ttcooked ();
4365
4366 dup2 (tempin, 0);
4367 dup2 (tempout, 1);
4368 dup2 (temperr, 2);
4369
4370 if (msshell && !argv[3])
4371 {
4372 4373 4374
4375
4376 const char *cmnd;
4377
4378 4379
4380
4381 4382 4383
4384 for (cmnd = saveargv2; *cmnd && isspace (*cmnd); cmnd++)
4385 ;
4386 if (*cmnd)
4387 {
4388 extern char **environ;
4389 char **save_env = environ;
4390 int save_system_flags = __system_flags;
4391
4392 4393
4394 __system_flags = (__system_redirect
4395 | __system_use_shell
4396 | __system_allow_multiple_cmds
4397 | __system_allow_long_cmds
4398 | __system_handle_null_commands
4399 | __system_emulate_chdir);
4400
4401 environ = envv;
4402 result = system (cmnd);
4403 __system_flags = save_system_flags;
4404 environ = save_env;
4405 }
4406 else
4407 result = 0;
4408 }
4409 else
4410 result = spawnve (P_WAIT, argv[0], argv, envv);
4411
4412 dup2 (inbak, 0);
4413 dup2 (outbak, 1);
4414 dup2 (errbak, 2);
4415 emacs_close (inbak);
4416 emacs_close (outbak);
4417 emacs_close (errbak);
4418
4419 if (!noninteractive)
4420 dos_ttraw (CURTTY ());
4421 if (have_mouse > 0)
4422 {
4423 mouse_init ();
4424 mouse_moveto (x, y);
4425 }
4426
4427 4428 4429
4430 if (!noninteractive)
4431 bright_bg ();
4432
4433 done:
4434 chdir (oldwd);
4435 if (msshell)
4436 {
4437 argv[1] = saveargv1;
4438 argv[2] = saveargv2;
4439 }
4440 return result;
4441 }
4442
4443 void
4444 croak (badfunc)
4445 char *badfunc;
4446 {
4447 fprintf (stderr, "%s not yet implemented\r\n", badfunc);
4448 reset_all_sys_modes ();
4449 exit (1);
4450 }
4451
4452 4453 4454
4455 setpgrp () {return 0; }
4456 setpriority (x,y,z) int x,y,z; { return 0; }
4457
4458 #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
4459
4460 4461
4462
4463 #include <libc/bss.h>
4464
4465
4466 static int sigprocmask_count = -1;
4467
4468
4469 static sigset_t current_mask;
4470
4471
4472 static sigset_t msdos_pending_signals;
4473
4474
4475 typedef void (*sighandler_t)(int);
4476 static sighandler_t prev_handlers[320];
4477
4478 4479
4480 static void
4481 sig_suspender (signo)
4482 int signo;
4483 {
4484 sigaddset (&msdos_pending_signals, signo);
4485 }
4486
4487 int
4488 sigprocmask (how, new_set, old_set)
4489 int how;
4490 const sigset_t *new_set;
4491 sigset_t *old_set;
4492 {
4493 int signo;
4494 sigset_t new_mask;
4495
4496
4497 if (sigprocmask_count != __bss_count)
4498 {
4499 sigprocmask_count = __bss_count;
4500 sigemptyset (&msdos_pending_signals);
4501 sigemptyset (¤t_mask);
4502 for (signo = 0; signo < 320; signo++)
4503 prev_handlers[signo] = SIG_ERR;
4504 }
4505
4506 if (old_set)
4507 *old_set = current_mask;
4508
4509 if (new_set == 0)
4510 return 0;
4511
4512 if (how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK)
4513 {
4514 errno = EINVAL;
4515 return -1;
4516 }
4517
4518 sigemptyset (&new_mask);
4519
4520
4521 for (signo = 0; signo < 320; signo++)
4522 {
4523 if (sigismember (¤t_mask, signo))
4524 sigaddset (&new_mask, signo);
4525 else if (sigismember (new_set, signo) && how != SIG_UNBLOCK)
4526 {
4527 sigaddset (&new_mask, signo);
4528
4529
4530 if (signo != SIGKILL && prev_handlers[signo] == SIG_ERR)
4531 prev_handlers[signo] = signal (signo, sig_suspender);
4532 }
4533 if (( how == SIG_UNBLOCK
4534 && sigismember (&new_mask, signo)
4535 && sigismember (new_set, signo))
4536 || (how == SIG_SETMASK
4537 && sigismember (&new_mask, signo)
4538 && !sigismember (new_set, signo)))
4539 {
4540 sigdelset (&new_mask, signo);
4541 if (prev_handlers[signo] != SIG_ERR)
4542 {
4543 signal (signo, prev_handlers[signo]);
4544 prev_handlers[signo] = SIG_ERR;
4545 }
4546 if (sigismember (&msdos_pending_signals, signo))
4547 {
4548 sigdelset (&msdos_pending_signals, signo);
4549 raise (signo);
4550 }
4551 }
4552 }
4553 current_mask = new_mask;
4554 return 0;
4555 }
4556
4557 #endif
4558
4559 #ifndef HAVE_SELECT
4560 #include "sysselect.h"
4561
4562 #ifndef EMACS_TIME_ZERO_OR_NEG_P
4563 #define EMACS_TIME_ZERO_OR_NEG_P(time) \
4564 ((long)(time).tv_sec < 0 \
4565 || ((time).tv_sec == 0 \
4566 && (long)(time).tv_usec <= 0))
4567 #endif
4568
4569 4570 4571 4572 4573 4574 4575
4576
4577 void
4578 dos_yield_time_slice (void)
4579 {
4580 _go32_dpmi_registers r;
4581
4582 r.x.ax = 0x1680;
4583 r.x.ss = r.x.sp = r.x.flags = 0;
4584 _go32_dpmi_simulate_int (0x2f, &r);
4585 if (r.h.al == 0x80)
4586 errno = ENOSYS;
4587 }
4588
4589
4590 4591
4592 int
4593 sys_select (nfds, rfds, wfds, efds, timeout)
4594 int nfds;
4595 SELECT_TYPE *rfds, *wfds, *efds;
4596 EMACS_TIME *timeout;
4597 {
4598 int check_input;
4599 struct time t;
4600
4601 check_input = 0;
4602 if (rfds)
4603 {
4604 check_input = FD_ISSET (0, rfds);
4605 FD_ZERO (rfds);
4606 }
4607 if (wfds)
4608 FD_ZERO (wfds);
4609 if (efds)
4610 FD_ZERO (efds);
4611
4612 if (nfds != 1)
4613 abort ();
4614
4615 4616
4617 if (!timeout)
4618 {
4619 while (!detect_input_pending ())
4620 {
4621 dos_yield_time_slice ();
4622 }
4623 }
4624 else
4625 {
4626 EMACS_TIME clnow, cllast, cldiff;
4627
4628 gettime (&t);
4629 EMACS_SET_SECS_USECS (cllast, t.ti_sec, t.ti_hund * 10000L);
4630
4631 while (!check_input || !detect_input_pending ())
4632 {
4633 gettime (&t);
4634 EMACS_SET_SECS_USECS (clnow, t.ti_sec, t.ti_hund * 10000L);
4635 EMACS_SUB_TIME (cldiff, clnow, cllast);
4636
4637 4638
4639 if (EMACS_TIME_NEG_P (cldiff))
4640 EMACS_SET_SECS (cldiff, EMACS_SECS (cldiff) + 60);
4641 EMACS_SUB_TIME (*timeout, *timeout, cldiff);
4642
4643
4644 if (EMACS_TIME_ZERO_OR_NEG_P (*timeout))
4645 return 0;
4646 cllast = clnow;
4647 dos_yield_time_slice ();
4648 }
4649 }
4650
4651 FD_SET (0, rfds);
4652 return 1;
4653 }
4654 #endif
4655
4656 4657 4658 4659 4660 4661 4662
4663
4664 #ifdef chdir
4665 #undef chdir
4666 extern int chdir ();
4667
4668 int
4669 sys_chdir (path)
4670 const char* path;
4671 {
4672 int len = strlen (path);
4673 char *tmp = (char *)path;
4674
4675 if (*tmp && tmp[1] == ':')
4676 {
4677 if (getdisk () != tolower (tmp[0]) - 'a')
4678 setdisk (tolower (tmp[0]) - 'a');
4679 tmp += 2;
4680 len -= 2;
4681 }
4682
4683 if (len > 1 && (tmp[len - 1] == '/'))
4684 {
4685 char *tmp1 = (char *) alloca (len + 1);
4686 strcpy (tmp1, tmp);
4687 tmp1[len - 1] = 0;
4688 tmp = tmp1;
4689 }
4690 return chdir (tmp);
4691 }
4692 #endif
4693
4694 #ifdef tzset
4695 #undef tzset
4696 extern void tzset (void);
4697
4698 void
4699 init_gettimeofday ()
4700 {
4701 time_t ltm, gtm;
4702 struct tm *lstm;
4703
4704 tzset ();
4705 ltm = gtm = time (NULL);
4706 ltm = mktime (lstm = localtime (<m));
4707 gtm = mktime (gmtime (>m));
4708 time_rec.tm_hour = 99;
4709 time_rec.tm_isdst = lstm->tm_isdst;
4710 dos_timezone_offset = time_rec.tm_gmtoff = (int)(gtm - ltm) / 60;
4711 }
4712 #endif
4713
4714 #ifdef abort
4715 #undef abort
4716 void
4717 dos_abort (file, line)
4718 char *file;
4719 int line;
4720 {
4721 char buffer1[200], buffer2[400];
4722 int i, j;
4723
4724 sprintf (buffer1, "<EMACS FATAL ERROR IN %s LINE %d>", file, line);
4725 for (i = j = 0; buffer1[i]; i++) {
4726 buffer2[j++] = buffer1[i];
4727 buffer2[j++] = 0x70;
4728 }
4729 dosmemput (buffer2, j, (int)ScreenPrimary);
4730 ScreenSetCursor (2, 0);
4731 abort ();
4732 }
4733 #else
4734 void
4735 abort ()
4736 {
4737 dos_ttcooked ();
4738 ScreenSetCursor (10, 0);
4739 cputs ("\r\n\nEmacs aborted!\r\n");
4740 #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
4741 if (screen_virtual_segment)
4742 dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X);
4743
4744 signal (SIGINT, SIG_DFL);
4745 __asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception");
4746 #else
4747 raise (SIGABRT);
4748 #endif
4749 exit (2);
4750 }
4751 #endif
4752
4753 4754
4755 #ifndef subprocesses
4756
4757 static int delete_exited_processes;
4758 #endif
4759
4760 syms_of_msdos ()
4761 {
4762 recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil);
4763 staticpro (&recent_doskeys);
4764
4765 #ifndef HAVE_X_WINDOWS
4766
4767
4768 Qreverse = intern ("reverse");
4769 staticpro (&Qreverse);
4770
4771 DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph,
4772 doc: 4773 );
4774 Vdos_unsupported_char_glyph = make_number ('\177');
4775
4776 #endif
4777 #ifndef subprocesses
4778 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
4779 doc: 4780 );
4781 delete_exited_processes = 0;
4782 #endif
4783
4784 defsubr (&Srecent_doskeys);
4785 defsubr (&Smsdos_long_file_names);
4786 defsubr (&Smsdos_downcase_filename);
4787 defsubr (&Smsdos_remember_default_colors);
4788 defsubr (&Smsdos_set_mouse_buttons);
4789 }
4790
4791 #endif
4792
4793 4794