1268
|
1 /* Shared event code between X and GTK -- include file.
|
|
2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
|
|
3 Copyright (C) 1995 Sun Microsystems, Inc.
|
|
4 Copyright (C) 1996, 2001, 2002, 2003 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 /* For some code it's reasonable to have only one copy and conditionalize
|
|
26 at run-time. For other code it isn't. #### Perhaps all code should be
|
|
27 included here, not in event-xlike.c. However, event-xlike.c is always
|
|
28 X-specific, whereas the following code isn't, in the GTK case. */
|
|
29
|
|
30 static int
|
|
31 #ifdef THIS_IS_GTK
|
|
32 emacs_gtk_event_pending_p (int how_many)
|
|
33 #else
|
|
34 emacs_Xt_event_pending_p (int how_many)
|
|
35 #endif
|
|
36 {
|
|
37 Lisp_Object event;
|
|
38 int tick_count_val;
|
|
39
|
|
40 /* If `how_many' is 0, then this function returns whether there are any
|
|
41 X, timeout, or fd events pending (that is, whether
|
|
42 emacs_Xt_next_event() would return immediately without blocking).
|
|
43
|
|
44 If `how_many' is > 0, then this function returns whether there are
|
|
45 that many *user generated* events available (keyboard, mouse click,
|
|
46 etc.). This also implies that emacs_Xt_next_event() would not block.
|
|
47 */
|
|
48
|
|
49 /* This function used to simply check whether there were any X events (or
|
|
50 if user_p was 1, it iterated over all the pending X events using
|
|
51 XCheckIfEvent(), looking for keystrokes and button events). That
|
|
52 worked in the old cheesoid event loop, which didn't go through
|
|
53 XtAppDispatchEvent(), but it doesn't work any more -- X events may not
|
|
54 result in anything. For example, a button press in a blank part of
|
|
55 the menubar appears as an X event but will not result in any Emacs
|
|
56 events (a button press that activates the menubar results in an Emacs
|
|
57 event through the stop_next_event mechanism).
|
|
58
|
|
59 The only accurate way of determining whether these X events translate
|
|
60 into Emacs events is to go ahead and dispatch them until there's
|
|
61 something on the dispatch queue. */
|
|
62
|
|
63 if (!how_many)
|
|
64 {
|
|
65 /* We're being asked for *ALL* events, not just user events. */
|
|
66
|
|
67 /* (1) Any pending events in the dispatch queue? */
|
|
68 if (!NILP (dispatch_event_queue))
|
|
69 return 1;
|
|
70
|
|
71 /* (2) Any TTY or process input available?
|
|
72
|
|
73 Note that formerly we just checked the value of XtAppPending() to
|
|
74 determine if there was file-desc input. This doesn't work any
|
|
75 more with the signal_event_pipe; XtAppPending() will says "yes" in
|
|
76 this case but there isn't really any input. So instead we keep
|
|
77 track of the file descriptors, and call select() ourselves.
|
|
78 Another way of fixing this problem is for the signal_event_pipe to
|
|
79 generate actual input in the form of an identity eval event or
|
|
80 something. (#### maybe this actually happens?) */
|
|
81
|
|
82 if (poll_fds_for_input (non_fake_input_wait_mask))
|
|
83 return 1;
|
|
84
|
|
85 #ifndef THIS_IS_GTK
|
|
86 /* (3) Any timeout input available? */
|
|
87 if (XtAppPending (Xt_app_con) & XtIMTimer)
|
|
88 return 1;
|
|
89 #else
|
|
90 /* #### Is there any way to do this in Gtk? I don't think there
|
|
91 is a 'peek' for events */
|
|
92 #endif
|
|
93 }
|
|
94 else
|
|
95 {
|
|
96 /* HOW_MANY > 0 */
|
|
97 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
|
|
98 {
|
|
99 if (command_event_p (event))
|
|
100 {
|
|
101 how_many--;
|
|
102 if (how_many <= 0)
|
|
103 return 1;
|
|
104 }
|
|
105 }
|
|
106 }
|
|
107
|
|
108 /* XtAppPending() can be super-slow, esp. over a network connection.
|
|
109 Quantify results have indicated that in some cases the call to
|
|
110 detect_input_pending() completely dominates the running time of
|
|
111 redisplay(). Fortunately, in a SIGIO world we can more quickly
|
|
112 determine whether there are any X events: if an event has happened
|
|
113 since the last time we checked, then a SIGIO will have happened. On a
|
|
114 machine with broken SIGIO, we'll still be in an OK state --
|
|
115 quit_check_signal_tick_count will get ticked at least every 1/4
|
|
116 second, so we'll be no more than that much behind reality. (In general
|
|
117 it's OK if we erroneously report no input pending when input is
|
|
118 actually pending() -- preemption is just a bit less efficient, that's
|
|
119 all. It's bad bad bad if you err the other way -- you've promised
|
|
120 that `next-event' won't block but it actually will, and some action
|
|
121 might get delayed until the next time you hit a key.)
|
|
122 */
|
|
123
|
|
124 if (!in_modal_loop)
|
|
125 {
|
|
126 /* quit_check_signal_tick_count is volatile so try to avoid race
|
|
127 conditions by using a temporary variable */
|
|
128 tick_count_val = quit_check_signal_tick_count;
|
|
129 if (last_quit_check_signal_tick_count != tick_count_val
|
|
130 #if !defined (THIS_IS_GTK) && (!defined (SIGIO) || defined (CYGWIN))
|
|
131 || (XtIMXEvent & XtAppPending (Xt_app_con))
|
|
132 #endif
|
|
133 )
|
|
134 {
|
|
135 last_quit_check_signal_tick_count = tick_count_val;
|
|
136
|
|
137 /* We need to drain the entire queue now -- if we only drain part of
|
|
138 it, we may later on end up with events actually pending but
|
|
139 detect_input_pending() returning false because there wasn't
|
|
140 another SIGIO. */
|
|
141 event_stream_drain_queue ();
|
|
142
|
|
143 if (!how_many)
|
|
144 return !NILP (dispatch_event_queue);
|
|
145
|
|
146 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
|
|
147 {
|
|
148 if (command_event_p (event))
|
|
149 {
|
|
150 how_many--;
|
|
151 if (how_many <= 0)
|
|
152 return 1;
|
|
153 }
|
|
154 }
|
|
155
|
|
156 return 0;
|
|
157 }
|
|
158 }
|
|
159
|
|
160 return 0;
|
|
161 }
|