summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2007-10-11 16:24:58 +0000
committerMiles Bader <miles@gnu.org>2007-10-11 16:24:58 +0000
commitc73bd236f75b742ad4642ec94798987ae6e3e1e8 (patch)
treeef5edc8db557fc1d25a17c379e4ae63a38b3ba5c /lib-src
parentecb21060d5c1752d41d7a742be565c59b5fcb855 (diff)
parent58ade22bf16a9ec2ff0aee6c59d8db4d1703e94f (diff)
downloademacs-c73bd236f75b742ad4642ec94798987ae6e3e1e8.tar.gz
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 866-879) - Merge multi-tty branch - Update from CVS - Merge from emacs--rel--22 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-257
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog111
-rw-r--r--lib-src/Makefile.in30
-rw-r--r--lib-src/emacsclient.c793
-rw-r--r--lib-src/emacstool.c504
-rw-r--r--lib-src/makefile.w32-in6
5 files changed, 731 insertions, 713 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 9d7d076ca46..6ea05fb9e9a 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,103 @@
+2007-10-09 Juanma Barranquero <lekktu@gmail.com>
+
+ * emacsclient.c (print_help_and_exit): Fix space to improve
+ alignment in output messages.
+
+2007-09-27 Jason Rumney <jasonr@gnu.org>
+
+ * makefile.w32-in (emacsclient, emacsclientw): Link to COMCTL32.
+
+ * emacsclient.c (w32_window_app): Init common controls when windowed.
+
+2007-09-21 Glenn Morris <rgm@gnu.org>
+
+ * emacstool.c: Remove file.
+ * Makefile.in (emacstool, nemacstool, xvetool, xveterm):
+ Delete targets built from emacstool.
+
+2007-09-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacsclient.c (decode_options): -t implies -c.
+
+2007-09-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacsclient.c (DIRECTORY_SEP, IS_DIRECTORY_SEP, IS_DEVICE_SEP)
+ (IS_ANY_SEP): Only define if !defined(HAVE_GET_CURRENT_DIR_NAME).
+ (main_argc): Remove.
+ (strprefix): Use strncmp.
+
+2007-09-20 Jason Rumney <jasonr@gnu.org>
+
+ * emacsclient.c (main) [SIGSTOP]: Change conditional from WINDOWSNT.
+
+2007-09-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacsclient.c (current_frame): Change the default.
+ (longopts): Replace --current-frame by --create-frame.
+ (decode_options): Reverse the meaning of -c.
+ (print_help_and_exit): Update help text accordingly.
+ (main): Remove the -version and -good-version messages.
+
+2007-09-12 Glenn Morris <rgm@gnu.org>
+
+ * Makefile.in (SOURCES, unlock, relock): Delete.
+
+2007-08-29 Glenn Morris <rgm@gnu.org>
+
+ * makefile.w32-in (VERSION): Increase to 23.0.50.
+
+2007-08-29 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * emacsclient.c (w32_execvp): Move definition before use.
+ (decode_options): Don't use a tty on mac carbon or windows.
+
+2007-08-29 Jason Rumney <jasonr@gnu.org>
+
+ * emacsclient.c (SEND_STRING, SEND_QUOTED): Remove obfuscation macros.
+ (quote_argument, set_tcp_socket, handle_sigcont, handle_sigtstp):
+ (main): Expand removed macros inline.
+ (main) [WINDOWSNT]: Don't call ttyname. Don't recognize -suspend
+ option.
+ (main) [NO_SOCKETS_IN_FILE_SYSTEM]: Don't call init_signals.
+
+2007-08-29 Karoly Lorentey <lorentey@elte.hu>
+
+ * emacsclient.c (signal.h): New include.
+ (sys/stat.h, errno.h): Always include, even on WINDOWSNT.
+ (DIRECTORY_SEP, IS_DIRECTORY_SEP, IS_DEVICE_SEP, IS_ANY_SEP):
+ Copy definitions here from src/lisp.h.
+ (main_argc, main_argv, current_frame, window_system, tty): New vars.
+ (longopts): Add tty, current-frame.
+ (xmalloc, xstrdup): New functions.
+ (get_current_dir_name): New function, copied from src/sysdep.c.
+ (decode_options): Set display from environment. Add tty and
+ current_frame options. Make --no-wait imply --current-frame,
+ except when it is the only option given. Make sure no frame is
+ opened when --current-frame is set.
+ (print_help_and_exit): Document tty and current-frame options.
+ (fail): Change arguments to void.
+ (main): When sockets are not defined, set main_argc, main_argv,
+ and call fail() with no arguments.
+ (emacs_socket): New variable (moved out from main `s').
+ (quote_file_name): Rename to quote_argument.
+ (quote_argument): New name for old quote_file_name.
+ (unquote_argument, strprefix, pass_signal_to_emacs)
+ (handle_sigcont, handle_sigtstp, init_signals): New functions.
+ (set_local_socket): Initialize saved_errno to 0. If socket-name
+ is too long, call `fail' rather than `exit'.
+ (main): Doc update. Set main_argc, main_argv. New var `str'.
+ Don't need a filename or argument if tty or window_system set.
+ Call fail with no arguments. Use get_current_dir_name to send
+ over the current directory. Send version number to Emacs for
+ verification. If tty is set, check TERM, and pass name and type
+ to Emacs. Pass window_system to Emacs. Move sending of eval to
+ optind loop. Send -position, -file to Emacs. Call fsync after
+ fflush. Check for a client/server version match.
+ Handle -emacs-pid, -window-system-unsupported, -print, -error, and
+ -suspend commands. Don't exit prematurely on --no-wait, let Emacs
+ close the connection for us. When creating a new frame, send
+ environment and pwd to Emacs. Send current-frame to Emacs.
+
2007-08-25 Eli Zaretskii <eliz@gnu.org>
* Makefile.in (rcs2log, rcs-checkin, grep-changelog, vcdiff):
@@ -316,8 +416,7 @@
suggest using options to make them explicit.
(AUTH_KEY_LENGTH, SEND_BUFFER_SIZE): New constants.
(send_buffer, sblen): New variables.
- (send_to_emacs): New function to buffer output and send it with
- send().
+ (send_to_emacs): New function to buffer output and send it with `send'.
(quote_file_name): Use SEND_STRING.
(close_winsock, initialize_sockets): New functions to load and
unload Winsock.
@@ -423,8 +522,8 @@
2006-05-23 Francesco Potort,Al(B <pot@gnu.org>
- * pop.c (pop_open, socket_connection, KPOP_SERVICE): Added
- comments explaining why the "kpop" service is never used.
+ * pop.c (pop_open, socket_connection, KPOP_SERVICE):
+ Add comments explaining why the "kpop" service is never used.
2006-05-13 Eli Zaretskii <eliz@gnu.org>
@@ -532,7 +631,7 @@
* makefile.w32-in (../src/config.h): Don't overwrite. Print a
message instead.
- (../src/paths.h): Removed.
+ (../src/paths.h): Remove.
2005-07-27 Juanma Barranquero <lekktu@gmail.com>
@@ -910,7 +1009,7 @@
2003-01-06 Kim F. Storm <storm@cua.dk>
- * pop.c (__P): Renamed from _P to avoid problems on Cygwin.
+ * pop.c (__P): Rename from _P to avoid problems on Cygwin.
All uses changed.
2002-12-18 Andrew Innes <andrewi@gnu.org>
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index 5d8da71dbdd..91074d3ccb1 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -122,9 +122,6 @@ SCRIPTS= rcs2log vcdiff
EXECUTABLES= ${UTILITIES} ${INSTALLABLES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS}
-SOURCES = COPYING ChangeLog Makefile.in README emacs.csh \
- makedoc.com *.[chy] rcs2log vcdiff
-
# Additional -D flags for movemail (add to MOVE_FLAGS if desired):
# MAIL_USE_POP Support mail retrieval from a POP mailbox.
# MAIL_USE_MMDF Support MMDF mailboxes.
@@ -368,12 +365,6 @@ maintainer-clean: distclean
extraclean: maintainer-clean
-rm -f *~ \#*
-unlock:
- chmod u+w $(SOURCES)
-
-relock:
- chmod u-w $(SOURCES)
-
/* Test the contents of the directory. */
check:
@echo "We don't have any tests for GNU Emacs yet."
@@ -471,24 +462,3 @@ update-game-score${EXEEXT}: update-game-score.o $(GETOPTDEPS)
update-game-score.o: ${srcdir}/update-game-score.c ../src/config.h $(GETOPT_H)
$(CC) -c ${CPP_CFLAGS} ${srcdir}/update-game-score.c \
-DHAVE_SHARED_GAME_DIR="\"$(gamedir)\""
-
-/* These are NOT included in INSTALLABLES or UTILITIES.
- See ../src/Makefile.in. */
-emacstool${EXEEXT}: ${srcdir}/emacstool.c
- $(CC) ${srcdir}/emacstool.c -o emacstool ${ALL_CFLAGS} \
- -lsuntool -lsunwindow -lpixrect $(LOADLIBES)
-
-/* For SUN Japanese Language Environment. */
-nemacstool${EXEEXT}: ${srcdir}/emacstool.c
- $(CC) -o nemacstool -DJLE ${ALL_CFLAGS} ${srcdir}/emacstool.c \
- -lsuntool -lmle -lsunwindow -lpixrect $(LOADLIBES)
-
-xvetool${EXEEXT}: ${srcdir}/emacstool.c
- $(CC) -o xvetool -DXVIEW ${ALL_CFLAGS} ${srcdir}/emacstool.c \
- -lxview -lX -I$(OPENWINHOME)/include -L$(OPENWINHOME)/lib \
- $(LOADLIBES)
-
-xveterm${EXEEXT}: ${srcdir}/emacstool.c
- $(CC) -o xveterm -DXVIEW -DTTERM ${ALL_CFLAGS} ${srcdir}/emacstool.c \
- -lxview -lolgx -lX -I$(OPENWINHOME)/include -L$(OPENWINHOME)/lib \
- $(LOADLIBES)
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 9edba132134..bfa4f9c01d7 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -35,6 +35,7 @@ Boston, MA 02110-1301, USA. */
# include <malloc.h>
# include <stdlib.h>
# include <windows.h>
+# include <commctrl.h>
# define NO_SOCKETS_IN_FILE_SYSTEM
@@ -76,7 +77,12 @@ Boston, MA 02110-1301, USA. */
# include <pwd.h>
#endif /* not WINDOWSNT */
#endif /* not VMS */
+#include <sys/stat.h>
+#include <signal.h>
+#include <errno.h>
+
+
char *getenv (), *getwd ();
char *(getcwd) ();
@@ -84,8 +90,6 @@ char *(getcwd) ();
#define VERSION "unspecified"
#endif
-#define SEND_STRING(data) (send_to_emacs (s, (data)))
-#define SEND_QUOTED(data) (quote_file_name (s, (data)))
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
@@ -110,15 +114,27 @@ char *(getcwd) ();
/* Name used to invoke this program. */
char *progname;
+/* The second argument to main. */
+char **main_argv;
+
/* Nonzero means don't wait for a response from Emacs. --no-wait. */
int nowait = 0;
/* Nonzero means args are expressions to be evaluated. --eval. */
int eval = 0;
+/* Nonzero means don't open a new frame. Inverse of --create-frame. */
+int current_frame = 1;
+
+/* Nonzero means open a new graphical frame. */
+int window_system = 0;
+
/* The display on which Emacs should work. --display. */
char *display = NULL;
+/* Nonzero means open a new Emacs frame on the current terminal. */
+int tty = 0;
+
/* If non-NULL, the name of an editor to fallback to if the server
is not running. --alternate-editor. */
const char *alternate_editor = NULL;
@@ -140,6 +156,8 @@ struct option longopts[] =
{ "eval", no_argument, NULL, 'e' },
{ "help", no_argument, NULL, 'H' },
{ "version", no_argument, NULL, 'V' },
+ { "tty", no_argument, NULL, 't' },
+ { "create-frame", no_argument, NULL, 'c' },
{ "alternate-editor", required_argument, NULL, 'a' },
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
{ "socket-name", required_argument, NULL, 's' },
@@ -149,6 +167,130 @@ struct option longopts[] =
{ 0, 0, 0, 0 }
};
+
+/* Like malloc but get fatal error if memory is exhausted. */
+
+long *
+xmalloc (size)
+ unsigned int size;
+{
+ long *result = (long *) malloc (size);
+ if (result == NULL)
+ {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ return result;
+}
+
+/* Like strdup but get a fatal error if memory is exhausted. */
+
+char *
+xstrdup (const char *s)
+{
+ char *result = strdup (s);
+ if (result == NULL)
+ {
+ perror ("strdup");
+ exit (EXIT_FAILURE);
+ }
+ return result;
+}
+
+/* From sysdep.c */
+#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
+
+/* From lisp.h */
+#ifndef DIRECTORY_SEP
+#define DIRECTORY_SEP '/'
+#endif
+#ifndef IS_DIRECTORY_SEP
+#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
+#endif
+#ifndef IS_DEVICE_SEP
+#ifndef DEVICE_SEP
+#define IS_DEVICE_SEP(_c_) 0
+#else
+#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
+#endif
+#endif
+#ifndef IS_ANY_SEP
+#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
+#endif
+
+
+/* Return the current working directory. Returns NULL on errors.
+ Any other returned value must be freed with free. This is used
+ only when get_current_dir_name is not defined on the system. */
+char*
+get_current_dir_name ()
+{
+ char *buf;
+ char *pwd;
+ struct stat dotstat, pwdstat;
+ /* If PWD is accurate, use it instead of calling getwd. PWD is
+ sometimes a nicer name, and using it may avoid a fatal error if a
+ parent directory is searchable but not readable. */
+ if ((pwd = getenv ("PWD")) != 0
+ && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
+ && stat (pwd, &pwdstat) == 0
+ && stat (".", &dotstat) == 0
+ && dotstat.st_ino == pwdstat.st_ino
+ && dotstat.st_dev == pwdstat.st_dev
+#ifdef MAXPATHLEN
+ && strlen (pwd) < MAXPATHLEN
+#endif
+ )
+ {
+ buf = (char *) xmalloc (strlen (pwd) + 1);
+ if (!buf)
+ return NULL;
+ strcpy (buf, pwd);
+ }
+#ifdef HAVE_GETCWD
+ else
+ {
+ size_t buf_size = 1024;
+ buf = (char *) xmalloc (buf_size);
+ if (!buf)
+ return NULL;
+ for (;;)
+ {
+ if (getcwd (buf, buf_size) == buf)
+ break;
+ if (errno != ERANGE)
+ {
+ int tmp_errno = errno;
+ free (buf);
+ errno = tmp_errno;
+ return NULL;
+ }
+ buf_size *= 2;
+ buf = (char *) realloc (buf, buf_size);
+ if (!buf)
+ return NULL;
+ }
+ }
+#else
+ else
+ {
+ /* We need MAXPATHLEN here. */
+ buf = (char *) xmalloc (MAXPATHLEN + 1);
+ if (!buf)
+ return NULL;
+ if (getwd (buf) == NULL)
+ {
+ int tmp_errno = errno;
+ free (buf);
+ errno = tmp_errno;
+ return NULL;
+ }
+ }
+#endif
+ return buf;
+}
+#endif
+
/* Message functions. */
#ifdef WINDOWSNT
@@ -159,13 +301,51 @@ w32_window_app ()
char szTitle[MAX_PATH];
if (window_app < 0)
- /* Checking for STDOUT does not work; it's a valid handle also in
- nonconsole apps. Testing for the console title seems to work. */
- window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
+ {
+ /* Checking for STDOUT does not work; it's a valid handle also in
+ nonconsole apps. Testing for the console title seems to work. */
+ window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
+ if (window_app)
+ InitCommonControls();
+ }
return window_app;
}
-#endif
+
+/*
+ execvp wrapper for Windows. Quotes arguments with embedded spaces.
+
+ This is necessary due to the broken implementation of exec* routines in
+ the Microsoft libraries: they concatenate the arguments together without
+ quoting special characters, and pass the result to CreateProcess, with
+ predictably bad results. By contrast, Posix execvp passes the arguments
+ directly into the argv array of the child process.
+*/
+int
+w32_execvp (path, argv)
+ char *path;
+ char **argv;
+{
+ int i;
+
+ /* Required to allow a .BAT script as alternate editor. */
+ argv[0] = (char *) alternate_editor;
+
+ for (i = 0; argv[i]; i++)
+ if (strchr (argv[i], ' '))
+ {
+ char *quoted = alloca (strlen (argv[i]) + 3);
+ sprintf (quoted, "\"%s\"", argv[i]);
+ argv[i] = quoted;
+ }
+
+ return execvp (path, argv);
+}
+
+#undef execvp
+#define execvp w32_execvp
+
+#endif /* WINDOWSNT */
void
message (int is_error, char *message, ...)
@@ -204,16 +384,19 @@ decode_options (argc, argv)
char **argv;
{
alternate_editor = getenv ("ALTERNATE_EDITOR");
+ display = getenv ("DISPLAY");
+ if (display && strlen (display) == 0)
+ display = NULL;
while (1)
{
int opt = getopt_long (argc, argv,
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
- "VHnea:s:f:d:",
+ "VHnea:s:f:d:tc",
#else
- "VHnea:f:d:",
+ "VHnea:f:d:tc",
#endif
- longopts, 0);
+ longopts, 0);
if (opt == EOF)
break;
@@ -256,6 +439,15 @@ decode_options (argc, argv)
exit (EXIT_SUCCESS);
break;
+ case 't':
+ tty = 1;
+ current_frame = 0;
+ break;
+
+ case 'c':
+ current_frame = 0;
+ break;
+
case 'H':
print_help_and_exit ();
break;
@@ -266,21 +458,49 @@ decode_options (argc, argv)
break;
}
}
+
+ if (!tty && display)
+ window_system = 1;
+#if !defined (WINDOWSNT) && !defined (HAVE_CARBON)
+ else
+ tty = 1;
+#endif
+
+ /* --no-wait implies --current-frame on ttys when there are file
+ arguments or expressions given. */
+ if (nowait && tty && argc - optind > 0)
+ current_frame = 1;
+
+ if (current_frame)
+ {
+ tty = 0;
+ window_system = 0;
+ }
+
+ if (tty)
+ window_system = 0;
}
+
void
print_help_and_exit ()
{
+ /* Spaces and tabs are significant in this message; they're chosen so the
+ message aligns properly both in a tty and in a Windows message box.
+ Please try to preserve them; otherwise the output is very hard to read
+ when using emacsclientw. */
message (FALSE,
- "Usage: %s [OPTIONS] FILE...\n\
+ "Usage: %s [OPTIONS] FILE...\n\
Tell the Emacs server to visit the specified files.\n\
Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
\n\
The following OPTIONS are accepted:\n\
-\n\
-V, --version Just print version info and return\n\
--H, --help Print this usage information message\n\
--e, --eval Evaluate FILE arguments as Lisp expressions\n\
+-H, --help Print this usage information message\n\
+-t, --tty Open a new Emacs frame on the current terminal\n\
+-c, --create-frame Create a new frame instead of trying to\n\
+ use the current Emacs frame\n\
+-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
-n, --no-wait Don't wait for the server to return\n\
-d, --display=DISPLAY Visit the file in the given display\n"
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
@@ -290,66 +510,27 @@ The following OPTIONS are accepted:\n\
"-f, --server-file=FILENAME\n\
Set filename of the TCP authentication file\n\
-a, --alternate-editor=EDITOR\n\
- Editor to fallback to if server is not running\n\
+ Editor to fallback to if the server is not running\n\
\n\
Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
exit (EXIT_SUCCESS);
}
-
-#ifdef WINDOWSNT
-
-/*
- execvp wrapper for Windows. Quotes arguments with embedded spaces.
-
- This is necessary due to the broken implementation of exec* routines in
- the Microsoft libraries: they concatenate the arguments together without
- quoting special characters, and pass the result to CreateProcess, with
- predictably bad results. By contrast, Posix execvp passes the arguments
- directly into the argv array of the child process.
-*/
-int
-w32_execvp (path, argv)
- char *path;
- char **argv;
-{
- int i;
-
- /* Required to allow a .BAT script as alternate editor. */
- argv[0] = (char *) alternate_editor;
-
- for (i = 0; argv[i]; i++)
- if (strchr (argv[i], ' '))
- {
- char *quoted = alloca (strlen (argv[i]) + 3);
- sprintf (quoted, "\"%s\"", argv[i]);
- argv[i] = quoted;
- }
-
- return execvp (path, argv);
-}
-
-#undef execvp
-#define execvp w32_execvp
-
-#endif /* WINDOWSNT */
-
/*
Try to run a different command, or --if no alternate editor is
defined-- exit with an errorcode.
+ Uses argv, but gets it from the global variable main_argv.
*/
void
-fail (argc, argv)
- int argc;
- char **argv;
+fail (void)
{
if (alternate_editor)
{
int i = optind - 1;
- execvp (alternate_editor, argv + i);
+ execvp (alternate_editor, main_argv + i);
message (TRUE, "%s: error executing alternate editor \"%s\"\n",
- progname, alternate_editor);
+ progname, alternate_editor);
}
exit (EXIT_FAILURE);
}
@@ -362,10 +543,12 @@ main (argc, argv)
int argc;
char **argv;
{
- message (TRUE, "%s: Sorry, the Emacs server is supported only\non systems with Berkely sockets.\n",
+ main_argv = argv;
+ progname = argv[0];
+ message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
+ "on systems with Berkeley sockets.\n",
argv[0]);
-
- fail (argc, argv);
+ fail ();
}
#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
@@ -376,8 +559,6 @@ main (argc, argv)
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/un.h>
-# include <sys/stat.h>
-# include <errno.h>
#endif
#define AUTH_KEY_LENGTH 64
@@ -389,6 +570,8 @@ extern int errno;
/* Buffer to accumulate data to send in TCP connections. */
char send_buffer[SEND_BUFFER_SIZE + 1];
int sblen = 0; /* Fill pointer for the send buffer. */
+/* Socket used to communicate with the Emacs server process. */
+HSOCKET emacs_socket = 0;
/* Let's send the data to Emacs when either
- the data ends in "\n", or
@@ -429,18 +612,21 @@ send_to_emacs (s, data)
}
}
-/* In NAME, insert a & before each &, each space, each newline, and
+
+/* In STR, insert a & before each &, each space, each newline, and
any initial -. Change spaces to underscores, too, so that the
- return value never contains a space. */
+ return value never contains a space.
+
+ Does not change the string. Outputs the result to STREAM. */
void
-quote_file_name (s, name)
+quote_argument (s, str)
HSOCKET s;
- char *name;
+ char *str;
{
- char *copy = (char *) malloc (strlen (name) * 2 + 1);
+ char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
char *p, *q;
- p = name;
+ p = str;
q = copy;
while (*p)
{
@@ -458,18 +644,54 @@ quote_file_name (s, name)
}
else
{
- if (*p == '&' || (*p == '-' && p == name))
+ if (*p == '&' || (*p == '-' && p == str))
*q++ = '&';
*q++ = *p++;
}
}
*q++ = 0;
- SEND_STRING (copy);
+ send_to_emacs (s, copy);
free (copy);
}
+
+/* The inverse of quote_argument. Removes quoting in string STR by
+ modifying the string in place. Returns STR. */
+
+char *
+unquote_argument (str)
+ char *str;
+{
+ char *p, *q;
+
+ if (! str)
+ return str;
+
+ p = str;
+ q = str;
+ while (*p)
+ {
+ if (*p == '&')
+ {
+ p++;
+ if (*p == '&')
+ *p = '&';
+ else if (*p == '_')
+ *p = ' ';
+ else if (*p == 'n')
+ *p = '\n';
+ else if (*p == '-')
+ *p = '-';
+ }
+ *q++ = *p++;
+ }
+ *q = 0;
+ return str;
+}
+
+
int
file_name_absolute_p (filename)
const unsigned char *filename;
@@ -551,6 +773,7 @@ initialize_sockets ()
atexit (close_winsock);
}
#endif /* WINDOWSNT */
+
/*
* Read the information needed to set up a TCP comm channel with
@@ -661,13 +884,22 @@ set_tcp_socket ()
*/
auth_string[AUTH_KEY_LENGTH] = '\0';
- SEND_STRING ("-auth ");
- SEND_STRING (auth_string);
- SEND_STRING ("\n");
+ send_to_emacs (s, "-auth ");
+ send_to_emacs (s, auth_string);
+ send_to_emacs (s, "\n");
return s;
}
+
+/* Returns 1 if PREFIX is a prefix of STRING. */
+static int
+strprefix (char *prefix, char *string)
+{
+ return !strncmp (prefix, string, strlen (prefix));
+}
+
+
#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
/* Three possibilities:
@@ -690,6 +922,93 @@ socket_status (socket_name)
return 0;
}
+
+/* A signal handler that passes the signal to the Emacs process.
+ Useful for SIGWINCH. */
+
+SIGTYPE
+pass_signal_to_emacs (int signalnum)
+{
+ int old_errno = errno;
+
+ if (emacs_pid)
+ kill (emacs_pid, signalnum);
+
+ signal (signalnum, pass_signal_to_emacs);
+ errno = old_errno;
+}
+
+/* Signal handler for SIGCONT; notify the Emacs process that it can
+ now resume our tty frame. */
+
+SIGTYPE
+handle_sigcont (int signalnum)
+{
+ int old_errno = errno;
+
+ if (tcgetpgrp (1) == getpgrp ())
+ {
+ /* We are in the foreground. */
+ send_to_emacs (emacs_socket, "-resume \n");
+ }
+ else
+ {
+ /* We are in the background; cancel the continue. */
+ kill (getpid (), SIGSTOP);
+ }
+
+ signal (signalnum, handle_sigcont);
+ errno = old_errno;
+}
+
+/* Signal handler for SIGTSTP; notify the Emacs process that we are
+ going to sleep. Normally the suspend is initiated by Emacs via
+ server-handle-suspend-tty, but if the server gets out of sync with
+ reality, we may get a SIGTSTP on C-z. Handling this signal and
+ notifying Emacs about it should get things under control again. */
+
+SIGTYPE
+handle_sigtstp (int signalnum)
+{
+ int old_errno = errno;
+ sigset_t set;
+
+ if (emacs_socket)
+ send_to_emacs (emacs_socket, "-suspend \n");
+
+ /* Unblock this signal and call the default handler by temprarily
+ changing the handler and resignalling. */
+ sigprocmask (SIG_BLOCK, NULL, &set);
+ sigdelset (&set, signalnum);
+ signal (signalnum, SIG_DFL);
+ kill (getpid (), signalnum);
+ sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
+ signal (signalnum, handle_sigtstp);
+
+ errno = old_errno;
+}
+/* Set up signal handlers before opening a frame on the current tty. */
+
+void
+init_signals (void)
+{
+ /* Set up signal handlers. */
+ signal (SIGWINCH, pass_signal_to_emacs);
+
+ /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
+ deciding which terminal the signal came from. C-g is now a
+ normal input event on secondary terminals. */
+#if 0
+ signal (SIGINT, pass_signal_to_emacs);
+ signal (SIGQUIT, pass_signal_to_emacs);
+#endif
+
+ signal (SIGCONT, handle_sigcont);
+ signal (SIGTSTP, handle_sigtstp);
+ signal (SIGTTOU, handle_sigtstp);
+}
+
+
HSOCKET
set_local_socket ()
{
@@ -711,30 +1030,30 @@ set_local_socket ()
{
int sock_status = 0;
int default_sock = !socket_name;
- int saved_errno;
+ int saved_errno = 0;
char *server_name = "server";
if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
{ /* socket_name is a file name component. */
- server_name = socket_name;
- socket_name = NULL;
- default_sock = 1; /* Try both UIDs. */
+ server_name = socket_name;
+ socket_name = NULL;
+ default_sock = 1; /* Try both UIDs. */
}
if (default_sock)
{
- socket_name = alloca (100 + strlen (server_name));
- sprintf (socket_name, "/tmp/emacs%d/%s",
- (int) geteuid (), server_name);
+ socket_name = alloca (100 + strlen (server_name));
+ sprintf (socket_name, "/tmp/emacs%d/%s",
+ (int) geteuid (), server_name);
}
if (strlen (socket_name) < sizeof (server.sun_path))
strcpy (server.sun_path, socket_name);
else
{
- message (TRUE, "%s: socket-name %s too long",
- progname, socket_name);
- exit (EXIT_FAILURE);
+ message (TRUE, "%s: socket-name %s too long",
+ progname, socket_name);
+ fail ();
}
/* See if the socket exists, and if it's owned by us. */
@@ -773,7 +1092,7 @@ set_local_socket ()
}
sock_status = socket_status (server.sun_path);
- saved_errno = errno;
+ saved_errno = errno;
}
else
errno = saved_errno;
@@ -783,26 +1102,26 @@ set_local_socket ()
switch (sock_status)
{
case 1:
- /* There's a socket, but it isn't owned by us. This is OK if
- we are root. */
- if (0 != geteuid ())
- {
- message (TRUE, "%s: Invalid socket owner\n", progname);
+ /* There's a socket, but it isn't owned by us. This is OK if
+ we are root. */
+ if (0 != geteuid ())
+ {
+ message (TRUE, "%s: Invalid socket owner\n", progname);
return INVALID_SOCKET;
- }
- break;
+ }
+ break;
case 2:
- /* `stat' failed */
- if (saved_errno == ENOENT)
- message (TRUE,
- "%s: can't find socket; have you started the server?\n\
+ /* `stat' failed */
+ if (saved_errno == ENOENT)
+ message (TRUE,
+ "%s: can't find socket; have you started the server?\n\
To start the server in Emacs, type \"M-x server-start\".\n",
progname);
- else
- message (TRUE, "%s: can't stat %s: %s\n",
+ else
+ message (TRUE, "%s: can't stat %s: %s\n",
progname, server.sun_path, strerror (saved_errno));
- return INVALID_SOCKET;
+ return INVALID_SOCKET;
}
}
@@ -830,10 +1149,9 @@ set_socket ()
{
s = set_local_socket ();
if ((s != INVALID_SOCKET) || alternate_editor)
- return s;
-
+ return s;
message (TRUE, "%s: error accessing socket \"%s\"",
- progname, socket_name);
+ progname, socket_name);
exit (EXIT_FAILURE);
}
#endif
@@ -846,10 +1164,10 @@ set_socket ()
{
s = set_tcp_socket ();
if ((s != INVALID_SOCKET) || alternate_editor)
- return s;
+ return s;
message (TRUE, "%s: error accessing server file \"%s\"",
- progname, server_file);
+ progname, server_file);
exit (EXIT_FAILURE);
}
@@ -938,129 +1256,264 @@ main (argc, argv)
int argc;
char **argv;
{
- HSOCKET s;
int i, rl, needlf = 0;
- char *cwd;
+ char *cwd, *str;
char string[BUFSIZ+1];
+ main_argv = argv;
progname = argv[0];
/* Process options. */
decode_options (argc, argv);
- if ((argc - optind < 1) && !eval)
+ if ((argc - optind < 1) && !eval && !tty && !window_system)
{
- message (TRUE, "%s: file name or argument required\nTry `%s --help' for more information\n",
- progname, progname);
+ message (TRUE, "%s: file name or argument required\n"
+ "Try `%s --help' for more information\n",
+ progname, progname);
exit (EXIT_FAILURE);
}
- if ((s = set_socket ()) == INVALID_SOCKET)
- fail (argc, argv);
+ if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
+ fail ();
-#ifdef HAVE_GETCWD
- cwd = getcwd (string, sizeof string);
-#else
- cwd = getwd (string);
-#endif
+
+ cwd = get_current_dir_name ();
if (cwd == 0)
{
/* getwd puts message in STRING if it fails. */
- message (TRUE, "%s: %s (%s)\n", progname,
-#ifdef HAVE_GETCWD
- "Cannot get current working directory",
-#else
- string,
-#endif
- strerror (errno));
- fail (argc, argv);
+ message (TRUE, "%s: %s\n", progname,
+ "Cannot get current working directory");
+ fail ();
}
#ifdef WINDOWSNT
w32_give_focus ();
#endif
+ /* Send over our environment. */
+ if (!current_frame)
+ {
+ extern char **environ;
+ int i;
+ for (i = 0; environ[i]; i++)
+ {
+ char *name = xstrdup (environ[i]);
+ char *value = strchr (name, '=');
+ send_to_emacs (emacs_socket, "-env ");
+ quote_argument (emacs_socket, environ[i]);
+ send_to_emacs (emacs_socket, " ");
+ }
+ }
+
+ /* Send over our current directory. */
+ if (!current_frame)
+ {
+ send_to_emacs (emacs_socket, "-dir ");
+ quote_argument (emacs_socket, cwd);
+ send_to_emacs (emacs_socket, "/");
+ send_to_emacs (emacs_socket, " ");
+ }
+
+ retry:
if (nowait)
- SEND_STRING ("-nowait ");
+ send_to_emacs (emacs_socket, "-nowait ");
- if (eval)
- SEND_STRING ("-eval ");
+ if (current_frame)
+ send_to_emacs (emacs_socket, "-current-frame ");
if (display)
{
- SEND_STRING ("-display ");
- SEND_QUOTED (display);
- SEND_STRING (" ");
+ send_to_emacs (emacs_socket, "-display ");
+ quote_argument (emacs_socket, display);
+ send_to_emacs (emacs_socket, " ");
}
+ if (tty)
+ {
+ char *type = getenv ("TERM");
+ char *tty_name = NULL;
+#ifndef WINDOWSNT
+ tty_name = ttyname (fileno (stdin));
+#endif
+
+ if (! tty_name)
+ {
+ message (TRUE, "%s: could not get terminal name\n", progname);
+ fail ();
+ }
+
+ if (! type)
+ {
+ message (TRUE, "%s: please set the TERM variable to your terminal type\n",
+ progname);
+ fail ();
+ }
+
+ if (! strcmp (type, "eterm"))
+ {
+ /* This causes nasty, MULTI_KBOARD-related input lockouts. */
+ message (TRUE, "%s: opening a frame in an Emacs term buffer"
+ " is not supported\n", progname);
+ fail ();
+ }
+#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
+ init_signals ();
+#endif
+
+ send_to_emacs (emacs_socket, "-tty ");
+ quote_argument (emacs_socket, tty_name);
+ send_to_emacs (emacs_socket, " ");
+ quote_argument (emacs_socket, type);
+ send_to_emacs (emacs_socket, " ");
+ }
+
+ if (window_system)
+ send_to_emacs (emacs_socket, "-window-system ");
+
if ((argc - optind > 0))
{
for (i = optind; i < argc; i++)
{
+ int relative = 0;
+
if (eval)
- ; /* Don't prepend any cwd or anything like that. */
- else if (*argv[i] == '+')
- {
+ {
+ /* Don't prepend cwd or anything like that. */
+ send_to_emacs (emacs_socket, "-eval ");
+ quote_argument (emacs_socket, argv[i]);
+ send_to_emacs (emacs_socket, " ");
+ continue;
+ }
+
+ if (*argv[i] == '+')
+ {
char *p = argv[i] + 1;
while (isdigit ((unsigned char) *p) || *p == ':') p++;
- if (*p != 0)
- {
- SEND_QUOTED (cwd);
- SEND_STRING ("/");
- }
- }
+ if (*p == 0)
+ {
+ send_to_emacs (emacs_socket, "-position ");
+ quote_argument (emacs_socket, argv[i]);
+ send_to_emacs (emacs_socket, " ");
+ continue;
+ }
+ else
+ relative = 1;
+ }
else if (! file_name_absolute_p (argv[i]))
- {
- SEND_QUOTED (cwd);
- SEND_STRING ("/");
- }
-
- SEND_QUOTED (argv[i]);
- SEND_STRING (" ");
- }
+ relative = 1;
+
+ send_to_emacs (emacs_socket, "-file ");
+ if (relative)
+ {
+ quote_argument (emacs_socket, cwd);
+ send_to_emacs (emacs_socket, "/");
+ }
+ quote_argument (emacs_socket, argv[i]);
+ send_to_emacs (emacs_socket, " ");
+ }
}
else
{
- while (fgets (string, BUFSIZ, stdin))
- {
- SEND_QUOTED (string);
- }
- SEND_STRING (" ");
+ if (!tty && !window_system)
+ {
+ while ((str = fgets (string, BUFSIZ, stdin)))
+ {
+ if (eval)
+ send_to_emacs (emacs_socket, "-eval ");
+ else
+ send_to_emacs (emacs_socket, "-file ");
+ quote_argument (emacs_socket, str);
+ }
+ send_to_emacs (emacs_socket, " ");
+ }
}
- SEND_STRING ("\n");
+ send_to_emacs (emacs_socket, "\n");
+
+ /* Wait for an answer. */
+ if (!eval && !tty && !nowait)
+ {
+ printf ("Waiting for Emacs...");
+ needlf = 2;
+ }
+ fflush (stdout);
+ fsync (1);
- /* Maybe wait for an answer. */
- if (!nowait)
+ /* Now, wait for an answer and print any messages. */
+ while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
{
- if (!eval)
+ char *p;
+ string[rl] = '\0';
+
+ p = string + strlen (string) - 1;
+ while (p > string && *p == '\n')
+ *p-- = 0;
+
+ if (strprefix ("-emacs-pid ", string))
{
- printf ("Waiting for Emacs...");
- needlf = 2;
+ /* -emacs-pid PID: The process id of the Emacs process. */
+ emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
}
- fflush (stdout);
-
- /* Now, wait for an answer and print any messages. */
- while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
+ else if (strprefix ("-window-system-unsupported ", string))
{
- string[rl] = '\0';
- if (needlf == 2)
+ /* -window-system-unsupported: Emacs was compiled without X
+ support. Try again on the terminal. */
+ window_system = 0;
+ nowait = 0;
+ tty = 1;
+ goto retry;
+ }
+ else if (strprefix ("-print ", string))
+ {
+ /* -print STRING: Print STRING on the terminal. */
+ str = unquote_argument (string + strlen ("-print "));
+ if (needlf)
printf ("\n");
- printf ("%s", string);
- needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
+ printf ("%s", str);
+ needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
+ }
+ else if (strprefix ("-error ", string))
+ {
+ /* -error DESCRIPTION: Signal an error on the terminal. */
+ str = unquote_argument (string + strlen ("-error "));
+ if (needlf)
+ printf ("\n");
+ fprintf (stderr, "*ERROR*: %s", str);
+ needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
+ }
+#ifdef SIGSTOP
+ else if (strprefix ("-suspend ", string))
+ {
+ /* -suspend: Suspend this terminal, i.e., stop the process. */
+ if (needlf)
+ printf ("\n");
+ needlf = 0;
+ kill (0, SIGSTOP);
+ }
+#endif
+ else
+ {
+ /* Unknown command. */
+ if (needlf)
+ printf ("\n");
+ printf ("*ERROR*: Unknown message: %s", string);
+ needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
}
-
- if (needlf)
- printf ("\n");
- fflush (stdout);
}
- CLOSE_SOCKET (s);
+ if (needlf)
+ printf ("\n");
+ fflush (stdout);
+ fsync (1);
+
+ CLOSE_SOCKET (emacs_socket);
return EXIT_SUCCESS;
}
#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
+
#ifndef HAVE_STRERROR
char *
strerror (errnum)
diff --git a/lib-src/emacstool.c b/lib-src/emacstool.c
deleted file mode 100644
index 7b39d2ed8fd..00000000000
--- a/lib-src/emacstool.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- Copyright (C) 1986, 1988, 1990, 1991, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
-
-/*
- * For Emacs in SunView/Sun-Windows: (supported by Sun Unix v3.2 or greater)
- * Insert a notifier filter-function to convert all useful input
- * to "key" sequences that emacs can understand. See: Emacstool(1).
- *
- * Author: Jeff Peck, Sun Microsystems, Inc. <peck@eng.sun.com>
- *
- * Original Idea: Ian Batten
- * Updated 15-Mar-88, Jeff Peck: set IN_EMACSTOOL, TERM, TERMCAP
- * Updated 10-Sep-88, Jeff Peck: add XVIEW and JLE support
- * Updated 8-Oct-90, Jeff Peck: add Meta-bit for Xview
- * Updated 6-Mar-91, Jeff Peck: Hack to detect -Wt invocation
- * [note, TTYSW limitation means you must Click-To-Type in Openwin]
- * [fixed in OW3 or use local/tty.o]
- * for better results, this should move to using TERMSW.
- * Updated 10-Mar-91, Jeff Peck, et al: support for TERMSW (TTERM)
- * allows point-to-type even in OW2
- *
- * [note: xvetool should be started with the "-nw" flag for emacs!]
- */
-
-#ifdef XVIEW
-#include <xview/xview.h>
-#include <xview/panel.h>
-#include <xview/attr.h>
-#include <xview/tty.h>
-#include <xview/ttysw.h> /* private defines */
-#include <xview/termsw.h> /* -DTTERM */
-#include <xview/font.h> /* for testing */
-#else
-#include <suntool/sunview.h>
-#include <suntool/tty.h>
-#include <suntool/ttysw.h>
-#endif XVIEW
-
-#ifdef JLE
-# include <locale.h>
-#endif JLE
-
-#include <stdio.h>
-#include <sys/file.h>
-
-#define BUFFER_SIZE 128 /* Size of all the buffers */
-
-/* define WANT_CAPS_LOCK to make f-key T1 (aka F1) behave as CapsLock */
-#define WANT_CAPS_LOCK
-#ifdef WANT_CAPS_LOCK
-int caps_lock; /* toggle indicator for f-key T1 caps lock */
-static char *Caps = "[CAPS] "; /* Caps Lock prefix string */
-#define CAPS_LEN 7 /* strlen (Caps) */
-#endif
-
-static char *mouse_prefix = "\030\000"; /* C-x C-@ */
-static int m_prefix_length = 2; /* mouse_prefix length */
-
-static char *key_prefix = "\030*"; /* C-x * */
-static int k_prefix_length = 2; /* key_prefix length */
-
-#ifdef JLE
-static char *emacs_name = "nemacs"; /* default run command */
-static char *title = "NEmacstool - "; /* initial title */
-#else
-static char *emacs_name = "emacs"; /* default run command */
-static char *title = "Emacstool - "; /* initial title */
-#endif JLE
-
-static char buffer[BUFFER_SIZE]; /* send to ttysw_input */
-static char *bold_name = 0; /* for -bold option */
-
-Frame frame; /* Base frame for system */
-
-#ifndef TTERM
-#define SWTYPE TTY
-Tty tty_win; /* Where emacs is reading */
-#else
-#define SWTYPE TERMSW
-Termsw tty_win; /* Termsw does follow-mouse */
-#endif TTERM
-
-#ifdef XVIEW
-Xv_Window tty_view; /* Where the events are in Xview*/
-#else
-Tty tty_view; /* SunView place filler */
-#endif XVIEW
-
-int font_width, font_height; /* For translating pixels to chars */
-int left_margin = 0; /* default window -- frame offset */
-
-int console_fd = 0; /* for debugging: setenv DEBUGEMACSTOOL */
-FILE *console; /* for debugging: setenv DEBUGEMACSTOOL */
-
-Icon frame_icon;
-/* make an icon_image for the default frame_icon */
-static short default_image[258] =
-{
-#include <images/terminal.icon>
-};
-mpr_static(icon_image, 64, 64, 1, default_image);
-
-/*
- * Assign a value to a set of keys
- */
-int
-button_value (event)
- Event *event;
-{
- int retval = 0;
- /*
- * Code up the current situation:
- *
- * 1 = MS_LEFT;
- * 2 = MS_MIDDLE;
- * 4 = MS_RIGHT;
- * 8 = SHIFT;
- * 16 = CONTROL;
- * 32 = META;
- * 64 = DOUBLE;
- * 128 = UP;
- */
-
- if (MS_LEFT == (event_id (event))) retval = 1;
- if (MS_MIDDLE == (event_id (event))) retval = 2;
- if (MS_RIGHT == (event_id (event))) retval = 4;
-
- if (event_shift_is_down (event)) retval += 8;
- if (event_ctrl_is_down (event)) retval += 16;
- if (event_meta_is_down (event)) retval += 32;
- if (event_is_up (event)) retval += 128;
- return retval;
-}
-
-/*
- * Variables to store the time of the previous mouse event that was
- * sent to emacs.
- *
- * The theory is that to time double clicks while ignoring UP buttons,
- * we must keep track of the accumulated time.
- *
- * If someone writes a SUN-SET-INPUT-MASK for emacstool,
- * That could be used to selectively disable UP events,
- * and then this cruft wouldn't be necessary.
- */
-static long prev_event_sec = 0;
-static long prev_event_usec = 0;
-
-/*
- * Give the time difference in milliseconds, where one second
- * is considered infinite.
- */
-int
-time_delta (now_sec, now_usec, prev_sec, prev_usec)
- long now_sec, now_usec, prev_sec, prev_usec;
-{
- long sec_delta = now_sec - prev_sec;
- long usec_delta = now_usec - prev_usec;
-
- if (usec_delta < 0) { /* "borrow" a second */
- usec_delta += 1000000;
- --sec_delta;
- }
-
- if (sec_delta >= 10)
- return (9999); /* Infinity */
- else
- return ((sec_delta * 1000) + (usec_delta / 1000));
-}
-
-
-/*
- * Filter function to translate selected input events for emacs
- * Mouse button events become ^X^@(button x-col y-line time-delta) .
- * Function keys: ESC-*{c}{lrt} l,r,t for Left, Right, Top;
- * {c} encodes the keynumber as a character [a-o]
- */
-static Notify_value
-input_event_filter_function (window, event, arg, type)
-#ifdef XVIEW
- Xv_Window window;
-#else
- Window window;
-#endif XVIEW
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
-{
- struct timeval time_stamp;
-
- if (console_fd) fprintf(console, "Event: %d\n", event_id(event));
-
- /* UP L1 is the STOP key */
- if (event_id(event) == WIN_STOP) {
- ttysw_input(tty_win, "\007\007\007\007\007\007\007", 7);
- return NOTIFY_IGNORED;
- }
-
- /* UP L5 & L7 is Expose & Open, let them pass to sunview */
- if (event_id(event) == KEY_LEFT(5) || event_id(event) == KEY_LEFT(7))
- if(event_is_up (event))
- return notify_next_event_func (window, event, arg, type);
- else return NOTIFY_IGNORED;
-
- if (event_is_button (event)) { /* do Mouse Button events */
-/* Commented out so that we send mouse up events too.
- if (event_is_up (event))
- return notify_next_event_func (window, event, arg, type);
-*/
- time_stamp = event_time (event);
- ttysw_input (tty_win, mouse_prefix, m_prefix_length);
- sprintf (buffer, "(%d %d %d %d)\015",
- button_value (event),
- (event_x (event) - left_margin) / font_width,
- event_y (event) / font_height,
- time_delta (time_stamp.tv_sec, time_stamp.tv_usec,
- prev_event_sec, prev_event_usec)
- );
- ttysw_input (tty_win, buffer, strlen(buffer));
- prev_event_sec = time_stamp.tv_sec;
- prev_event_usec = time_stamp.tv_usec;
- return NOTIFY_IGNORED;
- }
-
- { /* Do the function key events */
- int d;
- char c = (char) 0;
- if ((event_is_key_left (event)) ?
- ((d = event_id(event) - KEY_LEFT(1) + 'a'), c='l') :
- ((event_is_key_right (event)) ?
- ((d = event_id(event) - KEY_RIGHT(1) + 'a'), c='r') :
- ((event_is_key_top (event)) ?
- ((d = event_id(event) - KEY_TOP(1) + 'a'), c='t') : 0)))
- {
- if (event_is_up(event)) return NOTIFY_IGNORED;
- if (event_shift_is_down (event)) c = c - 32;
- /* this will give a non-{lrt} for unshifted keys */
- if (event_ctrl_is_down (event)) c = c - 64;
- if (event_meta_is_down (event)) c = c + 128;
-#ifdef WANT_CAPS_LOCK
-/* set a toggle and relabel window so T1 can act like caps-lock */
- if (event_id(event) == KEY_TOP(1))
- {
- /* make a frame label with and without CAPS */
- strcpy (buffer, Caps);
- title = &buffer[CAPS_LEN];
- strncpy (title, (char *)window_get (frame, FRAME_LABEL),
- BUFFER_SIZE - CAPS_LEN);
- buffer[BUFFER_SIZE] = (char) 0;
- if (strncmp (title, Caps, CAPS_LEN) == 0)
- title += CAPS_LEN; /* already Caps */
- caps_lock = (caps_lock ? 0 : CAPS_LEN);
- window_set(frame, FRAME_LABEL, (title -= caps_lock), 0);
- return NOTIFY_IGNORED;
- }
-#endif
- ttysw_input (tty_win, key_prefix, k_prefix_length);
- sprintf (buffer, "%c%c", d, c);
- ttysw_input(tty_win, buffer, strlen(buffer));
-
- return NOTIFY_IGNORED;
- }
- }
- if ((event_is_ascii(event) || event_is_meta(event))
- && event_is_up(event)) return NOTIFY_IGNORED;
-#ifdef WANT_CAPS_LOCK
-/* shift alpha chars to upper case if toggle is set */
- if ((caps_lock) && event_is_ascii(event)
- && (event_id(event) >= 'a') && (event_id(event) <= 'z'))
- event_set_id(event, (event_id(event) - 32));
-/* crufty, but it works for now. is there an UPCASE(event)? */
-#endif
-#ifndef NO_META_BIT
-/* under Openwindows/X, the meta bit is not set in the key event,
- * emacs expects this so we add it in here:
- */
- if (event_is_ascii(event) && event_meta_is_down(event))
- event_set_id(event, 128 | event_id(event));
-#endif
- return notify_next_event_func (window, event, arg, type);
-}
-
-main (argc, argv)
- int argc;
- char **argv;
-{
- int error_code; /* Error codes */
-
-#ifdef JLE
- setlocale(LC_ALL, "");
-#endif JLE
-
- if(getenv("DEBUGEMACSTOOL"))
- console = fdopen (console_fd = open("/dev/console",O_WRONLY), "w");
-
- putenv("IN_EMACSTOOL=t"); /* notify subprocess that it is in emacstool */
-
- if (putenv("TERM=sun") != 0) /* TTY_WIN will be a TERM=sun window */
- {fprintf (stderr, "%s: Could not set TERM=sun, using `%s'\n",
- argv[0], (char *)getenv("TERM")) ;};
- /*
- * If TERMCAP starts with a slash, it is the pathname of the
- * termcap file, not an entry extracted from it, so KEEP it!
- * Otherwise, it may not relate to the new TERM, so Nuke-It.
- * If there is no TERMCAP environment variable, don't make one.
- */
- {
- char *termcap ; /* Current TERMCAP value */
- termcap = (char *)getenv("TERMCAP") ;
- if (termcap && (*termcap != '/'))
- {
- if (putenv("TERMCAP=") != 0)
- {fprintf (stderr, "%s: Could not clear TERMCAP\n", argv[0]) ;} ;
- } ;
- } ;
-
- /* find command to run as subprocess in window */
- if (!(argv[0] = (char *)getenv("EMACSTOOL"))) /* Set emacs command name */
- argv[0] = emacs_name;
- /* Emacstool recognizes two special args: -rc <file> and -bold <bold-name> */
- for (argc = 1; argv[argc]; argc++) /* Use last one on line */
- {
- if(!(strcmp ("-rc", argv[argc]))) /* Override if -rc given */
- {int i = argc;
- argv[argc--]=0; /* kill the -rc argument */
- if (argv[i+1]) { /* move to argv[0] and squeeze the rest */
- argv[0]=argv[i+1];
- for (; argv[i+2]; (argv[i]=argv[i+2],argv[++i]=0));
- }
- }
-
- if (!(strcmp ("-bold", argv[argc])))
- {int i = argc;
- argv[argc--]=0; /* kill the -bold argument */
- if (argv[i+1]) { /* move to bold_name and squeeze the rest */
- bold_name = argv[i+1];
- for (; argv[i+2]; (argv[i]=argv[i+2],argv[++i]=0));
- }
- }
- };
-
- strcpy (buffer, title);
- strncat (buffer, argv[0], /* append run command name */
- (BUFFER_SIZE - (strlen (buffer)) - (strlen (argv[0]))) - 1);
-
- error_code = interpose_on_window(argc,argv);
- if (error_code != 0) { /* Barf */
- fprintf (stderr, "notify_interpose_event_func returns %d.\n", error_code);
- exit (1);
- }
-
-#ifdef XVIEW
- xv_main_loop (frame); /* And away we go */
-#else
- window_main_loop (frame);
-#endif XVIEW
-}
-
-#ifdef XVIEW
-int interpose_on_window(argc,argv)
- int argc;
- char **argv;
-{
-#ifndef TTERM
- int i, font_width_adjust = 1; /* hackery, and heuristics */
- /* if -Wt is not supplied, then font comes out as lucida-14 (width=8)
- * rather than the screen.r.12 (width=7) typically used
- * this hack attempts to workaround it.
- * could use a env var EMACSTOOL_DEFAULT_FONT_WIDTH instead */
- for (i = 1; argv[i]; i++) {
- if (!(strcmp ("-Wt", argv[i])))
- {font_width_adjust = 0;
- if (console_fd) fprintf(console, "-Wt = %d\n", font_width_adjust);
- break;}
- }
-#endif TTERM
- /* initialize Xview, and strip window args */
- xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0);
-
- /* do this first, so arglist can override it */
- frame_icon = icon_create (ICON_LABEL, "Emacstool",
- ICON_IMAGE, &icon_image,
- 0);
-
- /* Build a frame to run in */
- frame = xv_create ((Xv_Window)NULL, FRAME,
- FRAME_LABEL, buffer,
- FRAME_ICON, frame_icon,
- 0);
-
- /* Create a tty with emacs in it */
- tty_win = xv_create (frame, SWTYPE, WIN_IS_CLIENT_PANE,
- TTY_QUIT_ON_CHILD_DEATH, TRUE,
- TTY_BOLDSTYLE, TTYSW_BOLD_INVERT,
- TTY_ARGV, argv,
- 0);
-
- if (bold_name) {
- (void)xv_set(tty_win, TTY_BOLDSTYLE_NAME, bold_name, 0);
- }
-
- {
- Xv_font font; /* declare temp font variable */
- font = (Xv_font)xv_get (tty_win, XV_FONT);
- font_height = (int)xv_get (font, FONT_DEFAULT_CHAR_HEIGHT);
- font_width = (int)xv_get (font, FONT_DEFAULT_CHAR_WIDTH);
- }
- if (console_fd) fprintf(console, "Width = %d\n", font_width);
-
-#ifndef TTERM
- font_width -= font_width_adjust; /* A guess! font bug in ttysw*/
-#else
- /* make the termsw act as a tty */
- xv_set(tty_win, TERMSW_MODE, TTYSW_MODE_TYPE, 0);
- /* termsw has variable offset depending on scrollbar size/location */
- left_margin = (int)xv_get (tty_win, TEXTSW_LEFT_MARGIN);
-#endif TTERM
-
- tty_view = (Xv_Window) xv_get (tty_win, OPENWIN_NTH_VIEW, 0);
- xv_set(tty_view,
- WIN_CONSUME_EVENTS,
- WIN_MOUSE_BUTTONS, WIN_UP_EVENTS,
- ACTION_ADJUST, ACTION_MENU,
- WIN_ASCII_EVENTS,
- WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
- 0,
- 0);
- /* Interpose my event function */
- return (int) notify_interpose_event_func
- (tty_view, input_event_filter_function, NOTIFY_SAFE);
-}
-#else
-int interpose_on_window (argc, argv)
- int argc;
- char **argv;
-{
- /* do this first, so arglist can override it */
- frame_icon = icon_create (ICON_LABEL, "Emacstool",
- ICON_IMAGE, &icon_image,
- 0);
-
- /* Build a frame to run in */
- frame = window_create ((Window)NULL, FRAME,
- FRAME_LABEL, buffer,
- FRAME_ICON, frame_icon,
- FRAME_ARGC_PTR_ARGV, &argc, argv,
- 0);
-
- /* Create a tty with emacs in it */
- tty_win = window_create (frame, TTY,
- TTY_QUIT_ON_CHILD_DEATH, TRUE,
- TTY_BOLDSTYLE, TTYSW_BOLD_INVERT,
- TTY_ARGV, argv,
- 0);
-
- if (bold_name) {
- (void)window_set(tty_win, TTY_BOLDSTYLE_NAME, bold_name, 0);
- }
-
- /* ttysw uses pf_default, one must set WIN_FONT explicitly */
- window_set (tty_win, WIN_FONT, pf_default(), 0);
- font_height = (int)window_get (tty_win, WIN_ROW_HEIGHT);
- font_width = (int)window_get (tty_win, WIN_COLUMN_WIDTH);
-
- tty_view = tty_win;
- window_set(tty_view,
- WIN_CONSUME_PICK_EVENTS,
- WIN_STOP,
- WIN_MOUSE_BUTTONS, WIN_UP_EVENTS,
- /* LOC_WINENTER, LOC_WINEXIT, LOC_MOVE, */
- 0,
- WIN_CONSUME_KBD_EVENTS,
- WIN_STOP,
- WIN_ASCII_EVENTS,
- WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
- /* WIN_UP_ASCII_EVENTS, */
- 0,
- 0);
- /* Interpose my event function */
- return (int) notify_interpose_event_func
- (tty_view, input_event_filter_function, NOTIFY_SAFE);
-}
-#endif XVIEW
-
-/* arch-tag: 7a2e7105-c059-418a-b3d9-5b5de96abb4e
- (do not change this comment) */
diff --git a/lib-src/makefile.w32-in b/lib-src/makefile.w32-in
index 03ef92f023d..65ad9b08011 100644
--- a/lib-src/makefile.w32-in
+++ b/lib-src/makefile.w32-in
@@ -24,7 +24,7 @@ ALL = make-docfile hexl ctags etags movemail ebrowse sorted-doc digest-doc emacs
.PHONY: $(ALL)
-VERSION = 22.1.50
+VERSION = 23.0.50
LOCAL_FLAGS = -DWINDOWSNT -DDOS_NT -DSTDC_HEADERS=1 -DNO_LDAV=1 \
-DNO_ARCHIVES=1 -DHAVE_CONFIG_H=1 -I../nt/inc \
@@ -82,11 +82,11 @@ $(TRES): ../nt/emacs.rc
$(BLD)/emacsclient.exe: $(ECLIENTOBJS)
# put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib
- $(LINK) $(LINK_OUT)$@ $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(LIBS)
+ $(LINK) $(LINK_OUT)$@ $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(COMCTL32) $(LIBS)
$(BLD)/emacsclientw.exe: $(ECLIENTOBJS) $(TRES)
# put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib
- $(LINK) $(LINK_OUT)$@ $(TRES) -mwindows $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(LIBS)
+ $(LINK) $(LINK_OUT)$@ $(TRES) -mwindows $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(USER32) $(COMCTL32) $(LIBS)
# emacsclient.$(O) depends on makefile.w32-in because makefile.w32-in
# can be edited to define VERSION string, which is part of ECLIENT_CFLAGS.