Mercurial > hg > xemacs-beta
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 } |