comparison src/event-tty.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 3d6bfa290dbd
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
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.
5
6 This file is part of XEmacs.
7
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
11 later version.
12
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
16 for more details.
17
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. */
22
23 /* Synched up with: Not in FSF. */
24
25 #include <config.h>
26 #include "lisp.h"
27
28 #include "blocktype.h"
29 #include "device.h"
30 #include "console-tty.h"
31 #include "events.h"
32 #include "frame.h"
33 #include "process.h"
34
35 #include "sysproc.h"
36 #include "syswait.h"
37 #include "systime.h"
38
39 /* Mask of bits indicating the descriptors that we wait for input on */
40 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
41 extern SELECT_TYPE process_only_mask, tty_only_mask;
42
43 extern Lisp_Object Qdelete_device;
44
45 static struct event_stream *tty_event_stream;
46
47
48 /************************************************************************/
49 /* timeout events */
50 /************************************************************************/
51
52 /* The pending timers are stored in an ordered list, where the first timer
53 on the list is the first one to fire. Times recorded here are
54 absolute. */
55 static struct low_level_timeout *tty_timer_queue;
56
57 static int
58 emacs_tty_add_timeout (EMACS_TIME thyme)
59 {
60 return add_low_level_timeout (&tty_timer_queue, thyme);
61 }
62
63 static void
64 emacs_tty_remove_timeout (int id)
65 {
66 remove_low_level_timeout (&tty_timer_queue, id);
67 }
68
69 static void
70 tty_timeout_to_emacs_event (struct Lisp_Event *emacs_event)
71 {
72 emacs_event->event_type = timeout_event;
73 /* timeout events have nil as channel */
74 emacs_event->timestamp = 0; /* #### */
75 emacs_event->event.timeout.interval_id =
76 pop_low_level_timeout (&tty_timer_queue, 0);
77 }
78
79
80
81 static int
82 emacs_tty_event_pending_p (int user_p)
83 {
84 if (!user_p)
85 {
86 EMACS_TIME sometime;
87 /* see if there's a pending timeout. */
88 EMACS_GET_TIME (sometime);
89 if (tty_timer_queue &&
90 EMACS_TIME_EQUAL_OR_GREATER (sometime, tty_timer_queue->time))
91 return 1;
92 }
93
94 return poll_fds_for_input (user_p ? tty_only_mask :
95 non_fake_input_wait_mask);
96 }
97
98 static struct console *
99 find_console_from_fd (int fd)
100 {
101 Lisp_Object concons;
102
103 CONSOLE_LOOP (concons)
104 {
105 struct console *c;
106
107 c = XCONSOLE (XCAR (concons));
108 if (CONSOLE_TTY_P (c) && CONSOLE_TTY_DATA (c)->infd == fd)
109 return c;
110 }
111
112 return 0;
113 }
114
115 static void
116 emacs_tty_next_event (struct Lisp_Event *emacs_event)
117 {
118 while (1)
119 {
120 int ndesc;
121 int i;
122 SELECT_TYPE temp_mask = input_wait_mask;
123 EMACS_TIME time_to_block;
124 EMACS_SELECT_TIME select_time_to_block, *pointer_to_this;
125
126 if (!get_low_level_timeout_interval (tty_timer_queue, &time_to_block))
127 /* no timer events; block indefinitely */
128 pointer_to_this = 0;
129 else
130 {
131 EMACS_TIME_TO_SELECT_TIME (time_to_block, select_time_to_block);
132 pointer_to_this = &select_time_to_block;
133 }
134
135 ndesc = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
136 if (ndesc > 0)
137 {
138 /* Look for a TTY event */
139 for (i = 0; i < MAXDESC; i++)
140 {
141 /* To avoid race conditions (among other things, an infinite
142 loop when called from Fdiscard_input()), we must return
143 user events ahead of process events. */
144 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask))
145 {
146 struct console *c = find_console_from_fd (i);
147
148 assert (c);
149 if (read_event_from_tty_or_stream_desc (emacs_event, c, i))
150 return;
151 }
152 }
153
154 /* Look for a process event */
155 for (i = 0; i < MAXDESC; i++)
156 {
157 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &process_only_mask))
158 {
159 Lisp_Object process;
160 struct Lisp_Process *p =
161 get_process_from_input_descriptor (i);
162
163 assert (p);
164 XSETPROCESS (process, p);
165 emacs_event->event_type = process_event;
166 /* process events have nil as channel */
167 emacs_event->timestamp = 0; /* #### */
168 emacs_event->event.process.process = process;
169 return;
170 }
171 }
172
173 /* We might get here when a fake event came through a signal. */
174 /* Return a dummy event, so that a cycle of the command loop will
175 occur. */
176 drain_signal_event_pipe ();
177 emacs_event->event_type = eval_event;
178 /* eval events have nil as channel */
179 emacs_event->event.eval.function = Qidentity;
180 emacs_event->event.eval.object = Qnil;
181 return;
182 }
183 else if (ndesc == 0) /* timeout fired */
184 {
185 tty_timeout_to_emacs_event (emacs_event);
186 return;
187 }
188 }
189 }
190
191 static void
192 emacs_tty_handle_magic_event (struct Lisp_Event *emacs_event)
193 {
194 /* Nothing to do currently */
195 }
196
197
198 static void
199 emacs_tty_select_process (struct Lisp_Process *process)
200 {
201 event_stream_unixoid_select_process (process);
202 }
203
204 static void
205 emacs_tty_unselect_process (struct Lisp_Process *process)
206 {
207 event_stream_unixoid_unselect_process (process);
208 }
209
210 static void
211 emacs_tty_select_console (struct console *con)
212 {
213 event_stream_unixoid_select_console (con);
214 }
215
216 static void
217 emacs_tty_unselect_console (struct console *con)
218 {
219 event_stream_unixoid_unselect_console (con);
220 }
221
222 static void
223 emacs_tty_quit_p (void)
224 {
225 /* Nothing to do currently because QUIT is handled through SIGINT.
226 This could change. */
227 }
228
229
230 /************************************************************************/
231 /* initialization */
232 /************************************************************************/
233
234 void
235 vars_of_event_tty (void)
236 {
237 tty_event_stream =
238 (struct event_stream *) xmalloc (sizeof (struct event_stream));
239
240 tty_event_stream->event_pending_p = emacs_tty_event_pending_p;
241 tty_event_stream->next_event_cb = emacs_tty_next_event;
242 tty_event_stream->handle_magic_event_cb = emacs_tty_handle_magic_event;
243 tty_event_stream->add_timeout_cb = emacs_tty_add_timeout;
244 tty_event_stream->remove_timeout_cb = emacs_tty_remove_timeout;
245 tty_event_stream->select_console_cb = emacs_tty_select_console;
246 tty_event_stream->unselect_console_cb = emacs_tty_unselect_console;
247 tty_event_stream->select_process_cb = emacs_tty_select_process;
248 tty_event_stream->unselect_process_cb = emacs_tty_unselect_process;
249 tty_event_stream->quit_p_cb = emacs_tty_quit_p;
250 }
251
252 void
253 init_event_tty_late (void)
254 {
255 event_stream = tty_event_stream;
256 }