lisp/startup.el (command-line): Always call tty-register-default-colors.
src/dispextern.h (delete_tty): Added missing prototype.
src/keyboard.c (read_avail_input): Close display gracefully if needed.
Kill Emacs if the last display is to be closed.
(tty_read_avail_input): Don't call delete_tty and don't signal hangup here;
return -2 instead to indicate the non-transient failure to read_avail_input.
src/term.c (delete_tty): Removed superflous wiping of the deleted
frames' output_data field.
(delete_display): Check for and close live frames that are still on the display.
src/termhooks.h (read_socket_hook, delete_display_hook): Added detailed comment.
src/xfaces.c (realize_face): Create a dummy face for the initial frame.
(Reported by Robert J. Chassell (bob at rattlenake dot com).)
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-61
*** The new `initial-window-system' variable contains the
`window-system' value for the first frame.
+THANKS
+------
+
+The following is an (incomplete) list of people who have contributed
+to the project by testing, bug reports, and suggestions. Thanks!
+
+Robert J. Chassel <bob@rattlesnake.com>
+Romain Francoise <romain@orekobech.com>
+Ami Fischman <ami@fischman.org>
+
CHANGELOG
---------
THINGS TO DO
------------
-** emacs -nw --eval '(y-or-n-p "Foobar")' segfaults.
+** Robert J. Chassell reports:
-** Fix color handling during tty+X combo sessions. (It seems that tty
- sessions automatically convert the face colors to terminal colors
- when the face is loaded. This conversion must happen instead on
- the fly in write_glyphs, which might be problematic, as color
- approximation is currently done in lisp (term/tty-colors.el).)
- (Update: hm, colors seem to work fine if I start emacs with -nw and
- then create an X frame. Maybe it's just a small buglet somewhere.)
+ > * After starting the frame in the VC, I saw this message in the
+ > *Message* buffer
+ >
+ > error in process filter: server-process-filter: \
+ > Wrong type argument: sequencep,\
+ > framep
+ > error in process filter: Wrong type argument: sequencep, framep
+ >
+ > This also happens when I start a new frame in an xterm.
+
+** emacs -nw --eval '(y-or-n-p "Foobar")' segfaults.
** Fix interactive use of temacs. There are face-related SEGVs, most
likely because of changes in realize_default_face, realize_face.
(Done.)
+-- Fix color handling during tty+X combo sessions. (It seems that tty
+ sessions automatically convert the face colors to terminal colors
+ when the face is loaded. This conversion must happen instead on
+ the fly in write_glyphs, which might be problematic, as color
+ approximation is currently done in lisp (term/tty-colors.el).)
+ (Update: hm, colors seem to work fine if I start emacs with -nw and
+ then create an X frame. Maybe it's just a small buglet somewhere.)
+
+ (Seems to be fixed. The problem was in startup.el, it did not
+ initialize tty colors when the initial window system was
+ graphical.)
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
;; Register default TTY colors for the case the terminal hasn't a
;; terminal init file.
- (unless (memq initial-window-system '(x w32))
- ;; We do this regardles of whether the terminal supports colors
- ;; or not, since they can switch that support on or off in
- ;; mid-session by setting the tty-color-mode frame parameter.
- (tty-register-default-colors))
+ ;; We do this regardles of whether the terminal supports colors
+ ;; or not, since they can switch that support on or off in
+ ;; mid-session by setting the tty-color-mode frame parameter.
+ (tty-register-default-colors)
;; Record whether the tool-bar is present before the user and site
;; init files are processed. frame-notice-user-settings uses this
extern struct display *get_named_tty_display P_ ((char *));
extern struct display *init_initial_display P_ ((void));
extern struct display *term_init P_ ((char *, char *, int));
+extern void delete_tty P_ ((struct display *));
extern void fatal P_ ((/* char *, ... */));
extern void cursor_to P_ ((int, int));
extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
for (i = 0; i < KBD_BUFFER_SIZE; i++)
EVENT_INIT (buf[i]);
- for (d = display_list; d; d = d->next_display)
+ d = display_list;
+ while (d)
{
+ struct display *next = d->next_display;
+
if (d->read_socket_hook)
/* No need for FIONREAD or fcntl; just say don't wait. */
nread = (*d->read_socket_hook) (d, buf, KBD_BUFFER_SIZE, expected);
- if (nread > 0)
- break;
+ if (nread == -2)
+ {
+ /* The display device terminated; it should be closed. */
+
+ /* Kill Emacs if this was our last display. */
+ if (! display_list->next_display)
+ kill (getpid (), SIGHUP);
+
+ /* XXX Is calling delete_display safe here? It calls Fdelete_frame. */
+ if (d->delete_display_hook)
+ (*d->delete_display_hook) (d);
+ else
+ delete_display (d);
+ }
+ else if (nread > 0)
+ {
+ /* We've got input. */
+ break;
+ }
+
+ d = next;
}
/* Scan the chars for C-g and store them in kbd_buffer. */
Note that each terminal device has its own `struct display' object,
and so this function is called once for each individual termcap
display. The first parameter indicates which device to read from. */
+
int
tty_read_avail_input (struct display *display,
struct input_event *buf,
if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
{
if (! noninteractive)
- {
- delete_tty (tty); /* XXX I wonder if this is safe here. */
-
- /* Formerly simply reported no input, but that sometimes led to
- a failure of Emacs to terminate.
- SIGHUP seems appropriate if we can't reach the terminal. */
- /* ??? Is it really right to send the signal just to this process
- rather than to the whole process group?
- Perhaps on systems with FIONREAD Emacs is alone in its group. */
- /* It appears to be the case, see narrow_foreground_group. */
- if (! tty_list->next)
- kill (getpid (), SIGHUP); /* This was the last terminal. */
- }
+ return -2; /* Close this display. */
else
- {
- n_to_read = 0;
- }
+ n_to_read = 0;
}
if (n_to_read == 0)
return 0;
Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
if (nread == -1 && errno == EIO)
{
- if (! tty_list->next)
- kill (0, SIGHUP); /* This was the last terminal. */
- else
- delete_tty (tty); /* XXX I wonder if this is safe here. */
+ return -2; /* Close this display. */
}
#if defined (AIX) && (! defined (aix386) && defined (_BSD))
/* The kernel sometimes fails to deliver SIGHUP for ptys.
and that causes a value other than 0 when there is no input. */
if (nread == 0)
{
- if (! tty_list->next)
- kill (0, SIGHUP); /* This was the last terminal. */
- else
- delete_tty (tty); /* XXX I wonder if this is safe here. */
+ return -2; /* Close this display. */
}
#endif
}
if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty)
{
Fdelete_frame (frame, Qt);
- f->output_data.tty = 0;
}
}
delete_display (struct display *dev)
{
struct display **dp;
+ Lisp_Object tail, frame;
+
+ /* Check for and close live frames that are still on this
+ display. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && f->display == dev)
+ {
+ Fdelete_frame (frame, Qt);
+ }
+ }
+
for (dp = &display_list; *dp != dev; dp = &(*dp)->next_display)
if (! *dp)
abort ();
void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME));
\f
- /* Called to read input events. */
- int (*read_socket_hook) P_ ((struct display *, struct input_event *, int, int));
+ /* Called to read input events.
+
+ DISPLAY indicates which display to read from. Input events
+ should be read into BUF, the size of which is given in SIZE.
+ EXPECTED is non-zero if the caller suspects that new input is
+ available.
+
+ A positive return value indicates that that many input events
+ where read into BUF.
+ Zero means no events were immediately available.
+ A value of -1 means a transient read error, while -2 indicates
+ that the display was closed (hangup), and it should be deleted.
+
+ XXX Please note that a non-zero value of EXPECTED only means that
+ there is available input on at least one of the currently opened
+ display devices -- but not necessarily on this device.
+ Therefore, in most cases EXPECTED should be simply ignored.
+ */
+ int (*read_socket_hook) P_ ((struct display *display,
+ struct input_event *buf,
+ int size, int expected));
/* Called when a frame's display becomes entirely up to date. */
void (*frame_up_to_date_hook) P_ ((struct frame *));
on this display. */
void (*delete_frame_hook) P_ ((struct frame *));
- /* Called after the last frame on this display is deleted.
- If this is NULL, then the generic delete_frame() is called.
+ /* Called after the last frame on this display is deleted, or when
+ the display device was closed (hangup).
+
+ If this is NULL, then the generic delete_frame() is called
+ instead.
- Fdelete_frame ensures that there are no live frames on the
- display when it calls this hook. */
+ The hook must check for and close any live frames that are still
+ on the display. Fdelete_frame ensures that there are no live
+ frames on the display when it calls this hook, so infinite
+ recursion is prevented. */
void (*delete_display_hook) P_ ((struct display *));
};
if (FRAME_WINDOW_P (cache->f))
face = realize_x_face (cache, attrs, c, base_face);
- else if (FRAME_INITIAL_P (cache->f) || FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
+ else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
face = realize_tty_face (cache, attrs, c);
+ else if (FRAME_INITIAL_P (cache->f))
+ {
+ /* Create a dummy face. */
+ face = make_realized_face (attrs);
+ }
else
abort ();