CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/event_core.c
Go to the documentation of this file.
1/*
2 * Core event handling
3 *
4 * Copyright 1988 by Evans & Sutherland Computer Corporation,
5 * Salt Lake City, Utah
6 * Portions Copyright 1989 by the Massachusetts Institute of Technology
7 * Cambridge, Massachusetts
8 *
9 * Copyright 1992 Claude Lecommandeur.
10 */
11
12/***********************************************************************
13 *
14 * $XConsortium: events.c,v 1.182 91/07/17 13:59:14 dave Exp $
15 *
16 * twm event handling
17 *
18 * 17-Nov-87 Thomas E. LaStrange File created
19 *
20 * Do the necessary modification to be integrated in ctwm.
21 * Can no longer be used for the standard twm.
22 *
23 * 22-April-92 Claude Lecommandeur.
24 *
25 *
26 ***********************************************************************/
27
28#include "ctwm.h"
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <errno.h>
33#include <sys/time.h>
34
35#include <X11/extensions/shape.h>
36
37#include "animate.h"
38#ifdef CAPTIVE
39#include "captive.h"
40#endif
41#include "colormaps.h"
42#include "events.h"
43#include "event_handlers.h"
44#include "event_internal.h"
45#include "event_names.h"
46#include "functions.h"
47#include "iconmgr.h"
48#include "image.h"
49#include "screen.h"
50#include "signals.h"
51#include "util.h"
52#include "version.h"
53#include "win_utils.h"
54#ifdef SOUNDS
55#include "sound.h"
56#endif
57
58
60static bool StashEventTime(XEvent *ev);
61static void dumpevent(const XEvent *e);
62
63#define MAX_X_EVENT 256
64event_proc EventHandler[MAX_X_EVENT]; /* event handler jump table */
65int Context = C_NO_CONTEXT; /* current button press context */
66XEvent Event; /* the current event */
67
68Window DragWindow; /* variables used in moving windows */
73unsigned int DragWidth;
74unsigned int DragHeight;
75unsigned int DragBW;
78
79Time EventTime = CurrentTime; /* until Xlib does this for us */
80
81/* Maybe more staticizable later? */
85
86/*
87 * Not static because shared with colormaps.c and other events files, but
88 * not listed in events.h since nowhere else needs it.
89 */
91TwmWindow *Tmp_win; // the current twm window; shared with other event code
92
94bool Cancel = false;
95
96
97
98/*
99 * Initialize the event handling bits. Mainly the jump table for event
100 * handling, plus various event vars. Called during startup.
101 */
102void
104{
105 /* Clear out vars */
106 ResizeWindow = (Window) 0;
107 DragWindow = (Window) 0;
108 enter_flag = false;
110 leave_flag = false;
112
113 /* Set everything to unknown to start */
114 for(int i = 0; i < MAX_X_EVENT; i++) {
116 }
117
118#define STDH(evt) EventHandler[evt] = Handle##evt
119
120 /* Init the standard events */
121 STDH(Expose);
135 STDH(KeyPress);
140
141 /* Focus handlers are special; see comment on HandleFocusChange() */
144
145 /* Some more conditional bits */
146#ifdef EWMH
148#endif
149
150 /*
151 * Optional extensions are registered dynamically, so their events
152 * are put by the X server at some offset into the event number tree
153 * when it starts.
154 */
155 if(HasShape) {
157 }
158
159#undef STDH
160
161 /* And done */
162 return;
163}
164
165
166
167/*
168 * Main event loop.
169 *
170 * This is the last thing called during ctwm startup, and never returns.
171 * So in essence, this is everything ctwm does except starting up and
172 * shutting down (and that latter winds up called through us as well).
173 */
174void
176{
177 while(1) {
178 if(enter_flag && !QLength(dpy)) {
179 if(enter_win && enter_win != raise_win) {
180 AutoRaiseWindow(enter_win); /* sets enter_flag T */
181 }
182 else {
183 enter_flag = false;
184 }
185 }
186 if(leave_flag && !QLength(dpy)) {
187 if(leave_win && leave_win != lower_win) {
188 AutoLowerWindow(leave_win); /* sets leave_flag T */
189 }
190 else {
191 leave_flag = false;
192 }
193 }
194 if(ColortableThrashing && !QLength(dpy) && Scr) {
196 }
197 WindowMoved = false;
198
200
201 if(Event.type < 0 || Event.type >= MAX_X_EVENT) {
203 }
204 else {
206 }
207 }
208
209 /* NOTREACHED */
210 fprintf(stderr, "Error: Should never reach the end of HandleEvents()\n");
211 exit(1);
212}
213
214
215/*
216 * Grab the next event in the queue to process.
217 */
218static void
220{
221 int fd;
222 struct timeval timeout, *tout = NULL;
223 const bool animate = (AnimationActive && MaybeAnimate);
224
225#define NEXTEVENT XtAppNextEvent(appContext, event)
226
227 if(SignalFlag) {
229 }
231 NEXTEVENT;
232 return;
233 }
235
236 if(animate) {
237 TryToAnimate();
238 }
239 if(SignalFlag) {
241 }
242 if(! MaybeAnimate) {
243 NEXTEVENT;
244 return;
245 }
246 if(animate) {
247 tout = (AnimationSpeed > 0) ? &timeout : NULL;
248 }
249 while(1) {
250 fd_set mask;
251 int found;
252
253 FD_ZERO(&mask);
254 FD_SET(fd, &mask);
255 if(animate) {
257 }
258 found = select(fd + 1, &mask, NULL, NULL, tout);
259 if(SignalFlag) {
261 }
262 if(found < 0) {
263 if(errno != EINTR) {
264 perror("select");
265 }
266 continue;
267 }
268 if(FD_ISSET(fd, &mask)) {
269 NEXTEVENT;
270 return;
271 }
272 if(found == 0) {
273 if(animate) {
274 TryToAnimate();
275 }
276 if(SignalFlag) {
278 }
279 if(! MaybeAnimate) {
280 NEXTEVENT;
281 return;
282 }
283 continue;
284 }
285 }
286
287#undef NEXTEVENT
288
289 /* NOTREACHED */
290}
291
292
293
294/*
295 * And dispatchers. These look at the global Event and run with it from
296 * there.
297 *
298 * There are slight differences between the two, and it's not at all
299 * clear to what extent there should be or why they're different. At
300 * least some of the difference seem gratuitous; this requires further
301 * research. They probably can and should be collapsed together.
302 */
303/* Main dispatcher, from the loop above and a few other places */
304bool
306{
307 Window w = Event.xany.window;
309
313
315
316 if(!thisScr) {
317 return false;
318 }
319 Scr = thisScr;
320
321#ifdef CAPTIVE
322 if(CLarg.is_captive) {
323 if((Event.type == ConfigureNotify)
324 && (Event.xconfigure.window == Scr->CaptiveRoot)) {
326 return false;
327 }
328 }
329#endif
331 if(Event.type >= 0 && Event.type < MAX_X_EVENT) {
332#ifdef SOUNDS
333 play_sound(Event.type);
334#endif
335 (*EventHandler[Event.type])();
336 }
337 return true;
338}
339
340
341/* Alternate; called from various function and menu code */
342bool
344{
345 Window w = Event.xany.window;
347
351
353
354 if(!thisScr) {
355 return false;
356 }
357 Scr = thisScr;
358
360
361#ifdef SOUNDS
362 play_sound(Event.type);
363#endif
364
366 if(Event.type == Expose) {
367 HandleExpose();
368 }
369 }
370 else {
371 if(Event.type >= 0 && Event.type < MAX_X_EVENT) {
372 (*EventHandler[Event.type])();
373 }
374 }
375
376 return true;
377}
378
379
380
381
382/*
383 * Stash the time of the given event in our EventTime global. Called
384 * during dispatching the event.
385 */
386static bool
388{
389 switch(ev->type) {
390 case KeyPress:
391 case KeyRelease:
392 EventTime = ev->xkey.time;
393 return true;
394 case ButtonPress:
395 case ButtonRelease:
396 EventTime = ev->xbutton.time;
397 return true;
398 case MotionNotify:
399 EventTime = ev->xmotion.time;
400 return true;
401 case EnterNotify:
402 case LeaveNotify:
403 EventTime = ev->xcrossing.time;
404 return true;
405 case PropertyNotify:
406 EventTime = ev->xproperty.time;
407 return true;
408 case SelectionClear:
409 EventTime = ev->xselectionclear.time;
410 return true;
411 case SelectionRequest:
412 EventTime = ev->xselectionrequest.time;
413 return true;
414 case SelectionNotify:
415 EventTime = ev->xselection.time;
416 return true;
417 }
418 return false;
419}
420
421
422/*
423 * Debugging: output details of an event. Or at least, details of a few
424 * events, presumably those which somebody doing debugging needed at the
425 * time.
426 */
427static void
429{
430 const char *name;
431
432 if(! tracefile) {
433 return;
434 }
435
436 /* Whatsit? */
437 name = event_name_by_num(e->type);
438 if(!name) {
439 name = "Unknown event";
440 }
441
442 /* Tell about it */
443 fprintf(tracefile, "event: %s in window 0x%x\n", name,
444 (unsigned int)e->xany.window);
445 switch(e->type) {
446 case KeyPress:
447 case KeyRelease:
448 fprintf(tracefile, " : +%d,+%d (+%d,+%d) state=%d, keycode=%d\n",
449 e->xkey.x, e->xkey.y,
450 e->xkey.x_root, e->xkey.y_root,
451 e->xkey.state, e->xkey.keycode);
452 break;
453 case ButtonPress:
454 case ButtonRelease:
455 fprintf(tracefile, " : +%d,+%d (+%d,+%d) state=%d, button=%d\n",
456 e->xbutton.x, e->xbutton.y,
457 e->xbutton.x_root, e->xbutton.y_root,
458 e->xbutton.state, e->xbutton.button);
459 break;
460 }
461}
static int PlaceX
Definition add_window.c:82
int AnimationSpeed
Definition animate.c:31
bool MaybeAnimate
Definition animate.c:33
void TryToAnimate(void)
Definition animate.c:55
bool AnimationActive
Definition animate.c:32
struct timeval AnimateTimeout
Definition animate.c:34
void ConfigureCaptiveRootWindow(XEvent *ev)
Definition captive.c:641
ctwm_cl_args CLarg
Definition clargs.c:27
bool InstallColormaps(int type, Colormaps *cmaps)
Definition colormaps.c:51
int ShapeEventBase
Definition ctwm_main.c:91
Display * dpy
Definition ctwm_main.c:84
bool SignalFlag
Some signal flag has been set.
Definition signals.c:27
bool HasShape
Definition ctwm_main.c:90
Window ResizeWindow
Definition ctwm_main.c:85
#define C_NO_CONTEXT
Definition ctwm.h:74
#define Scr
unsigned int DragBW
Definition event_core.c:75
int CurrentDragY
Definition event_core.c:77
bool ColortableThrashing
Definition event_core.c:90
void InitEvents(void)
Definition event_core.c:103
Time EventTime
Definition event_core.c:79
int CurrentDragX
Definition event_core.c:76
bool Cancel
Definition event_core.c:94
int origDragX
Definition event_core.c:69
unsigned int DragWidth
Definition event_core.c:73
bool leave_flag
Definition event_core.c:83
#define NEXTEVENT
TwmWindow * lower_win
Definition event_core.c:84
unsigned int DragHeight
Definition event_core.c:74
static void dumpevent(const XEvent *e)
Definition event_core.c:428
int origDragY
Definition event_core.c:70
bool enter_flag
Definition event_core.c:82
void HandleEvents(void)
Definition event_core.c:175
TwmWindow * raise_win
Definition event_core.c:84
int DragY
Definition event_core.c:72
bool DispatchEvent(void)
Definition event_core.c:305
static bool StashEventTime(XEvent *ev)
Definition event_core.c:387
TwmWindow * Tmp_win
Definition event_core.c:91
bool DispatchEvent2(void)
Definition event_core.c:343
TwmWindow * enter_win
Definition event_core.c:84
#define STDH(evt)
XEvent Event
Definition event_core.c:66
event_proc EventHandler[256]
Definition event_core.c:64
int ButtonPressed
Definition event_core.c:93
Window DragWindow
Definition event_core.c:68
#define MAX_X_EVENT
Definition event_core.c:63
int DragX
Definition event_core.c:71
int Context
Definition event_core.c:65
TwmWindow * leave_win
Definition event_core.c:84
static void CtwmNextEvent(Display *display, XEvent *event)
Definition event_core.c:219
void HandleFocusChange(void)
void HandleUnknown(void)
void HandleShapeNotify(void)
void HandleExpose(void)
ScreenInfo * GetTwmScreen(XEvent *event)
void AutoLowerWindow(TwmWindow *tmp)
Definition event_utils.c:71
const char * event_name_by_num(int evt)
Definition event_names.c:27
void FixRootEvent(XEvent *e)
void AutoRaiseWindow(TwmWindow *tmp)
Definition event_utils.c:27
void(* event_proc)(void)
Definition events.h:21
bool WindowMoved
Definition functions.c:52
bool menuFromFrameOrWindowOrTitlebar
Definition menus.c:60
void handle_signal_flag(Time t)
Handle stuff set by a signal flag.
Definition signals.c:62
void play_sound(int snd)
Definition sound.c:222
Info and control for each X Screen we control.
Definition screen.h:96
Info and control for every X Window we take over.
FILE * tracefile
Definition util.c:59
TwmWindow * GetTwmWindow(Window w)
Definition win_utils.c:190