#include <config.h>
#ifdef MSDOS
#include "lisp.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/param.h>
#include <sys/time.h>
#include <dos.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dir.h>
#if __DJGPP__ >= 2
#pragma pack(0)
#include <fcntl.h>
#include <io.h>
#include <dpmi.h>
#include <sys/farptr.h>
#include <libc/dosio.h>
#include <conio.h>
#endif
#include "msdos.h"
#include "systime.h"
#include "termhooks.h"
#include "termchar.h"
#include "dispextern.h"
#include "dosfns.h"
#include "termopts.h"
#include "charset.h"
#include "coding.h"
#include "disptab.h"
#include "frame.h"
#include "window.h"
#include "buffer.h"
#include "commands.h"
#include "blockinput.h"
#include "keyboard.h"
#include "intervals.h"
#include <go32.h>
#include <pc.h>
#include <ctype.h>
#define P_WAIT 1
#ifndef _USE_LFN
#define _USE_LFN 0
#endif
#ifndef _dos_ds
#define _dos_ds _go32_info_block.selector_for_linear_memory
#endif
#if __DJGPP__ > 1
#include <signal.h>
#include "syssignal.h"
#ifndef SYSTEM_MALLOC
#ifdef GNU_MALLOC
#include <crt0.h>
#ifdef REL_ALLOC
int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
#else
int _crt0_startup_flags = (_CRT0_FLAG_UNIX_SBRK | _CRT0_FLAG_FILL_SBRK_MEMORY);
#endif
#endif
#endif
#endif
static unsigned long
event_timestamp ()
{
struct time t;
unsigned long s;
gettime (&t);
s = t.ti_min;
s *= 60;
s += t.ti_sec;
s *= 1000;
s += t.ti_hund * 10;
return s;
}
#define NUM_MOUSE_BUTTONS (5)
int have_mouse;
static int mouse_visible;
static int mouse_last_x;
static int mouse_last_y;
static int mouse_button_translate[NUM_MOUSE_BUTTONS];
static int mouse_button_count;
void
mouse_on ()
{
union REGS regs;
if (have_mouse > 0 && !mouse_visible)
{
if (termscript)
fprintf (termscript, "<M_ON>");
regs.x.ax = 0x0001;
int86 (0x33, ®s, ®s);
mouse_visible = 1;
}
}
void
mouse_off ()
{
union REGS regs;
if (have_mouse > 0 && mouse_visible)
{
if (termscript)
fprintf (termscript, "<M_OFF>");
regs.x.ax = 0x0002;
int86 (0x33, ®s, ®s);
mouse_visible = 0;
}
}
static void
mouse_setup_buttons (int n_buttons)
{
if (n_buttons == 3)
{
mouse_button_count = 3;
mouse_button_translate[0] = 0;
mouse_button_translate[1] = 2;
mouse_button_translate[2] = 1;
}
else
{
mouse_button_count = 2;
mouse_button_translate[0] = 0;
mouse_button_translate[1] = 1;
}
}
DEFUN ("msdos-set-mouse-buttons", Fmsdos_set_mouse_buttons, Smsdos_set_mouse_buttons,
1, 1, "NSet number of mouse buttons to: ",
doc: )
(nbuttons)
Lisp_Object nbuttons;
{
int n;
CHECK_NUMBER (nbuttons);
n = XINT (nbuttons);
if (n < 2 || n > 3)
xsignal2 (Qargs_out_of_range,
build_string ("only 2 or 3 mouse buttons are supported"),
nbuttons);
mouse_setup_buttons (n);
return Qnil;
}
static void
mouse_get_xy (int *x, int *y)
{
union REGS regs;
regs.x.ax = 0x0003;
int86 (0x33, ®s, ®s);
*x = regs.x.cx / 8;
*y = regs.x.dx / 8;
}
void
mouse_moveto (x, y)
int x, y;
{
union REGS regs;
if (termscript)
fprintf (termscript, "<M_XY=%dx%d>", x, y);
regs.x.ax = 0x0004;
mouse_last_x = regs.x.cx = x * 8;
mouse_last_y = regs.x.dx = y * 8;
int86 (0x33, ®s, ®s);
}
static int
mouse_pressed (b, xp, yp)
int b, *xp, *yp;
{
union REGS regs;
if (b >= mouse_button_count)
return 0;
regs.x.ax = 0x0005;
regs.x.bx = mouse_button_translate[b];
int86 (0x33, ®s, ®s);
if (regs.x.bx)
*xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
return (regs.x.bx != 0);
}
static int
mouse_released (b, xp, yp)
int b, *xp, *yp;
{
union REGS regs;
if (b >= mouse_button_count)
return 0;
regs.x.ax = 0x0006;
regs.x.bx = mouse_button_translate[b];
int86 (0x33, ®s, ®s);
if (regs.x.bx)
*xp = regs.x.cx / 8, *yp = regs.x.dx / 8;
return (regs.x.bx != 0);
}
static int
mouse_button_depressed (b, xp, yp)
int b, *xp, *yp;
{
union REGS regs;
if (b >= mouse_button_count)
return 0;
regs.x.ax = 0x0003;
int86 (0x33, ®s, ®s);
if ((regs.x.bx & (1 << mouse_button_translate[b])) != 0)
{
*xp = regs.x.cx / 8;
*yp = regs.x.dx / 8;
return 1;
}
return 0;
}
void
mouse_get_pos (f, insist, bar_window, part, x, y, time)
FRAME_PTR *f;
int insist;
Lisp_Object *bar_window, *x, *y;
enum scroll_bar_part *part;
unsigned long *time;
{
int ix, iy;
Lisp_Object frame, tail;
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->mouse_moved = 0;
*f = SELECTED_FRAME();
*bar_window = Qnil;
mouse_get_xy (&ix, &iy);
*time = event_timestamp ();
*x = make_number (mouse_last_x = ix);
*y = make_number (mouse_last_y = iy);
}
static void
mouse_check_moved ()
{
int x, y;
mouse_get_xy (&x, &y);
SELECTED_FRAME()->mouse_moved |= (x != mouse_last_x || y != mouse_last_y);
mouse_last_x = x;
mouse_last_y = y;
}
static void
mouse_clear_clicks (void)
{
int b;
for (b = 0; b < mouse_button_count; b++)
{
int dummy_x, dummy_y;
(void) mouse_pressed (b, &dummy_x, &dummy_y);
(void) mouse_released (b, &dummy_x, &dummy_y);
}
}
void
mouse_init ()
{
union REGS regs;
if (termscript)
fprintf (termscript, "<M_INIT>");
regs.x.ax = 0x0021;
int86 (0x33, ®s, ®s);
mouse_clear_clicks ();
regs.x.ax = 0x0007;
regs.x.cx = 0;
regs.x.dx = 8 * (ScreenCols () - 1);
int86 (0x33, ®s, ®s);
regs.x.ax = 0x0008;
regs.x.cx = 0;
regs.x.dx = 8 * (ScreenRows () - 1);
int86 (0x33, ®s, ®s);
mouse_moveto (0, 0);
mouse_visible = 0;
}
static int internal_terminal = 0;
#ifndef HAVE_X_WINDOWS
extern unsigned char ScreenAttrib;
static int screen_face;
static int screen_size_X;
static int screen_size_Y;
static int screen_size;
static int current_pos_X;
static int current_pos_Y;
static int new_pos_X;
static int new_pos_Y;
static void *startup_screen_buffer;
static int startup_screen_size_X;
static int startup_screen_size_Y;
static int startup_pos_X;
static int startup_pos_Y;
static unsigned char startup_screen_attrib;
static clock_t startup_time;
static int term_setup_done;
static unsigned short outside_cursor;
struct x_output the_only_x_display;
static unsigned long screen_old_address = 0;
static unsigned short screen_virtual_segment = 0;
static unsigned short screen_virtual_offset = 0;
extern int unibyte_display_via_language_environment;
extern Lisp_Object Qcursor_type;
extern Lisp_Object Qbar, Qhbar;
static int initial_screen_colors[2];
#if __DJGPP__ > 1
static void
dosv_refresh_virtual_screen (int offset, int count)
{
__dpmi_regs regs;
if (offset < 0 || count < 0)
return;
regs.h.ah = 0xff;
regs.x.es = screen_virtual_segment;
regs.x.di = screen_virtual_offset + offset;
regs.x.cx = count;
__dpmi_int (0x10, ®s);
}
#endif
static void
dos_direct_output (y, x, buf, len)
int x, y;
char *buf;
int len;
{
int t0 = 2 * (x + y * screen_size_X);
int t = t0 + (int) ScreenPrimary;
int l0 = len;
#if (__DJGPP__ < 2)
while (--len >= 0) {
dosmemput (buf++, 1, t);
t += 2;
}
#else
for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++)
_farnspokeb (t, *buf);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (t0, l0);
#endif
}
#endif
#if (__DJGPP__ < 2)
static void
do_visible_bell (xorattr)
unsigned char xorattr;
{
asm volatile
(" movb $1,%%dl \n\
visible_bell_0: \n\
movl _ScreenPrimary,%%eax \n\
call dosmemsetup \n\
movl %%eax,%%ebx \n\
movl %1,%%ecx \n\
movb %0,%%al \n\
incl %%ebx \n\
visible_bell_1: \n\
xorb %%al,%%gs:(%%ebx) \n\
addl $2,%%ebx \n\
decl %%ecx \n\
jne visible_bell_1 \n\
decb %%dl \n\
jne visible_bell_3 \n\
visible_bell_2: \n\
movzwl %%ax,%%eax \n\
movzwl %%ax,%%eax \n\
movzwl %%ax,%%eax \n\
movzwl %%ax,%%eax \n\
decw %%cx \n\
jne visible_bell_2 \n\
jmp visible_bell_0 \n\
visible_bell_3:"
:
: "m" (xorattr), "g" (screen_size)
: "%eax", "%ebx", "%ecx", "%edx");
}
static void
ScreenVisualBell (void)
{
do_visible_bell (((the_only_x_display.foreground_pixel
^ the_only_x_display.background_pixel)
* 0x11) & 0x7f);
}
#endif
#ifndef HAVE_X_WINDOWS
static int blink_bit = -1;
static void
bright_bg (void)
{
union REGS regs;
if (blink_bit == -1)
blink_bit = (_farpeekb (_dos_ds, 0x465) & 0x20) == 0x20;
regs.h.bl = 0;
regs.x.ax = 0x1003;
int86 (0x10, ®s, ®s);
}
static void
maybe_enable_blinking (void)
{
if (blink_bit == 1)
{
union REGS regs;
regs.h.bl = 1;
regs.x.ax = 0x1003;
int86 (0x10, ®s, ®s);
}
}
static int
vga_installed (void)
{
union REGS regs;
regs.x.ax = 0x1a00;
int86 (0x10, ®s, ®s);
if (regs.h.al == 0x1a && regs.h.bl > 5 && regs.h.bl < 13)
return 1;
return 0;
}
void
dos_set_window_size (rows, cols)
int *rows, *cols;
{
char video_name[30];
union REGS regs;
Lisp_Object video_mode;
int video_mode_value, have_vga = 0;
int current_rows = ScreenRows (), current_cols = ScreenCols ();
if (*rows == current_rows && *cols == current_cols)
return;
mouse_off ();
have_vga = vga_installed ();
sprintf (video_name, "screen-dimensions-%dx%d", *rows, *cols);
video_mode = XSYMBOL (Fintern_soft (build_string (video_name),
Qnil))-> value;
if (INTEGERP (video_mode)
&& (video_mode_value = XINT (video_mode)) > 0)
{
regs.x.ax = video_mode_value;
int86 (0x10, ®s, ®s);
if (have_mouse)
{
regs.x.ax = 0;
int86 (0x33, ®s, ®s);
}
}
#if __DJGPP__ > 1
else
{
static struct {
int rows, need_vga;
} std_dimension[] = {
{25, 0},
{28, 1},
{35, 0},
{40, 1},
{43, 0},
{50, 1}
};
int i = 0;
while (i < sizeof (std_dimension) / sizeof (std_dimension[0]))
{
if (std_dimension[i].need_vga <= have_vga
&& std_dimension[i].rows >= *rows)
{
if (std_dimension[i].rows != current_rows
|| *cols != current_cols)
_set_screen_lines (std_dimension[i].rows);
break;
}
i++;
}
}
#else
else if (*rows <= 25)
{
if (current_rows != 25 || current_cols != 80)
{
regs.x.ax = 3;
int86 (0x10, ®s, ®s);
regs.x.ax = 0x1101;
regs.h.bl = 0;
int86 (0x10, ®s, ®s);
regs.x.ax = 0x1200;
regs.h.bl = 32;
int86 (0x10, ®s, ®s);
regs.x.ax = 3;
int86 (0x10, ®s, ®s);
}
}
else if (*rows <= 50)
if (have_vga && (current_rows != 50 || current_cols != 80)
|| *rows <= 43 && (current_rows != 43 || current_cols != 80))
{
regs.x.ax = 3;
int86 (0x10, ®s, ®s);
regs.x.ax = 0x1112;
regs.h.bl = 0;
int86 (0x10, ®s, ®s);
regs.x.ax = 0x1200;
regs.h.bl = 32;
int86 (0x10, ®s, ®s);
regs.x.ax = 0x0100;
regs.x.cx = 7;
int86 (0x10, ®s, ®s);
}
#endif
if (have_mouse)
{
mouse_init ();
mouse_on ();
}
*rows = ScreenRows ();
*cols = ScreenCols ();
screen_size_X = *cols;
screen_size_Y = *rows;
screen_size = *cols * *rows;
#if __DJGPP__ > 1
if (current_rows != *rows || current_cols != *cols)
{
struct frame *f = SELECTED_FRAME();
struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Lisp_Object window = dpyinfo->mouse_face_window;
if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
{
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
}
}
#endif
bright_bg ();
if (screen_virtual_segment)
dosv_refresh_virtual_screen (0, *cols * *rows);
}
static void
mouse_off_maybe ()
{
int x, y;
if (!mouse_visible)
return;
mouse_get_xy (&x, &y);
if (y != new_pos_Y || x < new_pos_X)
return;
mouse_off ();
}
#define DEFAULT_CURSOR_START (-1)
#define DEFAULT_CURSOR_WIDTH (-1)
#define BOX_CURSOR_WIDTH (-32)
static void
msdos_set_cursor_shape (struct frame *f, int start_line, int width)
{
#if __DJGPP__ > 1
unsigned desired_cursor;
__dpmi_regs regs;
int max_line, top_line, bot_line;
if (f && f != SELECTED_FRAME())
return;
if (termscript)
fprintf (termscript, "\nCURSOR SHAPE=(%d,%d)", start_line, width);
max_line = _farpeekw (_dos_ds, 0x485) - 1;
switch (max_line)
{
default:
case 7:
bot_line = 7;
break;
case 9:
bot_line = 9;
break;
case 13:
bot_line = 12;
break;
case 15:
bot_line = 14;
break;
}
if (width < 0)
{
if (width == BOX_CURSOR_WIDTH)
{
top_line = 0;
bot_line = max_line;
}
else if (start_line != DEFAULT_CURSOR_START)
{
top_line = start_line;
bot_line = top_line - width - 1;
}
else if (width != DEFAULT_CURSOR_WIDTH)
{
top_line = 0;
bot_line = -1 - width;
}
else
top_line = bot_line + 1;
}
else if (width == 0)
{
top_line = 31;
bot_line = 0;
}
else
{
if (start_line != DEFAULT_CURSOR_START)
bot_line = start_line;
top_line = bot_line - (width - 1);
}
desired_cursor = ((top_line & 0x1f) << 8) | (bot_line & 0x1f);
if (desired_cursor == _farpeekw (_dos_ds, 0x460))
return;
regs.h.ah = 1;
regs.x.cx = desired_cursor;
__dpmi_int (0x10, ®s);
#endif
}
static void
IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type)
{
if (EQ (cursor_type, Qbar) || EQ (cursor_type, Qhbar))
{
msdos_set_cursor_shape (f, DEFAULT_CURSOR_START, DEFAULT_CURSOR_WIDTH);
}
else if (CONSP (cursor_type)
&& (EQ (XCAR (cursor_type), Qbar)
|| EQ (XCAR (cursor_type), Qhbar)))
{
Lisp_Object bar_parms = XCDR (cursor_type);
int width;
if (INTEGERP (bar_parms))
{
width = XINT (bar_parms);
msdos_set_cursor_shape (f, width >= 0 ? DEFAULT_CURSOR_START : 0,
width);
}
else if (CONSP (bar_parms)
&& INTEGERP (XCAR (bar_parms))
&& INTEGERP (XCDR (bar_parms)))
{
int start_line = XINT (XCDR (bar_parms));
width = XINT (XCAR (bar_parms));
msdos_set_cursor_shape (f, start_line, width);
}
}
else
{
msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH);
}
}
static void
IT_ring_bell (void)
{
if (visible_bell)
{
mouse_off ();
ScreenVisualBell ();
}
else
{
union REGS inregs, outregs;
inregs.h.ah = 2;
inregs.h.dl = 7;
intdos (&inregs, &outregs);
}
}
static void
IT_set_face (int face)
{
struct frame *sf = SELECTED_FRAME();
struct face *fp = FACE_FROM_ID (sf, face);
struct face *dfp = FACE_FROM_ID (sf, DEFAULT_FACE_ID);
unsigned long fg, bg, dflt_fg, dflt_bg;
if (!fp)
{
fp = dfp;
if (!fp)
abort ();
}
screen_face = face;
fg = fp->foreground;
bg = fp->background;
dflt_fg = dfp->foreground;
dflt_bg = dfp->background;
if (fg == FACE_TTY_DEFAULT_COLOR || fg == FACE_TTY_DEFAULT_FG_COLOR)
fg = FRAME_FOREGROUND_PIXEL (sf);
else if (fg == FACE_TTY_DEFAULT_BG_COLOR)
fg = FRAME_BACKGROUND_PIXEL (sf);
if (bg == FACE_TTY_DEFAULT_COLOR || bg == FACE_TTY_DEFAULT_BG_COLOR)
bg = FRAME_BACKGROUND_PIXEL (sf);
else if (bg == FACE_TTY_DEFAULT_FG_COLOR)
bg = FRAME_FOREGROUND_PIXEL (sf);
if (fp->tty_reverse_p && (fg == dflt_fg && bg == dflt_bg))
{
unsigned long tem = fg;
fg = bg;
bg = tem;
}
if (inverse_video)
{
unsigned long tem2 = fg;
fg = bg;
bg = tem2;
}
if (termscript)
fprintf (termscript, "<FACE %d: %d/%d[FG:%d/BG:%d]>", face,
fp->foreground, fp->background, fg, bg);
if (fg >= 0 && fg < 16)
{
ScreenAttrib &= 0xf0;
ScreenAttrib |= fg;
}
if (bg >= 0 && bg < 16)
{
ScreenAttrib &= 0x0f;
ScreenAttrib |= ((bg & 0x0f) << 4);
}
}
Lisp_Object Vdos_unsupported_char_glyph;
static void
IT_write_glyphs (struct glyph *str, int str_len)
{
unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp;
int unsupported_face = 0;
unsigned unsupported_char = '\177';
int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
register int sl = str_len;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
struct coding_system *coding =
(terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
? &terminal_coding
: &safe_terminal_coding);
struct frame *sf;
int convert_unibyte_characters
= (NILP (current_buffer->enable_multibyte_characters)
&& unibyte_display_via_language_environment);
unsigned char conversion_buffer[256];
int conversion_buffer_size = sizeof conversion_buffer;
if (str_len <= 0) return;
if (!NILP (Vdos_unsupported_char_glyph))
{
unsupported_char = FAST_GLYPH_CHAR (XINT (Vdos_unsupported_char_glyph));
unsupported_face = FAST_GLYPH_FACE (XINT (Vdos_unsupported_char_glyph));
}
screen_buf = screen_bp = alloca (str_len * 2);
screen_buf_end = screen_buf + str_len * 2;
sf = SELECTED_FRAME();
IT_set_face (DEFAULT_FACE_ID);
terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
while (sl)
{
int cf, chlen, enclen;
unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *buf;
unsigned ch;
if (CHAR_GLYPH_PADDING_P (*str))
{
str++;
sl--;
}
else
{
register GLYPH g = GLYPH_FROM_CHAR_GLYPH (*str);
int glyph_not_in_table = 0;
if (g < 0 || g >= tlen)
{
ch = str->u.ch;
glyph_not_in_table = 1;
}
else
{
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
ch = FAST_GLYPH_CHAR (g);
}
if (SINGLE_BYTE_CHAR_P (ch) && convert_unibyte_characters
&& (ch >= 0240
|| (ch >= 0200 && !NILP (Vnonascii_translation_table))))
ch = unibyte_char_to_multibyte (ch);
if (! CHAR_VALID_P (ch, 0))
{
g = !NILP (Vdos_unsupported_char_glyph)
? XINT (Vdos_unsupported_char_glyph)
: MAKE_GLYPH (sf, '\177', GLYPH_FACE (sf, g));
ch = FAST_GLYPH_CHAR (g);
}
cf = str->face_id;
if (cf != screen_face)
IT_set_face (cf);
if (glyph_not_in_table || GLYPH_SIMPLE_P (tbase, tlen, g))
{
chlen = CHAR_STRING (ch, workbuf);
buf = workbuf;
}
else
{
chlen = GLYPH_LENGTH (tbase, g);
buf = GLYPH_STRING (tbase, g);
}
if (chlen == 1)
{
*conversion_buffer = (unsigned char)ch;
chlen = 0;
enclen = 1;
}
else
{
coding->src_multibyte = 1;
encode_coding (coding, buf, conversion_buffer, chlen,
conversion_buffer_size);
chlen -= coding->consumed;
enclen = coding->produced;
if (*conversion_buffer == '?')
{
unsigned char *cbp = conversion_buffer;
while (cbp < conversion_buffer + enclen && *cbp == '?')
*cbp++ = unsupported_char;
if (unsupported_face != screen_face)
IT_set_face (unsupported_face);
}
}
if (enclen + chlen > screen_buf_end - screen_bp)
{
int nbytes = screen_bp - screen_buf;
mouse_off_maybe ();
dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (offset, nbytes / 2);
new_pos_X += nbytes / 2;
offset += nbytes;
screen_bp = screen_buf;
}
else
{
for (bp = conversion_buffer; enclen--; bp++)
{
*screen_bp++ = (unsigned char)*bp;
*screen_bp++ = ScreenAttrib;
if (termscript)
fputc (*bp, termscript);
}
if (chlen > 0)
{
buf += coding->consumed;
while (chlen--)
{
if (termscript)
fputc (*buf, termscript);
*screen_bp++ = (unsigned char)*buf++;
*screen_bp++ = ScreenAttrib;
}
}
str++;
sl--;
}
}
}
mouse_off_maybe ();
dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2);
new_pos_X += (screen_bp - screen_buf) / 2;
if (CODING_REQUIRE_FLUSHING (coding))
{
coding->mode |= CODING_MODE_LAST_BLOCK;
encode_coding (coding, "", conversion_buffer, 0, conversion_buffer_size);
if (coding->produced > 0)
{
screen_buf = alloca (coding->produced * 2);
for (screen_bp = screen_buf, bp = conversion_buffer;
coding->produced--; bp++)
{
*screen_bp++ = (unsigned char)*bp;
*screen_bp++ = ScreenAttrib;
if (termscript)
fputc (*bp, termscript);
}
offset += screen_bp - screen_buf;
mouse_off_maybe ();
dosmemput (screen_buf, screen_bp - screen_buf,
(int)ScreenPrimary + offset);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2);
new_pos_X += (screen_bp - screen_buf) / 2;
}
}
}
static Lisp_Object last_mouse_window;
static int mouse_preempted = 0;
static void
IT_set_mouse_pointer (int mode)
{
}
static void
show_mouse_face (struct display_info *dpyinfo, int hl)
{
struct window *w = XWINDOW (dpyinfo->mouse_face_window);
struct frame *f = XFRAME (WINDOW_FRAME (w));
int i;
struct face *fp;
if (w->current_matrix == NULL)
goto set_cursor_shape;
if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
goto set_cursor_shape;
if (hl > 0)
{
if (dpyinfo->mouse_face_hidden)
goto set_cursor_shape;
fp = FACE_FROM_ID (SELECTED_FRAME(), dpyinfo->mouse_face_face_id);
if (!fp)
goto set_cursor_shape;
}
for (i = dpyinfo->mouse_face_beg_row;
i <= dpyinfo->mouse_face_end_row;
i++)
{
int start_hpos, end_hpos;
struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
if (!row->enabled_p)
continue;
if (i == dpyinfo->mouse_face_beg_row)
start_hpos = dpyinfo->mouse_face_beg_col;
else
start_hpos = 0;
if (i == dpyinfo->mouse_face_end_row)
end_hpos = dpyinfo->mouse_face_end_col;
else
end_hpos = row->used[TEXT_AREA];
if (end_hpos <= start_hpos)
continue;
row->mouse_face_p = hl > 0;
if (hl > 0)
{
int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
int nglyphs = end_hpos - start_hpos;
int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
int start_offset = offset;
if (termscript)
fprintf (termscript, "\n<MH+ %d-%d:%d>",
kstart, kstart + nglyphs - 1, vpos);
mouse_off ();
IT_set_face (dpyinfo->mouse_face_face_id);
_farsetsel (_dos_ds);
while (nglyphs--)
{
_farnspokeb (offset, ScreenAttrib);
offset += 2;
}
if (screen_virtual_segment)
dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
mouse_on ();
}
else
{
int nglyphs = end_hpos - start_hpos;
int save_x = new_pos_X, save_y = new_pos_Y;
if (end_hpos >= row->used[TEXT_AREA])
nglyphs = row->used[TEXT_AREA] - start_hpos;
new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
if (termscript)
fprintf (termscript, "<MH- %d-%d:%d>",
new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
IT_write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
if (termscript)
fputs ("\n", termscript);
new_pos_X = save_x;
new_pos_Y = save_y;
}
}
set_cursor_shape:
IT_set_mouse_pointer (hl);
}
static void
clear_mouse_face (struct display_info *dpyinfo)
{
if (!dpyinfo->mouse_face_hidden && ! NILP (dpyinfo->mouse_face_window))
show_mouse_face (dpyinfo, 0);
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
}
static int
fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
{
int i, lastcol, line_start_position, maybe_next_line_p = 0;
int yb = window_text_bottom_y (w);
struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
while (row->y < yb)
{
if (row->used[TEXT_AREA])
line_start_position = row->glyphs[TEXT_AREA]->charpos;
else
line_start_position = 0;
if (line_start_position > pos)
break;
else if (line_start_position == pos
&& pos == BUF_ZV (XBUFFER (w->buffer)))
{
maybe_next_line_p = 1;
break;
}
else if (line_start_position > 0)
best_row = row;
if (row->y + 1 >= yb)
break;
++row;
}
lastcol = 0;
row = best_row;
for (i = 0; i < row->used[TEXT_AREA]; i++)
{
struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
int charpos;
charpos = glyph->charpos;
if (charpos == pos)
{
*hpos = i;
*vpos = row->y;
return 1;
}
else if (charpos > pos)
break;
else if (charpos > 0)
lastcol = i;
}
if (maybe_next_line_p)
{
++row;
lastcol = 0;
}
*vpos = row->y;
*hpos = lastcol + 1;
return 0;
}
static void
IT_note_mode_line_highlight (struct window *w, int x, int mode_line_p)
{
struct frame *f = XFRAME (w->frame);
struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
struct glyph_row *row;
if (mode_line_p)
row = MATRIX_MODE_LINE_ROW (w->current_matrix);
else
row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
if (row->enabled_p)
{
extern Lisp_Object Qhelp_echo;
struct glyph *glyph, *end;
Lisp_Object help, map;
glyph = (row->glyphs[TEXT_AREA]
+ x
- WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w));
end = glyph + row->used[TEXT_AREA];
if (glyph < end
&& STRINGP (glyph->object)
&& STRING_INTERVALS (glyph->object)
&& glyph->charpos >= 0
&& glyph->charpos < SCHARS (glyph->object))
{
help = Fget_text_property (make_number (glyph->charpos),
Qhelp_echo, glyph->object);
if (!NILP (help))
{
help_echo_string = help;
XSETWINDOW (help_echo_window, w);
help_echo_object = glyph->object;
help_echo_pos = glyph->charpos;
}
}
}
}
static void
IT_note_mouse_highlight (struct frame *f, int x, int y)
{
struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
enum window_part part = ON_NOTHING;
Lisp_Object window;
struct window *w;
if (mouse_preempted)
return;
if (NILP (Vmouse_highlight)
|| !f->glyphs_initialized_p)
return;
dpyinfo->mouse_face_mouse_x = x;
dpyinfo->mouse_face_mouse_y = y;
dpyinfo->mouse_face_mouse_frame = f;
if (dpyinfo->mouse_face_defer)
return;
if (gc_in_progress)
{
dpyinfo->mouse_face_deferred_gc = 1;
return;
}
window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
if (! EQ (window, dpyinfo->mouse_face_window))
clear_mouse_face (dpyinfo);
if (!WINDOWP (window))
return;
w = XWINDOW (window);
if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
{
IT_note_mode_line_highlight (w, x, part == ON_MODE_LINE);
return;
}
IT_set_mouse_pointer (0);
if (part == ON_TEXT
&& EQ (w->window_end_valid, w->buffer)
&& XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
&& (XFASTINT (w->last_overlay_modified)
== BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
{
int pos, i, nrows = w->current_matrix->nrows;
struct glyph_row *row;
struct glyph *glyph;
glyph = NULL;
if (y >= 0 && y < nrows)
{
row = MATRIX_ROW (w->current_matrix, y);
for (i = 0; i <= y; i++)
if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
break;
if (i > y
&& row->displays_text_p
&& x < window_box_width (w, TEXT_AREA))
{
glyph = row->glyphs[TEXT_AREA];
if (x >= row->used[TEXT_AREA])
glyph = NULL;
else
{
glyph += x;
if (!BUFFERP (glyph->object))
glyph = NULL;
}
}
}
if (glyph == NULL)
{
clear_mouse_face (dpyinfo);
return;
}
if (!BUFFERP (glyph->object))
abort ();
pos = glyph->charpos;
{
extern Lisp_Object Qmouse_face;
Lisp_Object mouse_face, overlay, position, *overlay_vec;
int noverlays, obegv, ozv;;
struct buffer *obuf;
if (pos > BUF_Z (XBUFFER (w->buffer)))
return;
obuf = current_buffer;
current_buffer = XBUFFER (w->buffer);
obegv = BEGV;
ozv = ZV;
BEGV = BEG;
ZV = Z;
XSETINT (position, pos);
GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
noverlays = sort_overlays (overlay_vec, noverlays, w);
if (! (EQ (window, dpyinfo->mouse_face_window)
&& y >= dpyinfo->mouse_face_beg_row
&& y <= dpyinfo->mouse_face_end_row
&& (y > dpyinfo->mouse_face_beg_row
|| x >= dpyinfo->mouse_face_beg_col)
&& (y < dpyinfo->mouse_face_end_row
|| x < dpyinfo->mouse_face_end_col
|| dpyinfo->mouse_face_past_end)))
{
clear_mouse_face (dpyinfo);
overlay = Qnil;
for (i = noverlays - 1; i >= 0; --i)
{
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
if (!NILP (mouse_face))
{
overlay = overlay_vec[i];
break;
}
}
if (NILP (overlay))
mouse_face = Fget_text_property (position, Qmouse_face,
w->buffer);
if (! NILP (overlay))
{
Lisp_Object before, after;
int ignore;
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
fast_find_position (w, XFASTINT (before),
&dpyinfo->mouse_face_beg_col,
&dpyinfo->mouse_face_beg_row);
dpyinfo->mouse_face_past_end
= !fast_find_position (w, XFASTINT (after),
&dpyinfo->mouse_face_end_col,
&dpyinfo->mouse_face_end_row);
dpyinfo->mouse_face_window = window;
dpyinfo->mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
&ignore, pos + 1,
!dpyinfo->mouse_face_hidden);
show_mouse_face (dpyinfo, 1);
}
else if (! NILP (mouse_face))
{
Lisp_Object before, after, beginning, end;
int ignore;
beginning = Fmarker_position (w->start);
XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
- XFASTINT (w->window_end_pos)));
before
= Fprevious_single_property_change (make_number (pos + 1),
Qmouse_face,
w->buffer, beginning);
after
= Fnext_single_property_change (position, Qmouse_face,
w->buffer, end);
fast_find_position (w, XFASTINT (before),
&dpyinfo->mouse_face_beg_col,
&dpyinfo->mouse_face_beg_row);
dpyinfo->mouse_face_past_end
= !fast_find_position (w, XFASTINT (after),
&dpyinfo->mouse_face_end_col,
&dpyinfo->mouse_face_end_row);
dpyinfo->mouse_face_window = window;
dpyinfo->mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
&ignore, pos + 1,
!dpyinfo->mouse_face_hidden);
show_mouse_face (dpyinfo, 1);
}
}
{
Lisp_Object help;
extern Lisp_Object Qhelp_echo;
help = Qnil;
for (i = noverlays - 1; i >= 0 && NILP (help); --i)
{
overlay = overlay_vec[i];
help = Foverlay_get (overlay, Qhelp_echo);
}
if (!NILP (help))
{
help_echo_string = help;
help_echo_window = window;
help_echo_object = overlay;
help_echo_pos = pos;
}
else if (NILP (help)
&& ((STRINGP (glyph->object)
&& glyph->charpos >= 0
&& glyph->charpos < SCHARS (glyph->object))
|| (BUFFERP (glyph->object)
&& glyph->charpos >= BEGV
&& glyph->charpos < ZV)))
{
help = Fget_text_property (make_number (glyph->charpos),
Qhelp_echo, glyph->object);
if (!NILP (help))
{
help_echo_string = help;
help_echo_window = window;
help_echo_object = glyph->object;
help_echo_pos = glyph->charpos;
}
}
}
BEGV = obegv;
ZV = ozv;
current_buffer = obuf;
}
}
}
static void
IT_clear_end_of_line (int first_unused)
{
char *spaces, *sp;
int i, j, offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
extern int fatal_error_in_progress;
if (new_pos_X >= first_unused || fatal_error_in_progress)
return;
IT_set_face (0);
i = (j = first_unused - new_pos_X) * 2;
if (termscript)
fprintf (termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused);
spaces = sp = alloca (i);
while (--j >= 0)
{
*sp++ = ' ';
*sp++ = ScreenAttrib;
}
mouse_off_maybe ();
dosmemput (spaces, i, (int)ScreenPrimary + offset);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (offset, i / 2);
new_pos_X = first_unused;
}
static void
IT_clear_screen (void)
{
if (termscript)
fprintf (termscript, "<CLR:SCR>");
if (FACE_FROM_ID (SELECTED_FRAME (), DEFAULT_FACE_ID) == NULL)
ScreenAttrib = (initial_screen_colors[0] << 4) | initial_screen_colors[1];
else
IT_set_face (0);
mouse_off ();
ScreenClear ();
if (screen_virtual_segment)
dosv_refresh_virtual_screen (0, screen_size);
new_pos_X = new_pos_Y = 0;
}
static void
IT_clear_to_end (void)
{
if (termscript)
fprintf (termscript, "<CLR:EOS>");
while (new_pos_Y < screen_size_Y) {
new_pos_X = 0;
IT_clear_end_of_line (screen_size_X);
new_pos_Y++;
}
}
static void
IT_cursor_to (int y, int x)
{
if (termscript)
fprintf (termscript, "\n<XY=%dx%d>", x, y);
new_pos_X = x;
new_pos_Y = y;
}
static int cursor_cleared;
static void
IT_display_cursor (int on)
{
if (termscript)
fprintf (termscript, "\nCURSOR %s", on ? "ON" : "OFF");
if (on && cursor_cleared)
{
ScreenSetCursor (current_pos_Y, current_pos_X);
cursor_cleared = 0;
}
else if (!on && !cursor_cleared)
{
ScreenSetCursor (-1, -1);
cursor_cleared = 1;
}
}
static void
IT_cmgoto (FRAME_PTR f)
{
int update_cursor_pos = 1;
#if 0
static int previous_pos_X = -1;
update_cursor_pos = 1;
if (update_cursor_pos && previous_pos_X >= 0)
previous_pos_X = -1;
if (!update_cursor_pos
&& WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f))) <= new_pos_Y)
{
int tem_X = current_pos_X, dummy;
if (echo_area_glyphs)
{
tem_X = echo_area_glyphs_length;
if (previous_pos_X == -1)
ScreenGetCursor (&dummy, &previous_pos_X);
}
else if (previous_pos_X >= 0)
{
tem_X = previous_pos_X;
previous_pos_X = -1;
}
if (current_pos_X != tem_X)
{
new_pos_X = tem_X;
update_cursor_pos = 1;
}
}
#endif
if (update_cursor_pos
&& (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y))
{
ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X);
if (termscript)
fprintf (termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y);
}
IT_display_cursor (1);
if (!mouse_visible)
mouse_on ();
}
static void
IT_update_begin (struct frame *f)
{
struct display_info *display_info = FRAME_X_DISPLAY_INFO (f);
struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame;
BLOCK_INPUT;
if (f && f == mouse_face_frame)
{
display_info->mouse_face_defer = 1;
if (FRAME_GARBAGED_P (f))
display_info->mouse_face_window = Qnil;
if (!NILP (display_info->mouse_face_window)
&& WINDOWP (display_info->mouse_face_window))
{
struct window *w = XWINDOW (display_info->mouse_face_window);
int i;
if (NILP (w->buffer))
display_info->mouse_face_window = Qnil;
else
{
for (i = 0; i < w->desired_matrix->nrows; ++i)
if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i)
&& MATRIX_ROW (w->current_matrix, i)->mouse_face_p)
break;
}
if (NILP (w->buffer) || i < w->desired_matrix->nrows)
clear_mouse_face (display_info);
}
}
else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
{
display_info->mouse_face_beg_row = display_info->mouse_face_beg_col = -1;
display_info->mouse_face_end_row = display_info->mouse_face_end_col = -1;
display_info->mouse_face_window = Qnil;
display_info->mouse_face_deferred_gc = 0;
display_info->mouse_face_mouse_frame = NULL;
}
UNBLOCK_INPUT;
}
static void
IT_update_end (struct frame *f)
{
FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
}
static void
IT_frame_up_to_date (struct frame *f)
{
struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Lisp_Object new_cursor, frame_desired_cursor;
struct window *sw;
if (dpyinfo->mouse_face_deferred_gc
|| (f && f == dpyinfo->mouse_face_mouse_frame))
{
BLOCK_INPUT;
if (dpyinfo->mouse_face_mouse_frame)
IT_note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
dpyinfo->mouse_face_mouse_x,
dpyinfo->mouse_face_mouse_y);
dpyinfo->mouse_face_deferred_gc = 0;
UNBLOCK_INPUT;
}
sw = XWINDOW (f->selected_window);
frame_desired_cursor = Fcdr (Fassq (Qcursor_type, f->param_alist));
if (cursor_in_echo_area
&& FRAME_HAS_MINIBUF_P (f)
&& EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)
&& sw == XWINDOW (echo_area_window))
new_cursor = frame_desired_cursor;
else
{
struct buffer *b = XBUFFER (sw->buffer);
if (EQ (b->cursor_type, Qt))
new_cursor = frame_desired_cursor;
else if (NILP (b->cursor_type))
new_cursor = Fcons (Qbar, make_number (0));
else
new_cursor = b->cursor_type;
}
IT_set_cursor_type (f, new_cursor);
IT_cmgoto (f);
}
static void
IT_copy_glyphs (int xfrom, int xto, size_t len, int ypos)
{
int from = 2 * (xfrom + screen_size_X * ypos) + ScreenPrimary;
int to = 2 * (xto + screen_size_X * ypos) + ScreenPrimary;
if (from == to || len <= 0)
return;
_farsetsel (_dos_ds);
if (from > to)
{
for ( ; len; from += 2, to += 2, len--)
_farnspokew (to, _farnspeekw (from));
}
else
{
from += (len - 1) * 2;
to += (len - 1) * 2;
for ( ; len; from -= 2, to -= 2, len--)
_farnspokew (to, _farnspeekw (from));
}
if (screen_virtual_segment)
dosv_refresh_virtual_screen (ypos * screen_size_X * 2, screen_size_X);
}
static void
IT_insert_glyphs (start, len)
register struct glyph *start;
register int len;
{
int shift_by_width = screen_size_X - (new_pos_X + len);
IT_copy_glyphs (new_pos_X, new_pos_X + len, shift_by_width, new_pos_Y);
IT_write_glyphs (start, len);
}
static void
IT_delete_glyphs (n)
register int n;
{
abort ();
}
void
x_set_menu_bar_lines (f, value, oldval)
struct frame *f;
Lisp_Object value, oldval;
{
set_menu_bar_lines (f, value, oldval);
}
extern Lisp_Object Qbackground_color;
extern Lisp_Object Qforeground_color;
Lisp_Object Qreverse;
extern Lisp_Object Qtitle;
static void
IT_set_terminal_modes (void)
{
if (termscript)
fprintf (termscript, "\n<SET_TERM>");
screen_size_X = ScreenCols ();
screen_size_Y = ScreenRows ();
screen_size = screen_size_X * screen_size_Y;
new_pos_X = new_pos_Y = 0;
current_pos_X = current_pos_Y = -1;
if (term_setup_done)
return;
term_setup_done = 1;
startup_screen_size_X = screen_size_X;
startup_screen_size_Y = screen_size_Y;
startup_screen_attrib = ScreenAttrib;
#if __DJGPP__ > 1
{
unsigned short es_value;
__dpmi_regs regs;
regs.h.ah = 0xfe;
if (ScreenPrimary == 0xb0000UL || ScreenPrimary == 0xb8000UL)
regs.x.es = (ScreenPrimary >> 4) & 0xffff;
else if (screen_old_address)
regs.x.es = (screen_old_address >> 4) & 0xffff;
else
regs.x.es = ScreenMode () == 7 ? 0xb000 : 0xb800;
regs.x.di = 0;
es_value = regs.x.es;
__dpmi_int (0x10, ®s);
if (regs.x.es != es_value)
{
if (regs.x.es != (ScreenPrimary >> 4) & 0xffff)
screen_old_address = ScreenPrimary;
screen_virtual_segment = regs.x.es;
screen_virtual_offset = regs.x.di;
ScreenPrimary = (screen_virtual_segment << 4) + screen_virtual_offset;
}
}
#endif
ScreenGetCursor (&startup_pos_Y, &startup_pos_X);
ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2));
if (termscript)
fprintf (termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n",
screen_size_X, screen_size_Y);
bright_bg ();
}
static void
IT_reset_terminal_modes (void)
{
int display_row_start = (int) ScreenPrimary;
int saved_row_len = startup_screen_size_X * 2;
int update_row_len = ScreenCols () * 2, current_rows = ScreenRows ();
int to_next_row = update_row_len;
unsigned char *saved_row = startup_screen_buffer;
int cursor_pos_X = ScreenCols () - 1, cursor_pos_Y = ScreenRows () - 1;
if (termscript)
fprintf (termscript, "\n<RESET_TERM>");
if (!term_setup_done)
return;
mouse_off ();
maybe_enable_blinking ();
ScreenAttrib = startup_screen_attrib;
if (clock () - startup_time >= 2*CLOCKS_PER_SEC)
{
ScreenClear ();
if (screen_virtual_segment)
dosv_refresh_virtual_screen (0, screen_size);
if (update_row_len > saved_row_len)
update_row_len = saved_row_len;
if (current_rows > startup_screen_size_Y)
current_rows = startup_screen_size_Y;
if (termscript)
fprintf (termscript, "<SCREEN RESTORED (dimensions=%dx%d)>\n",
update_row_len / 2, current_rows);
while (current_rows--)
{
dosmemput (saved_row, update_row_len, display_row_start);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (display_row_start - ScreenPrimary,
update_row_len / 2);
saved_row += saved_row_len;
display_row_start += to_next_row;
}
}
if (startup_pos_X < cursor_pos_X)
cursor_pos_X = startup_pos_X;
if (startup_pos_Y < cursor_pos_Y)
cursor_pos_Y = startup_pos_Y;
ScreenSetCursor (cursor_pos_Y, cursor_pos_X);
xfree (startup_screen_buffer);
term_setup_done = 0;
}
static void
IT_set_terminal_window (int foo)
{
}
DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors,
Smsdos_remember_default_colors, 1, 1, 0,
doc: )
(frame)
Lisp_Object frame;
{
struct frame *f;
CHECK_FRAME (frame);
f= XFRAME (frame);
if (EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt))
{
initial_screen_colors[0] = FRAME_BACKGROUND_PIXEL (f);
initial_screen_colors[1] = FRAME_FOREGROUND_PIXEL (f);
}
else
{
initial_screen_colors[0] = FRAME_FOREGROUND_PIXEL (f);
initial_screen_colors[1] = FRAME_BACKGROUND_PIXEL (f);
}
}
void
IT_set_frame_parameters (f, alist)
struct frame *f;
Lisp_Object alist;
{
Lisp_Object tail;
int i, j, length = XINT (Flength (alist));
Lisp_Object *parms
= (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
Lisp_Object *values
= (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt);
int need_to_reverse, was_reverse = reverse;
int redraw = 0, fg_set = 0, bg_set = 0;
unsigned long orig_fg, orig_bg;
Lisp_Object frame_bg, frame_fg;
extern Lisp_Object Qdefault, QCforeground, QCbackground;
if (EQ (alist, Vdefault_frame_alist)
&& initial_screen_colors[0] != -1 && initial_screen_colors[1] != -1)
{
FRAME_FOREGROUND_PIXEL (f) = initial_screen_colors[0];
FRAME_BACKGROUND_PIXEL (f) = initial_screen_colors[1];
}
orig_fg = FRAME_FOREGROUND_PIXEL (f);
orig_bg = FRAME_BACKGROUND_PIXEL (f);
frame_fg = Fcdr (Fassq (Qforeground_color, f->param_alist));
frame_bg = Fcdr (Fassq (Qbackground_color, f->param_alist));
if (NILP (frame_fg))
frame_fg = build_string (unspecified_fg);
if (NILP (frame_bg))
frame_bg = build_string (unspecified_bg);
i = 0;
for (tail = alist; CONSP (tail); tail = Fcdr (tail))
{
Lisp_Object elt;
elt = Fcar (tail);
parms[i] = Fcar (elt);
CHECK_SYMBOL (parms[i]);
values[i] = Fcdr (elt);
i++;
}
j = i;
for (i = 0; i < j; i++)
{
Lisp_Object prop, val;
prop = parms[i];
val = values[i];
if (EQ (prop, Qreverse))
reverse = EQ (val, Qt);
}
need_to_reverse = reverse && !was_reverse;
if (termscript && need_to_reverse)
fprintf (termscript, "<INVERSE-VIDEO>\n");
for (i--; i >= 0; i--)
{
Lisp_Object prop, val, frame;
prop = parms[i];
val = values[i];
if (EQ (prop, Qforeground_color))
{
unsigned long new_color = load_color (f, NULL, val, need_to_reverse
? LFACE_BACKGROUND_INDEX
: LFACE_FOREGROUND_INDEX);
if (new_color != FACE_TTY_DEFAULT_COLOR
&& new_color != FACE_TTY_DEFAULT_FG_COLOR
&& new_color != FACE_TTY_DEFAULT_BG_COLOR)
{
FRAME_FOREGROUND_PIXEL (f) = new_color;
XSETFRAME (frame, f);
if (need_to_reverse)
{
Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
val, frame);
prop = Qbackground_color;
bg_set = 1;
}
else
{
Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
val, frame);
fg_set = 1;
}
redraw = 1;
if (termscript)
fprintf (termscript, "<FGCOLOR %lu>\n", new_color);
}
}
else if (EQ (prop, Qbackground_color))
{
unsigned long new_color = load_color (f, NULL, val, need_to_reverse
? LFACE_FOREGROUND_INDEX
: LFACE_BACKGROUND_INDEX);
if (new_color != FACE_TTY_DEFAULT_COLOR
&& new_color != FACE_TTY_DEFAULT_FG_COLOR
&& new_color != FACE_TTY_DEFAULT_BG_COLOR)
{
FRAME_BACKGROUND_PIXEL (f) = new_color;
XSETFRAME (frame, f);
if (need_to_reverse)
{
Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
val, frame);
prop = Qforeground_color;
fg_set = 1;
}
else
{
Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
val, frame);
bg_set = 1;
}
redraw = 1;
if (termscript)
fprintf (termscript, "<BGCOLOR %lu>\n", new_color);
}
}
else if (EQ (prop, Qtitle))
{
x_set_title (f, val);
if (termscript)
fprintf (termscript, "<TITLE: %s>\n", SDATA (val));
}
else if (EQ (prop, Qcursor_type))
{
IT_set_cursor_type (f, val);
if (termscript)
fprintf (termscript, "<CTYPE: %s>\n",
EQ (val, Qbar) || EQ (val, Qhbar)
|| CONSP (val) && (EQ (XCAR (val), Qbar)
|| EQ (XCAR (val), Qhbar))
? "bar" : "box");
}
store_frame_param (f, prop, val);
}
if (need_to_reverse)
{
Lisp_Object frame;
if (!fg_set)
{
XSETFRAME (frame, f);
Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
tty_color_name (f, orig_bg),
frame);
redraw = 1;
}
if (!bg_set)
{
XSETFRAME (frame, f);
Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
tty_color_name (f, orig_fg),
frame);
redraw = 1;
}
}
if (redraw)
{
face_change_count++;
if (f == SELECTED_FRAME())
redraw_frame (f);
}
}
extern void init_frame_faces (FRAME_PTR);
#endif
void
internal_terminal_init ()
{
char *term = getenv ("TERM"), *colors;
struct frame *sf = SELECTED_FRAME();
#ifdef HAVE_X_WINDOWS
if (!inhibit_window_system)
return;
#endif
internal_terminal
= (!noninteractive) && term && !strcmp (term, "internal");
if (getenv ("EMACSTEST"))
termscript = fopen (getenv ("EMACSTEST"), "wt");
#ifndef HAVE_X_WINDOWS
if (!internal_terminal || inhibit_window_system)
{
sf->output_method = output_termcap;
return;
}
Vwindow_system = intern ("pc");
Vwindow_system_version = make_number (1);
sf->output_method = output_msdos_raw;
screen_old_address = 0;
initial_screen_colors[0] = initial_screen_colors[1] = -1;
bzero (&the_only_x_display, sizeof the_only_x_display);
the_only_x_display.background_pixel = 7;
the_only_x_display.foreground_pixel = 0;
bright_bg ();
colors = getenv ("EMACSCOLORS");
if (colors && strlen (colors) >= 2)
{
if (isdigit (colors[0]))
colors[0] -= '0';
else if (isxdigit (colors[0]))
colors[0] -= (isupper (colors[0]) ? 'A' : 'a') - 10;
if (colors[0] >= 0 && colors[0] < 16)
the_only_x_display.foreground_pixel = colors[0];
if (isdigit (colors[1]))
colors[1] -= '0';
else if (isxdigit (colors[1]))
colors[1] -= (isupper (colors[1]) ? 'A' : 'a') - 10;
if (colors[1] >= 0 && colors[1] < 16)
the_only_x_display.background_pixel = colors[1];
}
the_only_x_display.font = (XFontStruct *)1;
the_only_x_display.display_info.mouse_face_mouse_frame = NULL;
the_only_x_display.display_info.mouse_face_deferred_gc = 0;
the_only_x_display.display_info.mouse_face_beg_row =
the_only_x_display.display_info.mouse_face_beg_col = -1;
the_only_x_display.display_info.mouse_face_end_row =
the_only_x_display.display_info.mouse_face_end_col = -1;
the_only_x_display.display_info.mouse_face_face_id = DEFAULT_FACE_ID;
the_only_x_display.display_info.mouse_face_window = Qnil;
the_only_x_display.display_info.mouse_face_mouse_x =
the_only_x_display.display_info.mouse_face_mouse_y = 0;
the_only_x_display.display_info.mouse_face_defer = 0;
the_only_x_display.display_info.mouse_face_hidden = 0;
init_frame_faces (sf);
ring_bell_hook = IT_ring_bell;
insert_glyphs_hook = IT_insert_glyphs;
delete_glyphs_hook = IT_delete_glyphs;
write_glyphs_hook = IT_write_glyphs;
cursor_to_hook = raw_cursor_to_hook = IT_cursor_to;
clear_to_end_hook = IT_clear_to_end;
clear_end_of_line_hook = IT_clear_end_of_line;
clear_frame_hook = IT_clear_screen;
update_begin_hook = IT_update_begin;
update_end_hook = IT_update_end;
frame_up_to_date_hook = IT_frame_up_to_date;
set_terminal_modes_hook = IT_set_terminal_modes;
reset_terminal_modes_hook = IT_reset_terminal_modes;
set_terminal_window_hook = IT_set_terminal_window;
char_ins_del_ok = 0;
#endif
}
dos_get_saved_screen (screen, rows, cols)
char **screen;
int *rows;
int *cols;
{
#ifndef HAVE_X_WINDOWS
*screen = startup_screen_buffer;
*cols = startup_screen_size_X;
*rows = startup_screen_size_Y;
return *screen != (char *)0;
#else
return 0;
#endif
}
#ifndef HAVE_X_WINDOWS
void
check_x (void)
{
if (! FRAME_MSDOS_P (SELECTED_FRAME()))
error ("Not running under a window system");
}
#endif
#define Ignore 0x0000
#define Normal 0x0000
#define FctKey 0x1000
#define Special 0x2000
#define ModFct 0x3000
#define Map 0x4000
#define KeyPad 0x5000
#define Grey 0x6000
#define Alt 0x0100
#define Ctrl 0x0200
#define Shift 0x0400
static int extended_kbd;
struct kbd_translate {
unsigned char sc;
unsigned char ch;
unsigned short code;
};
struct dos_keyboard_map
{
char *unshifted;
char *shifted;
char *alt_gr;
struct kbd_translate *translate_table;
};
static struct dos_keyboard_map us_keyboard = {
"`1234567890-= qwertyuiop[] asdfghjkl;'\\ zxcvbnm,./ ",
"~!@#$%^&*()_+ QWERTYUIOP{} ASDFGHJKL:\"| ZXCVBNM<>? ",
0,
0
};
static struct dos_keyboard_map fr_keyboard = {
"ý&‚\",(-Š_€…)= azertyuiop^$ qsdfghjklm—* wxcvbnm;:! ",
" 1234567890ø+ AZERTYUIOPùœ QSDFGHJKLM%æ WXCVBN?./õ ",
" ~#{[|`\\^@]} Ï ",
0
};
static struct kbd_translate it_kbd_translate_table[] = {
{ 0x56, 0x3c, Normal | 13 },
{ 0x56, 0x3e, Normal | 27 },
{ 0, 0, 0 }
};
static struct dos_keyboard_map it_keyboard = {
"\\1234567890'< qwertyuiopŠ+> asdfghjkl•…— zxcvbnm,.- ",
"|!\"œ$%&/()=?^> QWERTYUIOP‚* ASDFGHJKL‡øõ ZXCVBNM;:_ ",
" {}~` [] @# ",
it_kbd_translate_table
};
static struct dos_keyboard_map dk_keyboard = {
"«1234567890+| qwertyuiop†~ asdfghjkl‘›' zxcvbnm,.- ",
"õ!\"#$%&/()=?` QWERTYUIOP^ ASDFGHJKL’* ZXCVBNM;:_ ",
" @œ$ {[]} | ",
0
};
static struct kbd_translate jp_kbd_translate_table[] = {
{ 0x73, 0x5c, Normal | 0 },
{ 0x73, 0x5f, Normal | 0 },
{ 0x73, 0x1c, Map | 0 },
{ 0x7d, 0x5c, Normal | 13 },
{ 0x7d, 0x7c, Normal | 13 },
{ 0x7d, 0x1c, Map | 13 },
{ 0, 0, 0 }
};
static struct dos_keyboard_map jp_keyboard = {
"\\1234567890-^\\ qwertyuiop@[ asdfghjkl;:] zxcvbnm,./ ",
"_!\"#$%&'()~=~| QWERTYUIOP`{ ASDFGHJKL+*} ZXCVBNM<>? ",
0,
jp_kbd_translate_table
};
static struct keyboard_layout_list
{
int country_code;
struct dos_keyboard_map *keyboard_map;
} keyboard_layout_list[] =
{
1, &us_keyboard,
33, &fr_keyboard,
39, &it_keyboard,
45, &dk_keyboard,
81, &jp_keyboard
};
static struct dos_keyboard_map *keyboard;
static int keyboard_map_all;
static int international_keyboard;
int
dos_set_keyboard (code, always)
int code;
int always;
{
int i;
_go32_dpmi_registers regs;
regs.x.ax = 0xad80;
regs.x.ss = regs.x.sp = regs.x.flags = 0;
_go32_dpmi_simulate_int (0x2f, ®s);
if (regs.h.al == 0xff)
international_keyboard = 1;
keyboard = keyboard_layout_list[0].keyboard_map;
keyboard_map_all = always;
dos_keyboard_layout = 1;
for (i = 0; i < (sizeof (keyboard_layout_list)/sizeof (struct keyboard_layout_list)); i++)
if (code == keyboard_layout_list[i].country_code)
{
keyboard = keyboard_layout_list[i].keyboard_map;
keyboard_map_all = always;
dos_keyboard_layout = code;
return 1;
}
return 0;
}
static struct
{
unsigned char char_code;
unsigned char meta_code;
unsigned char keypad_code;
unsigned char editkey_code;
} keypad_translate_map[] = {
'0', '0', 0xb0, 0x63,
'1', '1', 0xb1, 0x57,
'2', '2', 0xb2, 0x54,
'3', '3', 0xb3, 0x56,
'4', '4', 0xb4, 0x51,
'5', '5', 0xb5, 0xb5,
'6', '6', 0xb6, 0x53,
'7', '7', 0xb7, 0x50,
'8', '8', 0xb8, 0x52,
'9', '9', 0xb9, 0x55,
'.', '-', 0xae, 0xff
};
static struct
{
unsigned char char_code;
unsigned char keypad_code;
} grey_key_translate_map[] = {
'/', 0xaf,
'*', 0xaa,
'-', 0xad,
'+', 0xab,
'\r', 0x8d
};
static unsigned short
ibmpc_translate_map[] =
{
Normal | 0xff,
Alt | ModFct | 0x1b,
Normal | 1,
Normal | 2,
Normal | 3,
Normal | 4,
Normal | 5,
Normal | 6,
Normal | 7,
Normal | 8,
Normal | 9,
Normal | 10,
Normal | 11,
Normal | 12,
Special | 0x08,
ModFct | 0x74,
Map | 15,
Map | 16,
Map | 17,
Map | 18,
Map | 19,
Map | 20,
Map | 21,
Map | 22,
Map | 23,
Map | 24,
Map | 25,
Map | 26,
ModFct | 0x0d,
Ignore,
Map | 30,
Map | 31,
Map | 32,
Map | 33,
Map | 34,
Map | 35,
Map | 36,
Map | 37,
Map | 38,
Map | 39,
Map | 40,
Map | 0,
Ignore,
Map | 41,
Map | 45,
Map | 46,
Map | 47,
Map | 48,
Map | 49,
Map | 50,
Map | 51,
Map | 52,
Map | 53,
Map | 54,
Ignore,
Grey | 1,
Ignore,
Normal | 55,
Ignore,
FctKey | 0xbe,
FctKey | 0xbf,
FctKey | 0xc0,
FctKey | 0xc1,
FctKey | 0xc2,
FctKey | 0xc3,
FctKey | 0xc4,
FctKey | 0xc5,
FctKey | 0xc6,
FctKey | 0xc7,
Ignore,
Ignore,
KeyPad | 7,
KeyPad | 8,
KeyPad | 9,
Grey | 2,
KeyPad | 4,
KeyPad | 5,
KeyPad | 6,
Grey | 3,
KeyPad | 1,
KeyPad | 2,
KeyPad | 3,
KeyPad | 0,
KeyPad | 10,
Shift | FctKey | 0xbe,
Shift | FctKey | 0xbf,
Shift | FctKey | 0xc0,
Shift | FctKey | 0xc1,
Shift | FctKey | 0xc2,
Shift | FctKey | 0xc3,
Shift | FctKey | 0xc4,
Shift | FctKey | 0xc5,
Shift | FctKey | 0xc6,
Shift | FctKey | 0xc7,
Ctrl | FctKey | 0xbe,
Ctrl | FctKey | 0xbf,
Ctrl | FctKey | 0xc0,
Ctrl | FctKey | 0xc1,
Ctrl | FctKey | 0xc2,
Ctrl | FctKey | 0xc3,
Ctrl | FctKey | 0xc4,
Ctrl | FctKey | 0xc5,
Ctrl | FctKey | 0xc6,
Ctrl | FctKey | 0xc7,
Alt | FctKey | 0xbe,
Alt | FctKey | 0xbf,
Alt | FctKey | 0xc0,
Alt | FctKey | 0xc1,
Alt | FctKey | 0xc2,
Alt | FctKey | 0xc3,
Alt | FctKey | 0xc4,
Alt | FctKey | 0xc5,
Alt | FctKey | 0xc6,
Alt | FctKey | 0xc7,
Ctrl | FctKey | 0x6d,
Ctrl | KeyPad | 4,
Ctrl | KeyPad | 6,
Ctrl | KeyPad | 1,
Ctrl | KeyPad | 3,
Ctrl | KeyPad | 7,
Alt | Map | 1,
Alt | Map | 2,
Alt | Map | 3,
Alt | Map | 4,
Alt | Map | 5,
Alt | Map | 6,
Alt | Map | 7,
Alt | Map | 8,
Alt | Map | 9,
Alt | Map | 10,
Alt | Map | 11,
Alt | Map | 12,
Ctrl | KeyPad | 9,
FctKey | 0xc8,
FctKey | 0xc9,
Shift | FctKey | 0xc8,
Shift | FctKey | 0xc9,
Ctrl | FctKey | 0xc8,
Ctrl | FctKey | 0xc9,
Alt | FctKey | 0xc8,
Alt | FctKey | 0xc9,
Ctrl | KeyPad | 8,
Ctrl | Grey | 2,
Ctrl | KeyPad | 5,
Ctrl | Grey | 3,
Ctrl | KeyPad | 2,
Ctrl | KeyPad | 0,
Ctrl | KeyPad | 10,
Ctrl | FctKey | 0x09,
Ctrl | Grey | 0,
Ctrl | Grey | 1,
Alt | FctKey | 0x50,
Alt | FctKey | 0x52,
Alt | FctKey | 0x55,
Ignore,
Alt | FctKey | 0x51,
Ignore,
Alt | FctKey | 0x53,
Ignore,
Alt | FctKey | 0x57,
Alt | KeyPad | 2,
Alt | KeyPad | 3,
Alt | KeyPad | 0,
Alt | KeyPad | 10,
Alt | Grey | 0,
Alt | FctKey | 0x09,
Alt | Grey | 4
};
#define SHIFT_P 0x0003
#define CTRL_P 0x0004
#define ALT_P 0x0008
#define SCRLOCK_P 0x0010
#define NUMLOCK_P 0x0020
#define CAPSLOCK_P 0x0040
#define ALT_GR_P 0x0800
#define SUPER_P 0x4000
#define HYPER_P 0x8000
static int
dos_get_modifiers (keymask)
int *keymask;
{
union REGS regs;
int mask, modifiers = 0;
regs.h.ah = extended_kbd ? 0x12 : 0x02;
int86 (0x16, ®s, ®s);
if (!extended_kbd)
{
mask = regs.h.al & (SHIFT_P | CTRL_P | ALT_P |
SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P);
}
else
{
mask = regs.h.al & (SHIFT_P |
SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P);
if (regs.h.ah & 2)
mask |= ALT_P;
if ((regs.h.ah & 8) != 0)
{
mask |= ALT_GR_P;
if (dos_hyper_key == 1)
{
mask |= HYPER_P;
modifiers |= hyper_modifier;
}
else if (dos_super_key == 1)
{
mask |= SUPER_P;
modifiers |= super_modifier;
}
else if (!international_keyboard)
{
mask &= ~ALT_GR_P;
mask |= ALT_P;
}
}
if (regs.h.ah & 1)
mask |= CTRL_P;
if (regs.h.ah & 4)
{
if (dos_hyper_key == 2)
{
mask |= HYPER_P;
modifiers |= hyper_modifier;
}
else if (dos_super_key == 2)
{
mask |= SUPER_P;
modifiers |= super_modifier;
}
else
mask |= CTRL_P;
}
}
if (mask & SHIFT_P)
modifiers |= shift_modifier;
if (mask & CTRL_P)
modifiers |= ctrl_modifier;
if (mask & ALT_P)
modifiers |= meta_modifier;
if (keymask)
*keymask = mask;
return modifiers;
}
#define NUM_RECENT_DOSKEYS (100)
int recent_doskeys_index;
int total_doskeys;
Lisp_Object recent_doskeys;
DEFUN ("recent-doskeys", Frecent_doskeys, Srecent_doskeys, 0, 0, 0,
doc: )
()
{
Lisp_Object val, *keys = XVECTOR (recent_doskeys)->contents;
if (total_doskeys < NUM_RECENT_DOSKEYS)
return Fvector (total_doskeys, keys);
else
{
val = Fvector (NUM_RECENT_DOSKEYS, keys);
bcopy (keys + recent_doskeys_index,
XVECTOR (val)->contents,
(NUM_RECENT_DOSKEYS - recent_doskeys_index) * sizeof (Lisp_Object));
bcopy (keys,
XVECTOR (val)->contents + NUM_RECENT_DOSKEYS - recent_doskeys_index,
recent_doskeys_index * sizeof (Lisp_Object));
return val;
}
}
static int
dos_rawgetc ()
{
struct input_event event;
union REGS regs;
struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (SELECTED_FRAME());
EVENT_INIT (event);
#ifndef HAVE_X_WINDOWS
IT_cmgoto (SELECTED_FRAME());
#endif
while ((regs.h.ah = extended_kbd ? 0x11 : 0x01),
int86 (0x16, ®s, ®s),
(regs.x.flags & 0x40) == 0)
{
union REGS regs;
register unsigned char c;
int modifiers, sc, code = -1, mask, kp_mode;
regs.h.ah = extended_kbd ? 0x10 : 0x00;
int86 (0x16, ®s, ®s);
c = regs.h.al;
sc = regs.h.ah;
total_doskeys += 2;
XVECTOR (recent_doskeys)->contents[recent_doskeys_index++]
= make_number (c);
if (recent_doskeys_index == NUM_RECENT_DOSKEYS)
recent_doskeys_index = 0;
XVECTOR (recent_doskeys)->contents[recent_doskeys_index++]
= make_number (sc);
if (recent_doskeys_index == NUM_RECENT_DOSKEYS)
recent_doskeys_index = 0;
modifiers = dos_get_modifiers (&mask);
#ifndef HAVE_X_WINDOWS
if (!NILP (Vdos_display_scancodes))
{
char buf[11];
sprintf (buf, "%02x:%02x*%04x",
(unsigned) (sc&0xff), (unsigned) c, mask);
dos_direct_output (screen_size_Y - 2, screen_size_X - 12, buf, 10);
}
#endif
if (sc == 0xe0)
{
switch (c)
{
case 10:
code = Ctrl | Grey | 4;
break;
case 13:
code = Grey | 4;
break;
case '/':
code = Grey | 0;
break;
default:
continue;
};
c = 0;
}
else
{
if (keyboard->translate_table)
{
struct kbd_translate *p = keyboard->translate_table;
while (p->sc)
{
if (p->sc == sc && p->ch == c)
{
code = p->code;
break;
}
p++;
}
}
if (code == -1)
{
if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short)))
continue;
if ((code = ibmpc_translate_map[sc]) == Ignore)
continue;
}
}
if (c == 0)
{
if ( (code & Alt)
|| ( (code & 0xf000) == Map && !international_keyboard))
modifiers |= meta_modifier;
if (code & Ctrl)
modifiers |= ctrl_modifier;
if (code & Shift)
modifiers |= shift_modifier;
}
switch (code & 0xf000)
{
case ModFct:
if (c && !(mask & (SHIFT_P | ALT_P | CTRL_P | HYPER_P | SUPER_P)))
return c;
c = 0;
case FctKey:
if (c != 0)
return c;
case Special:
code |= 0xff00;
break;
case Normal:
if (sc == 0)
{
if (c == 0)
continue;
return c;
}
if (!keyboard_map_all)
{
if (c != ' ')
return c;
code = c;
break;
}
case Map:
if (c && !(mask & ALT_P) && !((mask & SHIFT_P) && (mask & CTRL_P)))
if (!keyboard_map_all)
return c;
code &= 0xff;
if (mask & ALT_P && code <= 10 && code > 0 && dos_keypad_mode & 0x200)
mask |= SHIFT_P;
if (mask & SHIFT_P)
{
code = keyboard->shifted[code];
mask -= SHIFT_P;
modifiers &= ~shift_modifier;
}
else
if ((mask & ALT_GR_P) && keyboard->alt_gr && keyboard->alt_gr[code] != ' ')
code = keyboard->alt_gr[code];
else
code = keyboard->unshifted[code];
break;
case KeyPad:
code &= 0xff;
if (c == 0xe0)
kp_mode = 3;
else
if ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P)
kp_mode = dos_keypad_mode & 0x03;
else
kp_mode = (dos_keypad_mode >> 4) & 0x03;
switch (kp_mode)
{
case 0:
if (code == 10 && dos_decimal_point)
return dos_decimal_point;
return keypad_translate_map[code].char_code;
case 1:
code = 0xff00 | keypad_translate_map[code].keypad_code;
break;
case 2:
code = keypad_translate_map[code].meta_code;
modifiers = meta_modifier;
break;
case 3:
code = 0xff00 | keypad_translate_map[code].editkey_code;
break;
}
break;
case Grey:
code &= 0xff;
kp_mode = ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P) ? 0x04 : 0x40;
if (dos_keypad_mode & kp_mode)
code = 0xff00 | grey_key_translate_map[code].keypad_code;
else
code = grey_key_translate_map[code].char_code;
break;
}
make_event:
if (code == 0)
continue;
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
{
clear_mouse_face (dpyinfo);
dpyinfo->mouse_face_hidden = 1;
}
if (code >= 0x100)
event.kind = NON_ASCII_KEYSTROKE_EVENT;
else
event.kind = ASCII_KEYSTROKE_EVENT;
event.code = code;
event.modifiers = modifiers;
event.frame_or_window = selected_frame;
event.arg = Qnil;
event.timestamp = event_timestamp ();
kbd_buffer_store_event (&event);
}
if (have_mouse > 0 && !mouse_preempted)
{
int but, press, x, y, ok;
int mouse_prev_x = mouse_last_x, mouse_prev_y = mouse_last_y;
Lisp_Object mouse_window = Qnil;
mouse_check_moved ();
if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y)
{
if (dpyinfo->mouse_face_hidden)
{
dpyinfo->mouse_face_hidden = 0;
clear_mouse_face (dpyinfo);
}
if (!NILP (Vmouse_autoselect_window))
{
mouse_window = window_from_coordinates (SELECTED_FRAME(),
mouse_last_x,
mouse_last_y,
0, 0, 0, 0);
if (WINDOWP (mouse_window)
&& !EQ (mouse_window, last_mouse_window)
&& !EQ (mouse_window, selected_window))
{
event.kind = SELECT_WINDOW_EVENT;
event.frame_or_window = mouse_window;
event.arg = Qnil;
event.timestamp = event_timestamp ();
kbd_buffer_store_event (&event);
}
last_mouse_window = mouse_window;
}
else
last_mouse_window = Qnil;
previous_help_echo_string = help_echo_string;
help_echo_string = help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
IT_note_mouse_highlight (SELECTED_FRAME(),
mouse_last_x, mouse_last_y);
if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
{
event.kind = HELP_EVENT;
event.frame_or_window = selected_frame;
event.arg = help_echo_object;
event.x = WINDOWP (help_echo_window)
? help_echo_window : selected_frame;
event.y = help_echo_string;
event.timestamp = event_timestamp ();
event.code = help_echo_pos;
kbd_buffer_store_event (&event);
}
}
for (but = 0; but < NUM_MOUSE_BUTTONS; but++)
for (press = 0; press < 2; press++)
{
int button_num = but;
if (press)
ok = mouse_pressed (but, &x, &y);
else
ok = mouse_released (but, &x, &y);
if (ok)
{
if (mouse_button_count == 2 && but < 2)
{
int x2, y2;
if (press && mouse_pressed (1-but, &x2, &y2)
|| !press && mouse_released (1-but, &x2, &y2))
button_num = 2;
else
{
delay (100);
if (press && mouse_pressed (1-but, &x2, &y2)
|| !press && mouse_released (1-but, &x2, &y2))
button_num = 2;
}
}
event.kind = MOUSE_CLICK_EVENT;
event.code = button_num;
event.modifiers = dos_get_modifiers (0)
| (press ? down_modifier : up_modifier);
event.x = make_number (x);
event.y = make_number (y);
event.frame_or_window = selected_frame;
event.arg = Qnil;
event.timestamp = event_timestamp ();
kbd_buffer_store_event (&event);
}
}
}
return -1;
}
static int prev_get_char = -1;
dos_keysns ()
{
if (prev_get_char != -1)
return 1;
else
return ((prev_get_char = dos_rawgetc ()) != -1);
}
dos_keyread ()
{
if (prev_get_char != -1)
{
int c = prev_get_char;
prev_get_char = -1;
return c;
}
else
return dos_rawgetc ();
}
#ifndef HAVE_X_WINDOWS
static char *menu_help_message, *prev_menu_help_message;
static int menu_help_paneno, menu_help_itemno;
static XMenu *
IT_menu_create ()
{
XMenu *menu;
menu = (XMenu *) xmalloc (sizeof (XMenu));
menu->allocated = menu->count = menu->panecount = menu->width = 0;
return menu;
}
static void
IT_menu_make_room (XMenu *menu)
{
if (menu->allocated == 0)
{
int count = menu->allocated = 10;
menu->text = (char **) xmalloc (count * sizeof (char *));
menu->submenu = (XMenu **) xmalloc (count * sizeof (XMenu *));
menu->panenumber = (int *) xmalloc (count * sizeof (int));
menu->help_text = (char **) xmalloc (count * sizeof (char *));
}
else if (menu->allocated == menu->count)
{
int count = menu->allocated = menu->allocated + 10;
menu->text
= (char **) xrealloc (menu->text, count * sizeof (char *));
menu->submenu
= (XMenu **) xrealloc (menu->submenu, count * sizeof (XMenu *));
menu->panenumber
= (int *) xrealloc (menu->panenumber, count * sizeof (int));
menu->help_text
= (char **) xrealloc (menu->help_text, count * sizeof (char *));
}
}
static XMenu *
IT_menu_search_pane (XMenu *menu, int pane)
{
int i;
XMenu *try;
for (i = 0; i < menu->count; i++)
if (menu->submenu[i])
{
if (pane == menu->panenumber[i])
return menu->submenu[i];
if ((try = IT_menu_search_pane (menu->submenu[i], pane)))
return try;
}
return (XMenu *) 0;
}
static void
IT_menu_calc_size (XMenu *menu, int *width, int *height)
{
int i, h2, w2, maxsubwidth, maxheight;
maxsubwidth = 0;
maxheight = menu->count;
for (i = 0; i < menu->count; i++)
{
if (menu->submenu[i])
{
IT_menu_calc_size (menu->submenu[i], &w2, &h2);
if (w2 > maxsubwidth) maxsubwidth = w2;
if (i + h2 > maxheight) maxheight = i + h2;
}
}
*width = menu->width + maxsubwidth;
*height = maxheight;
}
static void
IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
{
int i, j, face, width, mx, my, enabled, mousehere, row, col;
struct glyph *text, *p;
char *q;
struct frame *sf = SELECTED_FRAME();
menu_help_message = NULL;
width = menu->width;
text = (struct glyph *) xmalloc ((width + 2) * sizeof (struct glyph));
ScreenGetCursor (&row, &col);
mouse_get_xy (&mx, &my);
IT_update_begin (sf);
for (i = 0; i < menu->count; i++)
{
int max_width = width + 2;
IT_cursor_to (y + i, x);
enabled
= (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
mousehere = (y + i == my && x <= mx && mx < x + width + 2);
face = faces[enabled + mousehere * 2];
if (disp_help && enabled + mousehere * 2 >= 2)
{
menu_help_message = menu->help_text[i];
menu_help_paneno = pn - 1;
menu_help_itemno = i;
}
p = text;
SET_CHAR_GLYPH (*p, ' ', face, 0);
p++;
for (j = 0, q = menu->text[i]; *q; j++)
{
if (*q > 26)
{
SET_CHAR_GLYPH (*p, *q++, face, 0);
p++;
}
else
{
SET_CHAR_GLYPH (*p, '^', face, 0);
p++;
j++;
SET_CHAR_GLYPH (*p, *q++ + 64, face, 0);
p++;
}
}
if (x + max_width > screen_size_X)
{
max_width = screen_size_X - x;
text[max_width - 1].u.ch = '$';
}
for (; j < max_width - 2; j++, p++)
SET_CHAR_GLYPH (*p, ' ', face, 0);
SET_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0);
p++;
IT_write_glyphs (text, max_width);
}
IT_update_end (sf);
IT_cursor_to (row, col);
xfree (text);
}
int
have_menus_p () { return 1; }
XMenu *
XMenuCreate (Display *foo1, Window foo2, char *foo3)
{
return IT_menu_create ();
}
int
XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable)
{
int len;
char *p;
if (!enable)
abort ();
IT_menu_make_room (menu);
menu->submenu[menu->count] = IT_menu_create ();
menu->text[menu->count] = txt;
menu->panenumber[menu->count] = ++menu->panecount;
menu->help_text[menu->count] = NULL;
menu->count++;
for (len = strlen (txt), p = txt; *p; p++)
if (*p < 27)
len++;
if (len > menu->width)
menu->width = len;
return menu->panecount;
}
int
XMenuAddSelection (Display *bar, XMenu *menu, int pane,
int foo, char *txt, int enable, char *help_text)
{
int len;
char *p;
if (pane)
if (!(menu = IT_menu_search_pane (menu, pane)))
return XM_FAILURE;
IT_menu_make_room (menu);
menu->submenu[menu->count] = (XMenu *) 0;
menu->text[menu->count] = txt;
menu->panenumber[menu->count] = enable;
menu->help_text[menu->count] = help_text;
menu->count++;
for (len = strlen (txt), p = txt; *p; p++)
if (*p < 27)
len++;
if (len > menu->width)
menu->width = len;
return XM_SUCCESS;
}
void
XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y,
int *ulx, int *uly, int *width, int *height)
{
IT_menu_calc_size (menu, width, height);
*ulx = x + 1;
*uly = y;
*width += 2;
}
struct IT_menu_state
{
void *screen_behind;
XMenu *menu;
int pane;
int x, y;
};
int
XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
int x0, int y0, unsigned ButtonMask, char **txt,
void (*help_callback)(char *, int, int))
{
struct IT_menu_state *state;
int statecount, x, y, i, b, screensize, leave, result, onepane;
int title_faces[4];
int faces[4], buffers_num_deleted = 0;
struct frame *sf = SELECTED_FRAME();
Lisp_Object saved_echo_area_message, selectface;
if (have_mouse <= 0)
return XM_IA_SELECT;
if (x0 <= 0)
x0 = 1;
if (y0 <= 0)
y0 = 1;
mouse_preempted++;
state = alloca (menu->panecount * sizeof (struct IT_menu_state));
screensize = screen_size * 2;
faces[0]
= lookup_derived_face (sf, intern ("msdos-menu-passive-face"),
0, DEFAULT_FACE_ID, 1);
faces[1]
= lookup_derived_face (sf, intern ("msdos-menu-active-face"),
0, DEFAULT_FACE_ID, 1);
selectface = intern ("msdos-menu-select-face");
faces[2] = lookup_derived_face (sf, selectface,
0, faces[0], 1);
faces[3] = lookup_derived_face (sf, selectface,
0, faces[1], 1);
for (i = 0; i < 4; i++)
title_faces[i] = faces[3];
statecount = 1;
if (strncmp (menu->text[0], "Buffers 1", 9) == 0)
{
menu->text[0][7] = '\0';
buffers_num_deleted = 1;
}
saved_echo_area_message = Fcurrent_message ();
state[0].menu = menu;
mouse_off ();
ScreenRetrieve (state[0].screen_behind = xmalloc (screensize));
IT_display_cursor (0);
IT_menu_display (menu, y0 - 1, x0 - 1, 1, title_faces, 0);
if (buffers_num_deleted)
menu->text[0][7] = ' ';
if ((onepane = menu->count == 1 && menu->submenu[0]))
{
menu->width = menu->submenu[0]->width;
state[0].menu = menu->submenu[0];
}
else
{
state[0].menu = menu;
}
state[0].x = x0 - 1;
state[0].y = y0;
state[0].pane = onepane;
mouse_last_x = -1;
leave = 0;
while (!leave)
{
if (!mouse_visible) mouse_on ();
mouse_check_moved ();
if (sf->mouse_moved)
{
sf->mouse_moved = 0;
result = XM_IA_SELECT;
mouse_get_xy (&x, &y);
for (i = 0; i < statecount; i++)
if (state[i].x <= x && x < state[i].x + state[i].menu->width + 2)
{
int dy = y - state[i].y;
if (0 <= dy && dy < state[i].menu->count)
{
if (!state[i].menu->submenu[dy])
if (state[i].menu->panenumber[dy])
result = XM_SUCCESS;
else
result = XM_IA_SELECT;
*pane = state[i].pane - 1;
*selidx = dy;
if (i != statecount - 2
|| state[i].menu->submenu[dy] != state[i+1].menu)
while (i != statecount - 1)
{
statecount--;
mouse_off ();
ScreenUpdate (state[statecount].screen_behind);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (0, screen_size);
xfree (state[statecount].screen_behind);
}
if (i == statecount - 1 && state[i].menu->submenu[dy])
{
IT_menu_display (state[i].menu,
state[i].y,
state[i].x,
state[i].pane,
faces, 1);
state[statecount].menu = state[i].menu->submenu[dy];
state[statecount].pane = state[i].menu->panenumber[dy];
mouse_off ();
ScreenRetrieve (state[statecount].screen_behind
= xmalloc (screensize));
state[statecount].x
= state[i].x + state[i].menu->width + 2;
state[statecount].y = y;
statecount++;
}
}
}
IT_menu_display (state[statecount - 1].menu,
state[statecount - 1].y,
state[statecount - 1].x,
state[statecount - 1].pane,
faces, 1);
}
else
{
if ((menu_help_message || prev_menu_help_message)
&& menu_help_message != prev_menu_help_message)
{
help_callback (menu_help_message,
menu_help_paneno, menu_help_itemno);
IT_display_cursor (0);
prev_menu_help_message = menu_help_message;
}
__dpmi_yield ();
}
for (b = 0; b < mouse_button_count && !leave; b++)
{
if (mouse_pressed (b, &x, &y))
{
while (mouse_button_depressed (b, &x, &y))
__dpmi_yield ();
leave = 1;
}
(void) mouse_released (b, &x, &y);
}
}
mouse_off ();
ScreenUpdate (state[0].screen_behind);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (0, screen_size);
if (! NILP (saved_echo_area_message))
message_with_string ("%s", saved_echo_area_message, 0);
message (0);
while (statecount--)
xfree (state[statecount].screen_behind);
IT_display_cursor (1);
discard_mouse_events ();
mouse_clear_clicks ();
if (!kbd_buffer_events_waiting (1))
clear_input_pending ();
mouse_preempted--;
return result;
}
void
XMenuDestroy (Display *foo, XMenu *menu)
{
int i;
if (menu->allocated)
{
for (i = 0; i < menu->count; i++)
if (menu->submenu[i])
XMenuDestroy (foo, menu->submenu[i]);
xfree (menu->text);
xfree (menu->submenu);
xfree (menu->panenumber);
xfree (menu->help_text);
}
xfree (menu);
menu_help_message = prev_menu_help_message = NULL;
}
int
x_pixel_width (struct frame *f)
{
return FRAME_COLS (f);
}
int
x_pixel_height (struct frame *f)
{
return FRAME_LINES (f);
}
#endif
void msdos_downcase_filename (unsigned char *);
void
dostounix_filename (p)
register char *p;
{
msdos_downcase_filename (p);
while (*p)
{
if (*p == '\\')
*p = '/';
p++;
}
}
void
unixtodos_filename (p)
register char *p;
{
if (p[1] == ':' && *p >= 'A' && *p <= 'Z')
{
*p += 'a' - 'A';
p += 2;
}
while (*p)
{
if (*p == '/')
*p = '\\';
p++;
}
}
int
getdefdir (drive, dst)
int drive;
char *dst;
{
char in_path[4], *p = in_path, e = errno;;
if (drive != 0)
{
*p++ = drive + 'A' - 1;
*p++ = ':';
}
*p++ = '.';
*p = '\0';
errno = 0;
_fixpath (in_path, dst);
if ((errno && errno != ENOSYS) || *dst == '\0')
return 0;
msdos_downcase_filename (dst);
errno = e;
return 1;
}
char *
emacs_root_dir (void)
{
static char root_dir[4];
sprintf (root_dir, "%c:/", 'A' + getdisk ());
root_dir[0] = tolower (root_dir[0]);
return root_dir;
}
int
crlf_to_lf (n, buf)
register int n;
register unsigned char *buf;
{
unsigned char *np = buf, *startp = buf, *endp = buf + n;
if (n == 0)
return n;
while (buf < endp - 1)
{
if (*buf == 0x0d)
{
if (*(++buf) != 0x0a)
*np++ = 0x0d;
}
else
*np++ = *buf++;
}
if (buf < endp)
*np++ = *buf++;
return np - startp;
}
#if defined(__DJGPP__) && __DJGPP__ == 2 && __DJGPP_MINOR__ == 0
#include <io.h>
#include <libc/dosio.h>
static char xbuf[64 * 1024];
#define XBUF_END (xbuf + sizeof (xbuf) - 1)
int
__write (int handle, const void *buffer, size_t count)
{
if (count == 0)
return 0;
if(__file_handle_modes[handle] & O_BINARY)
return _write (handle, buffer, count);
else
{
char *xbp = xbuf;
const char *bp = buffer;
int total_written = 0;
int nmoved = 0, ncr = 0;
while (count)
{
if (xbp < XBUF_END)
{
if (*bp == '\n')
{
ncr++;
*xbp++ = '\r';
}
*xbp++ = *bp++;
nmoved++;
count--;
}
if (xbp >= XBUF_END || !count)
{
size_t to_write = nmoved + ncr;
int written = _write (handle, xbuf, to_write);
if (written == -1)
return -1;
else
total_written += nmoved;
if (written < to_write)
return total_written - (to_write - written) * nmoved/to_write;
nmoved = 0;
ncr = 0;
xbp = xbuf;
}
}
return total_written;
}
}
#include <io.h>
int _rename(const char *old, const char *new)
{
__dpmi_regs r;
int olen = strlen(old) + 1;
int i;
int use_lfn = _USE_LFN;
char tempfile[FILENAME_MAX];
const char *orig = old;
int lfn_fd = -1;
r.x.dx = __tb_offset;
r.x.di = __tb_offset + olen;
r.x.ds = r.x.es = __tb_segment;
if (use_lfn)
{
char *pbase = 0, *p;
static char try_char[] = "abcdefghijklmnopqrstuvwxyz012345789";
int idx = sizeof(try_char) - 1;
strcpy(tempfile, old);
for (p = tempfile; *p; p++)
if (*p == '/' || *p == '\\' || *p == ':')
pbase = p;
if (pbase)
pbase++;
else
pbase = tempfile;
strcpy(pbase, "X$$djren$$.$$temp$$");
do
{
if (idx <= 0)
return -1;
*pbase = try_char[--idx];
} while (_chmod(tempfile, 0) != -1);
r.x.ax = 0x7156;
_put_path2(tempfile, olen);
_put_path(old);
__dpmi_int(0x21, &r);
if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
lfn_fd = _creat(old, 0);
olen = strlen(tempfile) + 1;
old = tempfile;
r.x.di = __tb_offset + olen;
}
for (i=0; i<2; i++)
{
if(use_lfn)
r.x.ax = 0x7156;
else
r.h.ah = 0x56;
_put_path2(new, olen);
_put_path(old);
__dpmi_int(0x21, &r);
if(r.x.flags & 1)
{
if (r.x.ax == 5 && i == 0)
remove(new);
else
{
errno = __doserr_to_errno(r.x.ax);
if (use_lfn)
{
if (lfn_fd != -1)
{
_close (lfn_fd);
remove (orig);
}
_put_path2(orig, olen);
_put_path(tempfile);
r.x.ax = 0x7156;
__dpmi_int(0x21, &r);
}
return -1;
}
}
else
break;
}
if (lfn_fd != -1)
return (_close (lfn_fd) == 0) ? remove (orig) : -1;
return 0;
}
#endif
DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names,
0, 0, 0,
doc: )
()
{
return (_USE_LFN ? Qt : Qnil);
}
void
msdos_downcase_filename (p)
register unsigned char *p;
{
if (p[1] == ':' && *p >= 'A' && *p <= 'Z')
{
*p += 'a' - 'A';
p += 2;
}
if (NILP (Fmsdos_long_file_names ()))
for ( ; *p; p++)
if (*p >= 'A' && *p <= 'Z')
*p += 'a' - 'A';
}
DEFUN ("msdos-downcase-filename", Fmsdos_downcase_filename, Smsdos_downcase_filename,
1, 1, 0,
doc: )
(filename)
Lisp_Object filename;
{
Lisp_Object tem;
if (! STRINGP (filename))
return Qnil;
tem = Fcopy_sequence (filename);
msdos_downcase_filename (SDATA (tem));
return tem;
}
static char emacsroot[MAXPATHLEN];
char *
rootrelativepath (rel)
char *rel;
{
static char result[MAXPATHLEN + 10];
strcpy (result, emacsroot);
strcat (result, "/");
strcat (result, rel);
return result;
}
void
init_environment (argc, argv, skip_args)
int argc;
char **argv;
int skip_args;
{
char *s, *t, *root;
int len, i;
static const char * const tempdirs[] = {
"$TMPDIR", "$TEMP", "$TMP", "c:/"
};
const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]);
for (i = 0; i < imax ; i++)
{
const char *tmp = tempdirs[i];
char buf[FILENAME_MAX];
if (*tmp == '$')
{
int tmp_len;
tmp = getenv (tmp + 1);
if (!tmp)
continue;
tmp_len = strlen(tmp);
if (tmp[tmp_len - 1] != '/' && tmp[tmp_len - 1] != '\\')
{
strcpy(buf, tmp);
buf[tmp_len++] = '/', buf[tmp_len] = 0;
tmp = buf;
}
}
if (tmp && access (tmp, D_OK) == 0)
{
setenv ("TMPDIR", tmp, 1);
break;
}
}
if (i >= imax)
cmd_error_internal
(Fcons (Qerror,
Fcons (build_string ("no usable temporary directories found!!"),
Qnil)),
"While setting TMPDIR: ");
startup_time = clock ();
root = alloca (MAXPATHLEN + 20);
_fixpath (argv[0], root);
msdos_downcase_filename (root);
len = strlen (root);
while (len > 0 && root[len] != '/' && root[len] != ':')
len--;
root[len] = '\0';
if (len > 4
&& (strcmp (root + len - 4, "/bin") == 0
|| strcmp (root + len - 4, "/src") == 0))
root[len - 4] = '\0';
else
strcpy (root, "c:/emacs");
len = strlen (root);
strcpy (emacsroot, root);
setenv ("HOME", root, 0);
strcpy (root + len, "/bin");
setenv ("EMACSPATH", root, 0);
setenv ("TERM", "internal", 0);
#ifdef HAVE_X_WINDOWS
setenv ("DISPLAY", "unix:0.0", 0);
#endif
s = getenv ("COMSPEC");
if (!s) s = "c:/command.com";
t = alloca (strlen (s) + 1);
strcpy (t, s);
dostounix_filename (t);
setenv ("SHELL", t, 0);
s = getenv ("PATH");
if (!s) s = "";
t = alloca (strlen (s) + 3);
strcat (strcpy (t, ".;"), s);
dostounix_filename (t);
setenv ("PATH", t, 1);
setenv ("USER", "root", 0);
setenv ("NAME", getenv ("USER"), 0);
if (!getenv ("TZ"))
switch (dos_country_code)
{
case 31:
case 32:
case 33:
case 34:
case 36:
case 38:
case 39:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0);
break;
case 44:
case 351:
case 354:
setenv ("TZ", "GMT+00", 0);
break;
case 81:
case 82:
setenv ("TZ", "JST-09", 0);
break;
case 90:
case 358:
setenv ("TZ", "EET-02", 0);
break;
case 972:
setenv ("TZ", "IST-02IDT-03,M4.1.6/00:00,M9.5.6/01:00", 0);
break;
}
tzset ();
}
static int break_stat;
static int stdin_stat;
#if __DJGPP__ < 2
static _go32_dpmi_seginfo ctrl_break_vector;
static _go32_dpmi_registers ctrl_break_regs;
static int ctrlbreakinstalled = 0;
void
ctrl_break_func (regs)
_go32_dpmi_registers *regs;
{
Vquit_flag = Qt;
}
void
install_ctrl_break_check ()
{
if (!ctrlbreakinstalled)
{
ctrlbreakinstalled = 1;
ctrl_break_vector.pm_offset = (int) ctrl_break_func;
_go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector,
&ctrl_break_regs);
_go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector);
}
}
#endif
int
dos_ttraw ()
{
union REGS inregs, outregs;
static int first_time = 1;
break_stat = getcbrk ();
setcbrk (0);
#if __DJGPP__ < 2
install_ctrl_break_check ();
#endif
if (first_time)
{
inregs.h.ah = 0xc0;
int86 (0x15, &inregs, &outregs);
extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0);
have_mouse = 0;
if (internal_terminal
#ifdef HAVE_X_WINDOWS
&& inhibit_window_system
#endif
)
{
inregs.x.ax = 0x0021;
int86 (0x33, &inregs, &outregs);
have_mouse = (outregs.x.ax & 0xffff) == 0xffff;
if (!have_mouse)
{
inregs.x.ax = 0x0000;
int86 (0x33, &inregs, &outregs);
have_mouse = (outregs.x.ax & 0xffff) == 0xffff;
}
if (have_mouse)
{
have_mouse = 1;
mouse_visible = 0;
mouse_setup_buttons (outregs.x.bx);
mouse_position_hook = &mouse_get_pos;
mouse_init ();
}
#ifndef HAVE_X_WINDOWS
#if __DJGPP__ >= 2
outside_cursor = _farpeekw (_dos_ds, 0x460);
#endif
#endif
}
first_time = 0;
#if __DJGPP__ >= 2
stdin_stat = setmode (fileno (stdin), O_BINARY);
return (stdin_stat != -1);
}
else
return (setmode (fileno (stdin), O_BINARY) != -1);
#else
}
inregs.x.ax = 0x4400;
inregs.x.bx = 0x00;
intdos (&inregs, &outregs);
stdin_stat = outregs.h.dl;
inregs.x.dx = stdin_stat | 0x0020;
inregs.x.ax = 0x4401;
intdos (&inregs, &outregs);
return !outregs.x.cflag;
#endif
}
int
dos_ttcooked ()
{
union REGS inregs, outregs;
setcbrk (break_stat);
mouse_off ();
#if __DJGPP__ >= 2
#ifndef HAVE_X_WINDOWS
if (outside_cursor)
{
inregs.h.ah = 1;
inregs.x.cx = outside_cursor;
int86 (0x10, &inregs, &outregs);
}
#endif
return (setmode (fileno (stdin), stdin_stat) != -1);
#else
inregs.x.ax = 0x4401;
inregs.x.bx = 0x00;
inregs.x.dx = stdin_stat;
intdos (&inregs, &outregs);
return !outregs.x.cflag;
#endif
}
int
run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
unsigned char **argv;
const char *working_dir;
int tempin, tempout, temperr;
char **envv;
{
char *saveargv1, *saveargv2, *lowcase_argv0, *pa, *pl;
char oldwd[MAXPATHLEN + 1];
int msshell, result = -1, inbak, outbak, errbak, x, y;
Lisp_Object cmd;
getwd (oldwd);
lowcase_argv0 = alloca (strlen (argv[0]) + 1);
for (pa = argv[0], pl = lowcase_argv0; *pa; pl++)
{
*pl = *pa++;
if (*pl >= 'A' && *pl <= 'Z')
*pl += 'a' - 'A';
}
*pl = '\0';
cmd = Ffile_name_nondirectory (build_string (lowcase_argv0));
msshell = !NILP (Fmember (cmd, Fsymbol_value (intern ("msdos-shells"))))
&& !strcmp ("-c", argv[1]);
if (msshell)
{
saveargv1 = argv[1];
saveargv2 = argv[2];
argv[1] = "/c";
if (argv[2] && argv[3])
{
char *p = alloca (strlen (argv[2]) + 1);
strcpy (argv[2] = p, saveargv2);
while (*p && isspace (*p))
p++;
while (*p)
{
if (*p == '/')
*p++ = '\\';
else
p++;
}
}
}
chdir (working_dir);
inbak = dup (0);
outbak = dup (1);
errbak = dup (2);
if (inbak < 0 || outbak < 0 || errbak < 0)
goto done;
if (have_mouse > 0)
mouse_get_xy (&x, &y);
dos_ttcooked ();
dup2 (tempin, 0);
dup2 (tempout, 1);
dup2 (temperr, 2);
#if __DJGPP__ > 1
if (msshell && !argv[3])
{
const char *cmnd;
for (cmnd = saveargv2; *cmnd && isspace (*cmnd); cmnd++)
;
if (*cmnd)
{
extern char **environ;
char **save_env = environ;
int save_system_flags = __system_flags;
__system_flags = (__system_redirect
| __system_use_shell
| __system_allow_multiple_cmds
| __system_allow_long_cmds
| __system_handle_null_commands
| __system_emulate_chdir);
environ = envv;
result = system (cmnd);
__system_flags = save_system_flags;
environ = save_env;
}
else
result = 0;
}
else
#endif
result = spawnve (P_WAIT, argv[0], argv, envv);
dup2 (inbak, 0);
dup2 (outbak, 1);
dup2 (errbak, 2);
emacs_close (inbak);
emacs_close (outbak);
emacs_close (errbak);
dos_ttraw ();
if (have_mouse > 0)
{
mouse_init ();
mouse_moveto (x, y);
}
bright_bg ();
done:
chdir (oldwd);
if (msshell)
{
argv[1] = saveargv1;
argv[2] = saveargv2;
}
return result;
}
void
croak (badfunc)
char *badfunc;
{
fprintf (stderr, "%s not yet implemented\r\n", badfunc);
reset_sys_modes ();
exit (1);
}
#if __DJGPP__ < 2
gethostname (p, size)
char *p;
int size;
{
char *q = egetenv ("HOSTNAME");
if (!q) q = "pc";
strcpy (p, q);
return 0;
}
static struct tm time_rec;
int
gettimeofday (struct timeval *tp, struct timezone *tzp)
{
if (tp)
{
struct time t;
struct tm tm;
gettime (&t);
if (t.ti_hour < time_rec.tm_hour)
{
struct date d;
getdate (&d);
time_rec.tm_year = d.da_year - 1900;
time_rec.tm_mon = d.da_mon - 1;
time_rec.tm_mday = d.da_day;
}
time_rec.tm_hour = t.ti_hour;
time_rec.tm_min = t.ti_min;
time_rec.tm_sec = t.ti_sec;
tm = time_rec;
tm.tm_gmtoff = dos_timezone_offset;
tp->tv_sec = mktime (&tm);
tp->tv_usec = t.ti_hund * (1000000 / 100);
}
return 0;
}
#endif
#if __DJGPP__ < 2
unsigned alarm (s) unsigned s; {}
fork () { return 0; }
int kill (x, y) int x, y; { return -1; }
nice (p) int p; {}
void volatile pause () {}
sigsetmask (x) int x; { return 0; }
sigblock (mask) int mask; { return 0; }
#endif
void request_sigio (void) {}
setpgrp () {return 0; }
setpriority (x,y,z) int x,y,z; { return 0; }
void unrequest_sigio (void) {}
#if __DJGPP__ > 1
#if __DJGPP_MINOR__ < 2
#ifdef POSIX_SIGNALS
#include <libc/bss.h>
static int sigprocmask_count = -1;
static sigset_t current_mask;
static sigset_t pending_signals;
typedef void (*sighandler_t)(int);
static sighandler_t prev_handlers[320];
static void
sig_suspender (signo)
int signo;
{
sigaddset (&pending_signals, signo);
}
int
sigprocmask (how, new_set, old_set)
int how;
const sigset_t *new_set;
sigset_t *old_set;
{
int signo;
sigset_t new_mask;
if (sigprocmask_count != __bss_count)
{
sigprocmask_count = __bss_count;
sigemptyset (&pending_signals);
sigemptyset (¤t_mask);
for (signo = 0; signo < 320; signo++)
prev_handlers[signo] = SIG_ERR;
}
if (old_set)
*old_set = current_mask;
if (new_set == 0)
return 0;
if (how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK)
{
errno = EINVAL;
return -1;
}
sigemptyset (&new_mask);
for (signo = 0; signo < 320; signo++)
{
if (sigismember (¤t_mask, signo))
sigaddset (&new_mask, signo);
else if (sigismember (new_set, signo) && how != SIG_UNBLOCK)
{
sigaddset (&new_mask, signo);
if (signo != SIGKILL && prev_handlers[signo] == SIG_ERR)
prev_handlers[signo] = signal (signo, sig_suspender);
}
if (( how == SIG_UNBLOCK
&& sigismember (&new_mask, signo)
&& sigismember (new_set, signo))
|| (how == SIG_SETMASK
&& sigismember (&new_mask, signo)
&& !sigismember (new_set, signo)))
{
sigdelset (&new_mask, signo);
if (prev_handlers[signo] != SIG_ERR)
{
signal (signo, prev_handlers[signo]);
prev_handlers[signo] = SIG_ERR;
}
if (sigismember (&pending_signals, signo))
{
sigdelset (&pending_signals, signo);
raise (signo);
}
}
}
current_mask = new_mask;
return 0;
}
#else
sigsetmask (x) int x; { return 0; }
sigblock (mask) int mask; { return 0; }
#endif
#endif
#endif
#ifndef HAVE_SELECT
#include "sysselect.h"
#ifndef EMACS_TIME_ZERO_OR_NEG_P
#define EMACS_TIME_ZERO_OR_NEG_P(time) \
((long)(time).tv_sec < 0 \
|| ((time).tv_sec == 0 \
&& (long)(time).tv_usec <= 0))
#endif
void
dos_yield_time_slice (void)
{
_go32_dpmi_registers r;
r.x.ax = 0x1680;
r.x.ss = r.x.sp = r.x.flags = 0;
_go32_dpmi_simulate_int (0x2f, &r);
if (r.h.al == 0x80)
errno = ENOSYS;
}
int
sys_select (nfds, rfds, wfds, efds, timeout)
int nfds;
SELECT_TYPE *rfds, *wfds, *efds;
EMACS_TIME *timeout;
{
int check_input;
struct time t;
check_input = 0;
if (rfds)
{
check_input = FD_ISSET (0, rfds);
FD_ZERO (rfds);
}
if (wfds)
FD_ZERO (wfds);
if (efds)
FD_ZERO (efds);
if (nfds != 1)
abort ();
if (!timeout)
{
while (!detect_input_pending ())
{
dos_yield_time_slice ();
}
}
else
{
EMACS_TIME clnow, cllast, cldiff;
gettime (&t);
EMACS_SET_SECS_USECS (cllast, t.ti_sec, t.ti_hund * 10000L);
while (!check_input || !detect_input_pending ())
{
gettime (&t);
EMACS_SET_SECS_USECS (clnow, t.ti_sec, t.ti_hund * 10000L);
EMACS_SUB_TIME (cldiff, clnow, cllast);
if (EMACS_TIME_NEG_P (cldiff))
EMACS_SET_SECS (cldiff, EMACS_SECS (cldiff) + 60);
EMACS_SUB_TIME (*timeout, *timeout, cldiff);
if (EMACS_TIME_ZERO_OR_NEG_P (*timeout))
return 0;
cllast = clnow;
dos_yield_time_slice ();
}
}
FD_SET (0, rfds);
return 1;
}
#endif
#ifdef chdir
#undef chdir
extern int chdir ();
int
sys_chdir (path)
const char* path;
{
int len = strlen (path);
char *tmp = (char *)path;
if (*tmp && tmp[1] == ':')
{
if (getdisk () != tolower (tmp[0]) - 'a')
setdisk (tolower (tmp[0]) - 'a');
tmp += 2;
len -= 2;
}
if (len > 1 && (tmp[len - 1] == '/'))
{
char *tmp1 = (char *) alloca (len + 1);
strcpy (tmp1, tmp);
tmp1[len - 1] = 0;
tmp = tmp1;
}
return chdir (tmp);
}
#endif
#ifdef tzset
#undef tzset
extern void tzset (void);
void
init_gettimeofday ()
{
time_t ltm, gtm;
struct tm *lstm;
tzset ();
ltm = gtm = time (NULL);
ltm = mktime (lstm = localtime (<m));
gtm = mktime (gmtime (>m));
time_rec.tm_hour = 99;
time_rec.tm_isdst = lstm->tm_isdst;
dos_timezone_offset = time_rec.tm_gmtoff = (int)(gtm - ltm) / 60;
}
#endif
#ifdef abort
#undef abort
void
dos_abort (file, line)
char *file;
int line;
{
char buffer1[200], buffer2[400];
int i, j;
sprintf (buffer1, "<EMACS FATAL ERROR IN %s LINE %d>", file, line);
for (i = j = 0; buffer1[i]; i++) {
buffer2[j++] = buffer1[i];
buffer2[j++] = 0x70;
}
dosmemput (buffer2, j, (int)ScreenPrimary);
ScreenSetCursor (2, 0);
abort ();
}
#else
void
abort ()
{
dos_ttcooked ();
ScreenSetCursor (10, 0);
cputs ("\r\n\nEmacs aborted!\r\n");
#if __DJGPP__ > 1
#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
if (screen_virtual_segment)
dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X);
signal (SIGINT, SIG_DFL);
__asm__ __volatile__ ("movb $0x1b,%al;call ___djgpp_hw_exception");
#else
raise (SIGABRT);
#endif
#endif
exit (2);
}
#endif
#ifndef subprocesses
static int delete_exited_processes;
#endif
syms_of_msdos ()
{
recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil);
staticpro (&recent_doskeys);
#ifndef HAVE_X_WINDOWS
Qreverse = intern ("reverse");
staticpro (&Qreverse);
DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph,
doc: );
Vdos_unsupported_char_glyph = make_number ('\177');
#endif
#ifndef subprocesses
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
doc: );
delete_exited_processes = 0;
#endif
defsubr (&Srecent_doskeys);
defsubr (&Smsdos_long_file_names);
defsubr (&Smsdos_downcase_filename);
defsubr (&Smsdos_remember_default_colors);
defsubr (&Smsdos_set_mouse_buttons);
}
#endif