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