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