1 /* The event_stream interface for tty's.
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1995 Ben Wing.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: Not in FSF. */
29 #include "console-tty.h"
38 /* Mask of bits indicating the descriptors that we wait for input on */
39 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
40 extern SELECT_TYPE process_only_mask, tty_only_mask;
42 static struct event_stream *tty_event_stream;
45 /************************************************************************/
47 /************************************************************************/
49 /* The pending timers are stored in an ordered list, where the first timer
50 on the list is the first one to fire. Times recorded here are
52 static struct low_level_timeout *tty_timer_queue;
55 emacs_tty_add_timeout (EMACS_TIME thyme)
57 return add_low_level_timeout (&tty_timer_queue, thyme);
61 emacs_tty_remove_timeout (int id)
63 remove_low_level_timeout (&tty_timer_queue, id);
67 tty_timeout_to_emacs_event (struct Lisp_Event *emacs_event)
69 emacs_event->event_type = timeout_event;
70 /* timeout events have nil as channel */
71 emacs_event->timestamp = 0; /* #### */
72 emacs_event->event.timeout.interval_id =
73 pop_low_level_timeout (&tty_timer_queue, 0);
79 emacs_tty_event_pending_p (int user_p)
84 /* see if there's a pending timeout. */
85 EMACS_GET_TIME (sometime);
86 if (tty_timer_queue &&
87 EMACS_TIME_EQUAL_OR_GREATER (sometime, tty_timer_queue->time))
91 return poll_fds_for_input (user_p ? tty_only_mask :
92 non_fake_input_wait_mask);
95 static struct console *
96 find_console_from_fd (int fd)
100 CONSOLE_LOOP (concons)
104 c = XCONSOLE (XCAR (concons));
105 if (CONSOLE_TTY_P (c) && CONSOLE_TTY_DATA (c)->infd == fd)
113 emacs_tty_next_event (struct Lisp_Event *emacs_event)
119 SELECT_TYPE temp_mask = input_wait_mask;
120 EMACS_TIME time_to_block;
121 EMACS_SELECT_TIME select_time_to_block, *pointer_to_this;
123 if (!get_low_level_timeout_interval (tty_timer_queue, &time_to_block))
124 /* no timer events; block indefinitely */
128 EMACS_TIME_TO_SELECT_TIME (time_to_block, select_time_to_block);
129 pointer_to_this = &select_time_to_block;
132 ndesc = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
135 /* Look for a TTY event */
136 for (i = 0; i < MAXDESC; i++)
138 /* To avoid race conditions (among other things, an infinite
139 loop when called from Fdiscard_input()), we must return
140 user events ahead of process events. */
141 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask))
143 struct console *c = find_console_from_fd (i);
146 if (read_event_from_tty_or_stream_desc (emacs_event, c, i))
151 /* Look for a process event */
152 for (i = 0; i < MAXDESC; i++)
154 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &process_only_mask))
157 struct Lisp_Process *p =
158 get_process_from_usid (FD_TO_USID(i));
161 XSETPROCESS (process, p);
162 emacs_event->event_type = process_event;
163 /* process events have nil as channel */
164 emacs_event->timestamp = 0; /* #### */
165 emacs_event->event.process.process = process;
170 /* We might get here when a fake event came through a signal. */
171 /* Return a dummy event, so that a cycle of the command loop will
173 drain_signal_event_pipe ();
174 emacs_event->event_type = eval_event;
175 /* eval events have nil as channel */
176 emacs_event->event.eval.function = Qidentity;
177 emacs_event->event.eval.object = Qnil;
180 else if (ndesc == 0) /* timeout fired */
182 tty_timeout_to_emacs_event (emacs_event);
189 emacs_tty_handle_magic_event (struct Lisp_Event *emacs_event)
191 /* Nothing to do currently */
196 emacs_tty_select_process (struct Lisp_Process *process)
198 event_stream_unixoid_select_process (process);
202 emacs_tty_unselect_process (struct Lisp_Process *process)
204 event_stream_unixoid_unselect_process (process);
208 emacs_tty_select_console (struct console *con)
210 event_stream_unixoid_select_console (con);
214 emacs_tty_unselect_console (struct console *con)
216 event_stream_unixoid_unselect_console (con);
220 emacs_tty_quit_p (void)
222 /* Nothing to do currently because QUIT is handled through SIGINT.
223 This could change. */
227 emacs_tty_create_stream_pair (void* inhandle, void* outhandle,
228 Lisp_Object* instream, Lisp_Object* outstream, int flags)
230 return event_stream_unixoid_create_stream_pair
231 (inhandle, outhandle, instream, outstream, flags);
235 emacs_tty_delete_stream_pair (Lisp_Object instream, Lisp_Object outstream)
237 return event_stream_unixoid_delete_stream_pair (instream, outstream);
241 /************************************************************************/
243 /************************************************************************/
246 vars_of_event_tty (void)
248 tty_event_stream = xnew (struct event_stream);
250 tty_event_stream->event_pending_p = emacs_tty_event_pending_p;
251 tty_event_stream->next_event_cb = emacs_tty_next_event;
252 tty_event_stream->handle_magic_event_cb = emacs_tty_handle_magic_event;
253 tty_event_stream->add_timeout_cb = emacs_tty_add_timeout;
254 tty_event_stream->remove_timeout_cb = emacs_tty_remove_timeout;
255 tty_event_stream->select_console_cb = emacs_tty_select_console;
256 tty_event_stream->unselect_console_cb = emacs_tty_unselect_console;
257 tty_event_stream->select_process_cb = emacs_tty_select_process;
258 tty_event_stream->unselect_process_cb = emacs_tty_unselect_process;
259 tty_event_stream->quit_p_cb = emacs_tty_quit_p;
260 tty_event_stream->create_stream_pair_cb = emacs_tty_create_stream_pair;
261 tty_event_stream->delete_stream_pair_cb = emacs_tty_delete_stream_pair;
265 init_event_tty_late (void)
267 event_stream = tty_event_stream;