/* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991.
Major changes May-July 1993 Morten Welinder (only 10% original code left)
- Copyright (C) 1991, 1993, 1996, 1997, 1998, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1996-1998, 2001-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* The entire file is within this conditional */
#include <stdio.h>
-#include <string.h>
#include <dos.h>
+#include <setjmp.h>
#include "lisp.h"
#include "buffer.h"
#include "termchar.h"
-#include "termhooks.h"
#include "frame.h"
+#include "termhooks.h"
#include "blockinput.h"
#include "window.h"
#include "dosfns.h"
#include "dispextern.h"
#include "character.h"
#include "coding.h"
+#include "process.h"
#include <dpmi.h>
#include <go32.h>
#include <dirent.h>
#include <sys/vfs.h>
-
-#ifndef __DJGPP_MINOR__
-# define __tb _go32_info_block.linear_address_of_transfer_buffer;
-#endif
+#include <unistd.h>
+#include <grp.h>
+#include <crt0.h>
DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
- doc: /* Call specific MSDOS interrupt number INTERRUPT with REGISTERS.
+ doc: /* Call specific MS-DOS interrupt number INTERRUPT with REGISTERS.
Return the updated REGISTER vector.
INTERRUPT should be an integer in the range 0 to 255.
REGISTERS should be a vector produced by `make-register' and
`set-register-value'. */)
- (interrupt, registers)
- Lisp_Object interrupt, registers;
+ (Lisp_Object interrupt, Lisp_Object registers)
{
register int i;
int no;
union REGS inregs, outregs;
- Lisp_Object val;
CHECK_NUMBER (interrupt);
no = (unsigned long) XINT (interrupt);
CHECK_VECTOR (registers);
- if (no < 0 || no > 0xff || XVECTOR (registers)-> size != 8)
+ if (no < 0 || no > 0xff || ASIZE (registers) != 8)
return Qnil;
for (i = 0; i < 8; i++)
CHECK_NUMBER (XVECTOR (registers)->contents[i]);
DEFUN ("msdos-memget", Fdos_memget, Sdos_memget, 2, 2, 0,
doc: /* Read DOS memory at offset ADDRESS into VECTOR.
Return the updated VECTOR. */)
- (address, vector)
- Lisp_Object address, vector;
+ (Lisp_Object address, Lisp_Object vector)
{
register int i;
int offs, len;
char *buf;
- Lisp_Object val;
CHECK_NUMBER (address);
offs = (unsigned long) XINT (address);
CHECK_VECTOR (vector);
- len = XVECTOR (vector)-> size;
+ len = ASIZE (vector);
if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
return Qnil;
buf = alloca (len);
DEFUN ("msdos-memput", Fdos_memput, Sdos_memput, 2, 2, 0,
doc: /* Write DOS memory at offset ADDRESS from VECTOR. */)
- (address, vector)
- Lisp_Object address, vector;
+ (Lisp_Object address, Lisp_Object vector)
{
register int i;
int offs, len;
char *buf;
- Lisp_Object val;
CHECK_NUMBER (address);
offs = (unsigned long) XINT (address);
CHECK_VECTOR (vector);
- len = XVECTOR (vector)-> size;
+ len = ASIZE (vector);
if (len < 1 || len > 2048 || offs < 0 || offs > 0xfffff - len)
return Qnil;
buf = alloca (len);
If the optional argument ALLKEYS is non-nil, the keyboard is mapped for
all keys; otherwise it is only used when the ALT key is pressed.
The current keyboard layout is available in dos-keyboard-code. */)
- (country_code, allkeys)
- Lisp_Object country_code, allkeys;
+ (Lisp_Object country_code, Lisp_Object allkeys)
{
CHECK_NUMBER (country_code);
if (!dos_set_keyboard (XINT (country_code), !NILP (allkeys)))
DEFUN ("msdos-mouse-p", Fmsdos_mouse_p, Smsdos_mouse_p, 0, 0, 0,
doc: /* Report whether a mouse is present. */)
- ()
+ (void)
{
if (have_mouse)
return Qt;
DEFUN ("msdos-mouse-init", Fmsdos_mouse_init, Smsdos_mouse_init, 0, 0, "",
doc: /* Initialize and enable mouse if available. */)
- ()
+ (void)
{
if (have_mouse)
{
DEFUN ("msdos-mouse-enable", Fmsdos_mouse_enable, Smsdos_mouse_enable, 0, 0, "",
doc: /* Enable mouse if available. */)
- ()
+ (void)
{
if (have_mouse)
{
DEFUN ("msdos-mouse-disable", Fmsdos_mouse_disable, Smsdos_mouse_disable, 0, 0, "",
doc: /* Disable mouse if available. */)
- ()
+ (void)
{
mouse_off ();
if (have_mouse) have_mouse = -1;
DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "",
doc: /* Insert copy of screen contents prior to starting Emacs.
Return nil if startup screen is not available. */)
- ()
+ (void)
{
char *s;
int rows, cols, i, j;
return Qt;
}
\f
-/* country info */
-EMACS_INT dos_country_code;
-EMACS_INT dos_codepage;
-EMACS_INT dos_timezone_offset;
-EMACS_INT dos_decimal_point;
-EMACS_INT dos_keyboard_layout;
unsigned char dos_country_info[DOS_COUNTRY_INFO];
static unsigned char usa_country_info[DOS_COUNTRY_INFO] = {
0, 0, /* date format */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* reserved */
};
-EMACS_INT dos_hyper_key;
-EMACS_INT dos_super_key;
-EMACS_INT dos_keypad_mode;
-
-Lisp_Object Vdos_version;
-Lisp_Object Vdos_display_scancodes;
-
#ifndef HAVE_X_WINDOWS
static unsigned dos_windows_version;
-Lisp_Object Vdos_windows_version;
-
char parent_vm_title[50]; /* Ralf Brown says 30 is enough */
int w95_set_virtual_machine_title (const char *);
#endif /* !HAVE_X_WINDOWS */
void
-init_dosfns ()
+init_dosfns (void)
{
union REGS regs;
_go32_dpmi_registers dpmiregs;
unsigned long xbuf = _go32_info_block.linear_address_of_transfer_buffer;
#ifndef SYSTEM_MALLOC
+ extern void get_lim_data (void);
+
get_lim_data (); /* why the hell isn't this called elsewhere? */
#endif
}
#endif /* !HAVE_X_WINDOWS */
-#if __DJGPP__ >= 2
-
/* Without this, we never see hidden files.
Don't OR it with the previous value, so the value recorded at dump
time, possibly with `preserve-case' flags set, won't get through. */
if (!NILP (Fmsdos_long_file_names ()))
__opendir_flags |= __OPENDIR_PRESERVE_CASE;
#endif /* __DJGPP_MINOR__ == 0 */
-#endif /* __DJGPP__ >= 2 */
}
\f
#ifndef HAVE_X_WINDOWS
sets the name in the frame struct, but has no other effects. */
void
-x_set_title (f, name)
- struct frame *f;
- Lisp_Object name;
+x_set_title (struct frame *f, Lisp_Object name)
{
/* Don't change the title if it's already NAME. */
if (EQ (name, f->title))
storage of the file system, FREE is the free storage, and AVAIL is the
storage available to a non-superuser. All 3 numbers are in bytes.
If the underlying system call fails, value is nil. */)
- (filename)
- Lisp_Object filename;
+ (Lisp_Object filename)
{
struct statfs stfs;
Lisp_Object encoded, value;
return value;
}
\f
+/* System depended enumeration of and access to system processes a-la
+ ps(1). Here, we only return info about the running Emacs process.
+ (There are no other processes on DOS, right?) */
+
+Lisp_Object
+list_system_processes (void)
+{
+ Lisp_Object proclist = Qnil;
+
+ proclist = Fcons (make_fixnum_or_float (getpid ()), proclist);
+
+ return proclist;
+}
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+ int proc_id;
+ Lisp_Object attrs = Qnil;
+
+ CHECK_NUMBER_OR_FLOAT (pid);
+ proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
+
+ if (proc_id == getpid ())
+ {
+ EMACS_INT uid, gid;
+ char *usr;
+ struct group *gr;
+ char cmd[FILENAME_MAX];
+ char *cmdline = NULL, *p, *q;
+ size_t cmdline_size = 0;
+ int i;
+ Lisp_Object cmd_str, decoded_cmd, tem;
+ double pmem;
+ EXFUN (Fget_internal_run_time, 0);
+#ifndef SYSTEM_MALLOC
+ extern unsigned long ret_lim_data ();
+#endif
+
+ uid = getuid ();
+ attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
+ usr = getlogin ();
+ if (usr)
+ attrs = Fcons (Fcons (Quser, build_string (usr)), attrs);
+ gid = getgid ();
+ attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
+ gr = getgrgid (gid);
+ if (gr)
+ attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
+ strcpy (cmd, basename (__crt0_argv[0]));
+ /* Command name is encoded in locale-coding-system; decode it. */
+ cmd_str = make_unibyte_string (cmd, strlen (cmd));
+ decoded_cmd = code_convert_string_norecord (cmd_str,
+ Vlocale_coding_system, 0);
+ attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
+ /* Pretend we have 0 as PPID. */
+ attrs = Fcons (Fcons (Qppid, make_number (0)), attrs);
+ attrs = Fcons (Fcons (Qpgrp, pid), attrs);
+ attrs = Fcons (Fcons (Qttname, build_string ("/dev/tty")), attrs);
+ /* We are never idle! */
+ tem = Fget_internal_run_time ();
+ attrs = Fcons (Fcons (Qtime, tem), attrs);
+ attrs = Fcons (Fcons (Qthcount, make_number (1)), attrs);
+ attrs = Fcons (Fcons (Qstart,
+ Fsymbol_value (intern ("before-init-time"))),
+ attrs);
+ attrs = Fcons (Fcons (Qvsize,
+ make_fixnum_or_float ((unsigned long)sbrk(0)/1024)),
+ attrs);
+ attrs = Fcons (Fcons (Qetime, tem), attrs);
+#ifndef SYSTEM_MALLOC
+ /* ret_lim_data is on vm-limit.c, which is not compiled in under
+ SYSTEM_MALLOC. */
+ pmem = (double)((unsigned long) sbrk (0)) / ret_lim_data () * 100.0;
+ if (pmem > 100)
+#endif
+ pmem = 100;
+ attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
+ /* Pass 1: Count how much storage we need. */
+ for (i = 0; i < __crt0_argc; i++)
+ {
+ cmdline_size += strlen (__crt0_argv[i]) + 1; /* +1 for blank delim */
+ if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
+ {
+ cmdline_size += 2;
+ for (p = __crt0_argv[i]; *p; p++)
+ {
+ if (*p == '"')
+ cmdline_size++;
+ }
+ }
+ }
+ /* Pass 2: Allocate storage and concatenate argv[]. */
+ cmdline = xmalloc (cmdline_size + 1);
+ for (i = 0, q = cmdline; i < __crt0_argc; i++)
+ {
+ if (strpbrk (__crt0_argv[i], " \t\n\r\v\f"))
+ {
+ *q++ = '"';
+ for (p = __crt0_argv[i]; *p; p++)
+ {
+ if (*p == '\"')
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ *q++ = '"';
+ }
+ else
+ {
+ strcpy (q, __crt0_argv[i]);
+ q += strlen (__crt0_argv[i]);
+ }
+ *q++ = ' ';
+ }
+ /* Remove the trailing blank. */
+ if (q > cmdline)
+ q[-1] = '\0';
+
+ /* Command line is encoded in locale-coding-system; decode it. */
+ cmd_str = make_unibyte_string (cmdline, strlen (cmdline));
+ decoded_cmd = code_convert_string_norecord (cmd_str,
+ Vlocale_coding_system, 0);
+ xfree (cmdline);
+ attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
+ }
+
+ return attrs;
+}
+\f
void
dos_cleanup (void)
{
+ struct tty_display_info *tty;
+
#ifndef HAVE_X_WINDOWS
restore_parent_vm_title ();
#endif
/* Make sure the termscript file is committed, in case we are
crashing and some vital info was written there. */
- if (termscript)
+ if (FRAMEP (selected_frame))
{
- fflush (termscript);
- fsync (fileno (termscript));
+ struct frame *sf = XFRAME (selected_frame);
+
+ if (FRAME_LIVE_P (sf)
+ && (FRAME_MSDOS_P (sf) || FRAME_TERMCAP_P (sf)))
+ {
+ tty = CURTTY ();
+ if (tty->termscript)
+ {
+ fflush (tty->termscript);
+ fsync (fileno (tty->termscript));
+ }
+ }
}
}
/*
* Define everything
*/
-syms_of_dosfns ()
+void
+syms_of_dosfns (void)
{
defsubr (&Sint86);
defsubr (&Sdos_memget);
defsubr (&Smsdos_mouse_p);
#endif
- DEFVAR_INT ("dos-country-code", &dos_country_code,
+ DEFVAR_INT ("dos-country-code", dos_country_code,
doc: /* The country code returned by Dos when Emacs was started.
Usually this is the international telephone prefix. */);
- DEFVAR_INT ("dos-codepage", &dos_codepage,
+ DEFVAR_INT ("dos-codepage", dos_codepage,
doc: /* The codepage active when Emacs was started.
The following are known:
437 United States
863 Canada (French)
865 Norway/Denmark */);
- DEFVAR_INT ("dos-timezone-offset", &dos_timezone_offset,
+ DEFVAR_INT ("dos-timezone-offset", dos_timezone_offset,
doc: /* The current timezone offset to UTC in minutes.
Implicitly modified when the TZ variable is changed. */);
- DEFVAR_LISP ("dos-version", &Vdos_version,
+ DEFVAR_LISP ("dos-version", Vdos_version,
doc: /* The (MAJOR . MINOR) Dos version (subject to modification with setver). */);
#ifndef HAVE_X_WINDOWS
- DEFVAR_LISP ("dos-windows-version", &Vdos_windows_version,
+ DEFVAR_LISP ("dos-windows-version", Vdos_windows_version,
doc: /* The (MAJOR . MINOR) Windows version for DOS session on MS-Windows. */);
#endif
- DEFVAR_LISP ("dos-display-scancodes", &Vdos_display_scancodes,
+ DEFVAR_LISP ("dos-display-scancodes", Vdos_display_scancodes,
doc: /* *Controls whether DOS raw keyboard events are displayed as you type.
When non-nil, the keyboard scan-codes are displayed at the bottom right
corner of the display (typically at the end of the mode line).
Vdos_display_scancodes = Qnil;
- DEFVAR_INT ("dos-hyper-key", &dos_hyper_key,
+ DEFVAR_INT ("dos-hyper-key", dos_hyper_key,
doc: /* *If set to 1, use right ALT key as hyper key.
If set to 2, use right CTRL key as hyper key. */);
dos_hyper_key = 0;
- DEFVAR_INT ("dos-super-key", &dos_super_key,
+ DEFVAR_INT ("dos-super-key", dos_super_key,
doc: /* *If set to 1, use right ALT key as super key.
If set to 2, use right CTRL key as super key. */);
dos_super_key = 0;
- DEFVAR_INT ("dos-keypad-mode", &dos_keypad_mode,
+ DEFVAR_INT ("dos-keypad-mode", dos_keypad_mode,
doc: /* *Controls what key code is returned by a key in the numeric keypad.
The `numlock ON' action is only taken if no modifier keys are pressed.
The value is an integer constructed by adding the following bits together:
0x200 ALT-0..ALT-9 in top-row produces shifted codes. */);
dos_keypad_mode = 0x75;
- DEFVAR_INT ("dos-keyboard-layout", &dos_keyboard_layout,
+ DEFVAR_INT ("dos-keyboard-layout", dos_keyboard_layout,
doc: /* Contains the country code for the current keyboard layout.
Use msdos-set-keyboard to select another keyboard layout. */);
dos_keyboard_layout = 1; /* US */
- DEFVAR_INT ("dos-decimal-point", &dos_decimal_point,
+ DEFVAR_INT ("dos-decimal-point", dos_decimal_point,
doc: /* The character to produce when kp-decimal key is pressed.
If non-zero, this variable contains the character to be returned when the
decimal point key in the numeric keypad is pressed when Num Lock is on.
}
#endif /* MSDOS */
-/* arch-tag: f5ea8847-a014-42c9-83f5-7738ad640b17
- (do not change this comment) */