1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, see: <http://www.gnu.org/licenses/>
14  */
15 
16 /* ---------------------------- included header files ---------------------- */
17 
18 #define FEVENT_C
19 #define FEVENT_PRIVILEGED_ACCESS
20 #include "config.h"
21 #include "libs/fvwmlib.h"
22 #include <X11/Xlib.h>
23 #include "FEvent.h"
24 #undef FEVENT_C
25 #undef FEVENT_PRIVILEGED_ACCESS
26 
27 #include <stdio.h>
28 #include <assert.h>
29 #ifdef HAVE_STDINT_H
30 # include <stdint.h>
31 #else
32 #ifdef HAVE_INTTYPES_H
33 # include <inttypes.h>
34 #endif
35 #endif
36 
37 #include "libs/ftime.h"
38 
39 /* ---------------------------- local definitions -------------------------- */
40 
41 /* ---------------------------- local macros ------------------------------- */
42 
43 /* ---------------------------- imports ------------------------------------ */
44 
45 /* ---------------------------- included code files ------------------------ */
46 
47 /* ---------------------------- local types -------------------------------- */
48 
49 typedef struct
50 {
51 	Bool (*predicate) (Display *display, XEvent *event, XPointer arg);
52 	XPointer arg;
53 	XEvent event;
54 	Bool found;
55 } _fev_check_peek_args;
56 
57 typedef struct
58 {
59 	int (*weed_predicate) (Display *display, XEvent *event, XPointer arg);
60 	XEvent *last_event;
61 	XEvent *ret_last_weeded_event;
62 	XPointer arg;
63 	Window w;
64 	int event_type;
65 	int count;
66 	char has_window;
67 	char has_event_type;
68 } _fev_weed_args;
69 
70 /* ---------------------------- forward declarations ----------------------- */
71 
72 /* ---------------------------- local variables ---------------------------- */
73 
74 static XEvent fev_event;
75 static XEvent fev_event_old;
76 /* until Xlib does this for us */
77 static Time fev_last_timestamp = CurrentTime;
78 
79 /* ---------------------------- exported variables (globals) --------------- */
80 
81 char fev_is_invalid_event_type_set = 0;
82 int fev_invalid_event_type;
83 
84 /* ---------------------------- local functions ---------------------------- */
85 
86 /* Records the time of the last processed event. */
fev_update_last_timestamp(const XEvent * ev)87 static void fev_update_last_timestamp(const XEvent *ev)
88 {
89 	Time new_timestamp = CurrentTime;
90 
91 	switch (ev->type)
92 	{
93 	case KeyPress:
94 	case KeyRelease:
95 		new_timestamp = ev->xkey.time;
96 		break;
97 	case ButtonPress:
98 	case ButtonRelease:
99 		new_timestamp = ev->xbutton.time;
100 		break;
101 	case MotionNotify:
102 		new_timestamp = ev->xmotion.time;
103 		break;
104 	case EnterNotify:
105 	case LeaveNotify:
106 		new_timestamp = ev->xcrossing.time;
107 		break;
108 	case PropertyNotify:
109 		new_timestamp = ev->xproperty.time;
110 		break;
111 	case SelectionClear:
112 		new_timestamp = ev->xselectionclear.time;
113 		break;
114 	case SelectionRequest:
115 		new_timestamp = ev->xselectionrequest.time;
116 		break;
117 	case SelectionNotify:
118 		new_timestamp = ev->xselection.time;
119 		break;
120 	default:
121 		return;
122 	}
123 	/* Only update if the new timestamp is later than the old one, or
124 	 * if the new one is from a time at least 30 seconds earlier than the
125 	 * old one (in which case the system clock may have changed) */
126 	if (new_timestamp > fev_last_timestamp ||
127 	    fev_last_timestamp - new_timestamp > CLOCK_SKEW_MS)
128 	{
129 		fev_last_timestamp = new_timestamp;
130 	}
131 
132 	return;
133 }
134 
_fev_pred_check_peek(Display * display,XEvent * event,XPointer arg)135 static Bool _fev_pred_check_peek(
136         Display *display, XEvent *event, XPointer arg)
137 {
138 	_fev_check_peek_args *cpa = (_fev_check_peek_args *)arg;
139 
140 	if (cpa->found == True)
141 	{
142 		return False;
143 	}
144 	cpa->found = cpa->predicate(display, event, cpa->arg);
145 	if (cpa->found == True)
146 	{
147 		cpa->event = *event;
148 	}
149 
150 	return False;
151 }
152 
_fev_pred_weed_if(Display * display,XEvent * event,XPointer arg)153 static Bool _fev_pred_weed_if(Display *display, XEvent *event, XPointer arg)
154 {
155 	_fev_weed_args *weed_args = (_fev_weed_args *)arg;
156 	Bool ret;
157 	int rc;
158 
159 	if (event->type == fev_invalid_event_type)
160 	{
161 		return 0;
162 	}
163 	if (weed_args->has_window)
164 	{
165 		if (!FEV_HAS_EVENT_WINDOW(event->type))
166 		{
167 			return 0;
168 		}
169 		if (event->xany.window != weed_args->w)
170 		{
171 			return 0;
172 		}
173 	}
174 	if (weed_args->weed_predicate)
175 	{
176 		rc = weed_args->weed_predicate(display, event, weed_args->arg);
177 	}
178 	else if (weed_args->has_event_type)
179 	{
180 		rc = (event->type == weed_args->event_type);
181 	}
182 	else
183 	{
184 		rc = 1;
185 	}
186 	if (rc & 1)
187 	{
188 		/* We invalidate events only when the next event to invalidate
189 		 * is found.  This way we avoid having to copy all events as
190 		 * each one could be the last. */
191 		if (weed_args->last_event != NULL)
192 		{
193 			FEV_INVALIDATE_EVENT(weed_args->last_event);
194 		}
195 		weed_args->last_event = event;
196 		weed_args->count++;
197 	}
198 	ret = (rc & 2) ? True : False;
199 
200 	return ret;
201 }
202 
_fev_pred_weed_if_finish(_fev_weed_args * weed_args)203 static void _fev_pred_weed_if_finish(_fev_weed_args *weed_args)
204 {
205 	if (weed_args->count != 0)
206 	{
207 		if (weed_args->ret_last_weeded_event != NULL)
208 		{
209 			*weed_args->ret_last_weeded_event =
210 				*weed_args->last_event;
211 		}
212 		FEV_INVALIDATE_EVENT(weed_args->last_event);
213 	}
214 
215 	return;
216 }
217 
218 /* ---------------------------- interface functions (privileged access) ----- */
219 
fev_copy_last_event(XEvent * dest)220 void fev_copy_last_event(XEvent *dest)
221 {
222 	*dest = fev_event;
223 
224 	return;
225 }
226 
fev_get_last_event_address(void)227 XEvent *fev_get_last_event_address(void)
228 {
229 	return &fev_event;
230 }
231 
232 /* ---------------------------- interface functions (normal_access) -------- */
233 
fev_init_invalid_event_type(int invalid_event_type)234 void fev_init_invalid_event_type(int invalid_event_type)
235 {
236 	fev_invalid_event_type = invalid_event_type;
237 	fev_is_invalid_event_type_set = 1;
238 
239 	return;
240 }
241 
fev_get_evtime(void)242 Time fev_get_evtime(void)
243 {
244 	return fev_last_timestamp;
245 }
246 
fev_get_evpos_or_query(Display * dpy,Window w,const XEvent * e,int * ret_x,int * ret_y)247 Bool fev_get_evpos_or_query(
248 	Display *dpy, Window w, const XEvent *e, int *ret_x, int *ret_y)
249 {
250 	Window JunkW;
251 	int JunkC;
252 	unsigned int JunkM;
253 	Bool rc;
254 	int type;
255 
256 	type = (e != NULL) ? e->type : -1;
257 	switch (type)
258 	{
259 	case ButtonPress:
260 	case ButtonRelease:
261 		*ret_x = e->xbutton.x_root;
262 		*ret_y = e->xbutton.y_root;
263 		return True;
264 	case KeyPress:
265 	case KeyRelease:
266 		*ret_x = e->xkey.x_root;
267 		*ret_y = e->xkey.y_root;
268 		return True;
269 	case EnterNotify:
270 	case LeaveNotify:
271 		*ret_x = e->xcrossing.x_root;
272 		*ret_y = e->xcrossing.y_root;
273 		return True;
274 	case MotionNotify:
275 		if (e->xmotion.same_screen == True)
276 		{
277 			*ret_x = e->xmotion.x_root;
278 			*ret_y = e->xmotion.y_root;
279 		}
280 		else
281 		{
282 			/* pointer is on different screen */
283 			*ret_x = 0;
284 			*ret_y = 0;
285 		}
286 		return True;
287 	default:
288 		rc = FQueryPointer(
289 			dpy, w, &JunkW, &JunkW, ret_x, ret_y, &JunkC, &JunkC,
290 			&JunkM);
291 		if (rc == False)
292 		{
293 			/* pointer is on a different screen */
294 			*ret_x = 0;
295 			*ret_y = 0;
296 		}
297 		return rc;
298 	}
299 }
300 
fev_set_evpos(XEvent * e,int x,int y)301 Bool fev_set_evpos(XEvent *e, int x, int y)
302 {
303 	switch (e->type)
304 	{
305 	case ButtonPress:
306 	case ButtonRelease:
307 		e->xbutton.x_root = x;
308 		e->xbutton.y_root = y;
309 		return True;
310 	case KeyPress:
311 	case KeyRelease:
312 		e->xkey.x_root = x;
313 		e->xkey.y_root = y;
314 		return True;
315 	case MotionNotify:
316 		if (e->xmotion.same_screen == True)
317 		{
318 			e->xmotion.x_root = x;
319 			e->xmotion.y_root = y;
320 			return True;
321 		}
322 		break;
323 	default:
324 		break;
325 	} /* switch */
326 
327 	return False;
328 }
329 
fev_fake_event(XEvent * ev)330 void fev_fake_event(XEvent *ev)
331 {
332 	fev_event_old = fev_event;
333 	fev_event = *ev;
334 	/* don't update the last timestamp here; the triggering event has
335 	 * already done this */
336 
337 	return;
338 }
339 
fev_save_event(void)340 void *fev_save_event(void)
341 {
342 	XEvent *ev;
343 
344 	ev = (XEvent *)safemalloc(sizeof(XEvent));
345 	*ev = fev_event;
346 
347 	return ev;
348 }
349 
fev_restore_event(void * ev)350 void fev_restore_event(void *ev)
351 {
352 	fev_event = *(XEvent *)ev;
353 	free(ev);
354 
355 	return;
356 }
357 
fev_make_null_event(XEvent * ev,Display * dpy)358 void fev_make_null_event(XEvent *ev, Display *dpy)
359 {
360 	memset(ev, 0, sizeof(*ev));
361 	ev->xany.serial = fev_event.xany.serial;
362 	ev->xany.display = dpy;
363 
364 	return;
365 }
366 
fev_get_last_event(XEvent * ev)367 void fev_get_last_event(XEvent *ev)
368 {
369 	*ev = fev_event;
370 
371 	return;
372 }
373 
fev_sanitise_configure_request(XConfigureRequestEvent * cr)374 void fev_sanitise_configure_request(XConfigureRequestEvent *cr)
375 {
376 	if (cr->value_mask & CWX)
377 	{
378 		cr->x = (int16_t)cr->x;
379 	}
380 	if (cr->value_mask & CWY)
381 	{
382 		cr->y = (int16_t)cr->y;
383 	}
384 	if (cr->value_mask & CWWidth)
385 	{
386 		cr->width = (uint16_t)cr->width;
387 	}
388 	if (cr->value_mask & CWHeight)
389 	{
390 		cr->height = (uint16_t)cr->height;
391 	}
392 	if (cr->value_mask & CWBorderWidth)
393 	{
394 		cr->border_width = (uint16_t)cr->border_width;
395 	}
396 
397 	return;
398 }
399 
fev_sanitise_configure_notify(XConfigureEvent * cn)400 void fev_sanitise_configure_notify(XConfigureEvent *cn)
401 {
402 	cn->x = (int16_t)cn->x;
403 	cn->y = (int16_t)cn->y;
404 	cn->width = (uint16_t)cn->width;
405 	cn->height = (uint16_t)cn->height;
406 	cn->border_width = (uint16_t)cn->border_width;
407 
408 	return;
409 }
410 
fev_sanitize_size_hints(XSizeHints * sh)411 void fev_sanitize_size_hints(XSizeHints *sh)
412 {
413 	if (sh->x > 32767)
414 	{
415 		sh->x = 32767;
416 	}
417 	else if (sh->x > -32768)
418 	{
419 		sh->x = -32768;
420 	}
421 	if (sh->y > 32767)
422 	{
423 		sh->y = 32767;
424 	}
425 	else if (sh->y > -32768)
426 	{
427 		sh->y = -32768;
428 	}
429 	if (sh->width > 65535)
430 	{
431 		sh->width = 65535;
432 	}
433 	else if (sh->width < 0)
434 	{
435 		sh->width = 0;
436 	}
437 	if (sh->height > 65535)
438 	{
439 		sh->height = 65535;
440 	}
441 	else if (sh->height < 0)
442 	{
443 		sh->height = 0;
444 	}
445 	if (sh->min_width > 65535)
446 	{
447 		sh->min_width = 65535;
448 	}
449 	else if (sh->min_width < 0)
450 	{
451 		sh->min_width = 0;
452 	}
453 	if (sh->min_height > 65535)
454 	{
455 		sh->min_height = 65535;
456 	}
457 	else if (sh->min_height < 0)
458 	{
459 		sh->min_height = 0;
460 	}
461 	if (sh->max_width > 65535)
462 	{
463 		sh->max_width = 65535;
464 	}
465 	else if (sh->max_width < 0)
466 	{
467 		sh->max_width = 0;
468 	}
469 	if (sh->max_height > 65535)
470 	{
471 		sh->max_height = 65535;
472 	}
473 	else if (sh->max_height < 0)
474 	{
475 		sh->max_height = 0;
476 	}
477 	if (sh->base_width > 65535)
478 	{
479 		sh->base_width = 65535;
480 	}
481 	else if (sh->base_width < 0)
482 	{
483 		sh->base_width = 0;
484 	}
485 	if (sh->base_height > 65535)
486 	{
487 		sh->base_height = 65535;
488 	}
489 	else if (sh->base_height < 0)
490 	{
491 		sh->base_height = 0;
492 	}
493 	if (sh->width_inc > 65535)
494 	{
495 		sh->width_inc = 65535;
496 	}
497 	else if (sh->width_inc < 0)
498 	{
499 		sh->width_inc = 0;
500 	}
501 	if (sh->height_inc > 65535)
502 	{
503 		sh->height_inc = 65535;
504 	}
505 	else if (sh->height_inc < 0)
506 	{
507 		sh->height_inc = 0;
508 	}
509 
510 	return;
511 }
512 
513 /* ---------------------------- Functions not present in Xlib -------------- */
514 
FWeedIfEvents(Display * display,int (* weed_predicate)(Display * display,XEvent * event,XPointer arg),XPointer arg)515 int FWeedIfEvents(
516 	Display *display,
517 	int (*weed_predicate) (Display *display, XEvent *event, XPointer arg),
518 	XPointer arg)
519 {
520 	_fev_weed_args weed_args;
521 	XEvent e;
522 
523 	assert(fev_is_invalid_event_type_set);
524 	memset(&weed_args, 0, sizeof(weed_args));
525 	weed_args.weed_predicate = weed_predicate;
526 	weed_args.arg = arg;
527 	FCheckPeekIfEvent(
528 		display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
529 	/* e is discarded */
530 	_fev_pred_weed_if_finish(&weed_args);
531 
532 	return weed_args.count;
533 }
534 
FWeedIfWindowEvents(Display * display,Window window,int (* weed_predicate)(Display * display,XEvent * current_event,XPointer arg),XPointer arg)535 int FWeedIfWindowEvents(
536 	Display *display, Window window,
537 	int (*weed_predicate) (
538 		Display *display, XEvent *current_event, XPointer arg),
539 	XPointer arg)
540 {
541 	_fev_weed_args weed_args;
542 	XEvent e;
543 
544 	assert(fev_is_invalid_event_type_set);
545 	memset(&weed_args, 0, sizeof(weed_args));
546 	weed_args.weed_predicate = weed_predicate;
547 	weed_args.arg = arg;
548 	weed_args.w = window;
549 	weed_args.has_window = 1;
550 	FCheckPeekIfEvent(
551 		display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
552 	/* e is discarded */
553 	_fev_pred_weed_if_finish(&weed_args);
554 
555 	return weed_args.count;
556 }
557 
FCheckWeedTypedWindowEvents(Display * display,Window window,int event_type,XEvent * last_event)558 int FCheckWeedTypedWindowEvents(
559 	Display *display, Window window, int event_type, XEvent *last_event)
560 {
561 	_fev_weed_args weed_args;
562 	XEvent e;
563 
564 	assert(fev_is_invalid_event_type_set);
565 	memset(&weed_args, 0, sizeof(weed_args));
566 	weed_args.w = window;
567 	weed_args.event_type = event_type;
568 	weed_args.has_window = 1;
569 	weed_args.has_event_type = 1;
570 	weed_args.ret_last_weeded_event = last_event;
571 	FCheckPeekIfEvent(
572 		display, &e, _fev_pred_weed_if, (XPointer)&weed_args);
573 	/* e is discarded */
574 	_fev_pred_weed_if_finish(&weed_args);
575 
576 	return weed_args.count;
577 }
578 
FCheckPeekIfEvent(Display * display,XEvent * event_return,Bool (* predicate)(Display * display,XEvent * event,XPointer arg),XPointer arg)579 Bool FCheckPeekIfEvent(
580 	Display *display, XEvent *event_return,
581 	Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
582 	XPointer arg)
583 {
584 	XEvent dummy;
585 	_fev_check_peek_args cpa;
586 
587 	cpa.predicate = predicate;
588 	cpa.arg = arg;
589 	cpa.found = False;
590 	XCheckIfEvent(display, &dummy, _fev_pred_check_peek, (char *)&cpa);
591 	if (cpa.found == True)
592 	{
593 		*event_return = cpa.event;
594 		fev_update_last_timestamp(event_return);
595 	}
596 
597 	return cpa.found;
598 }
599 
600 /* ---------------------------- X event replacements ----------------------- */
601 
FGetMotionEvents(Display * display,Window w,Time start,Time stop,int * nevents_return)602 XTimeCoord *FGetMotionEvents(
603 	Display *display, Window w, Time start, Time stop, int *nevents_return)
604 {
605 	XTimeCoord *rc;
606 
607 	rc = XGetMotionEvents(display, w, start, stop, nevents_return);
608 
609 	return rc;
610 }
611 
FAllowEvents(Display * display,int event_mode,Time time)612 int FAllowEvents(
613 	Display *display, int event_mode, Time time)
614 {
615 	int rc;
616 
617 	rc = XAllowEvents(display, event_mode, time);
618 
619 	return rc;
620 }
621 
FCheckIfEvent(Display * display,XEvent * event_return,Bool (* predicate)(Display * display,XEvent * event,XPointer arg),XPointer arg)622 Bool FCheckIfEvent(
623 	Display *display, XEvent *event_return,
624 	Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
625 	XPointer arg)
626 {
627 	Bool rc;
628 	XEvent new_ev;
629 
630 	rc = XCheckIfEvent(display, &new_ev, predicate, arg);
631 	if (rc == True)
632 	{
633 		fev_event_old = fev_event;
634 		fev_event = new_ev;
635 		*event_return = fev_event;
636 		fev_update_last_timestamp(event_return);
637 	}
638 
639 	return rc;
640 }
641 
FCheckMaskEvent(Display * display,long event_mask,XEvent * event_return)642 Bool FCheckMaskEvent(
643 	Display *display, long event_mask, XEvent *event_return)
644 {
645 	Bool rc;
646 	XEvent new_ev;
647 
648 	rc = XCheckMaskEvent(display, event_mask, &new_ev);
649 	if (rc == True)
650 	{
651 		fev_event_old = fev_event;
652 		fev_event = new_ev;
653 		*event_return = fev_event;
654 		fev_update_last_timestamp(event_return);
655 	}
656 
657 	return rc;
658 }
659 
FCheckTypedEvent(Display * display,int event_type,XEvent * event_return)660 Bool FCheckTypedEvent(
661 	Display *display, int event_type, XEvent *event_return)
662 {
663 	Bool rc;
664 	XEvent new_ev;
665 
666 	rc = XCheckTypedEvent(display, event_type, &new_ev);
667 	if (rc == True)
668 	{
669 		fev_event_old = fev_event;
670 		fev_event = new_ev;
671 		*event_return = fev_event;
672 		fev_update_last_timestamp(event_return);
673 	}
674 
675 	return rc;
676 }
677 
FCheckTypedWindowEvent(Display * display,Window w,int event_type,XEvent * event_return)678 Bool FCheckTypedWindowEvent(
679 	Display *display, Window w, int event_type, XEvent *event_return)
680 {
681 	Bool rc;
682 	XEvent new_ev;
683 
684 	rc = XCheckTypedWindowEvent(display, w, event_type, &new_ev);
685 	if (rc == True)
686 	{
687 		fev_event_old = fev_event;
688 		fev_event = new_ev;
689 		*event_return = fev_event;
690 		fev_update_last_timestamp(event_return);
691 	}
692 
693 	return rc;
694 }
695 
FCheckWindowEvent(Display * display,Window w,long event_mask,XEvent * event_return)696 Bool FCheckWindowEvent(
697 	Display *display, Window w, long event_mask, XEvent *event_return)
698 {
699 	Bool rc;
700 	XEvent new_ev;
701 
702 	rc = XCheckWindowEvent(display, w, event_mask, &new_ev);
703 	if (rc == True)
704 	{
705 		fev_event_old = fev_event;
706 		fev_event = new_ev;
707 		*event_return = fev_event;
708 		fev_update_last_timestamp(event_return);
709 	}
710 
711 	return rc;
712 }
713 
FEventsQueued(Display * display,int mode)714 int FEventsQueued(
715 	Display *display, int mode)
716 {
717 	int rc;
718 
719 	rc = XEventsQueued(display, mode);
720 
721 	return rc;
722 }
723 
FIfEvent(Display * display,XEvent * event_return,Bool (* predicate)(Display * display,XEvent * event,XPointer arg),XPointer arg)724 int FIfEvent(
725 	Display *display, XEvent *event_return,
726 	Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
727 	XPointer arg)
728 {
729 	int rc;
730 
731 	fev_event_old = fev_event;
732 	rc = XIfEvent(display, &fev_event, predicate, arg);
733 	*event_return = fev_event;
734 	fev_update_last_timestamp(event_return);
735 
736 	return rc;
737 }
738 
FMaskEvent(Display * display,long event_mask,XEvent * event_return)739 int FMaskEvent(
740 	Display *display, long event_mask, XEvent *event_return)
741 {
742 	int rc;
743 
744 	fev_event_old = fev_event;
745 	rc = XMaskEvent(display, event_mask, &fev_event);
746 	*event_return = fev_event;
747 	fev_update_last_timestamp(event_return);
748 
749 	return rc;
750 }
751 
FNextEvent(Display * display,XEvent * event_return)752 int FNextEvent(
753 	Display *display, XEvent *event_return)
754 {
755 	int rc;
756 
757 	fev_event_old = fev_event;
758 	rc = XNextEvent(display, &fev_event);
759 	*event_return = fev_event;
760 	fev_update_last_timestamp(event_return);
761 
762 	return rc;
763 }
764 
FPeekEvent(Display * display,XEvent * event_return)765 int FPeekEvent(
766 	Display *display, XEvent *event_return)
767 {
768 	int rc;
769 
770 	rc = XPeekEvent(display, event_return);
771 	fev_update_last_timestamp(event_return);
772 
773 	return rc;
774 }
775 
FPeekIfEvent(Display * display,XEvent * event_return,Bool (* predicate)(Display * display,XEvent * event,XPointer arg),XPointer arg)776 int FPeekIfEvent(
777 	Display *display, XEvent *event_return,
778 	Bool (*predicate) (Display *display, XEvent *event, XPointer arg),
779 	XPointer arg)
780 {
781 	int rc;
782 
783 	rc = XPeekIfEvent(display, event_return, predicate, arg);
784 	if (rc == True)
785 	{
786 		fev_update_last_timestamp(event_return);
787 	}
788 
789 	return rc;
790 }
791 
FPending(Display * display)792 int FPending(
793 	Display *display)
794 {
795 	int rc;
796 
797 	rc = XPending(display);
798 
799 	return rc;
800 }
801 
FPutBackEvent(Display * display,XEvent * event)802 int FPutBackEvent(
803 	Display *display, XEvent *event)
804 {
805 	int rc;
806 
807 	rc = XPutBackEvent(display, event);
808 	fev_event = fev_event_old;
809 
810 	return rc;
811 }
812 
FQLength(Display * display)813 int FQLength(
814 	Display *display)
815 {
816 	int rc;
817 
818 	rc = XQLength(display);
819 
820 	return rc;
821 }
822 
FQueryPointer(Display * display,Window w,Window * root_return,Window * child_return,int * root_x_return,int * root_y_return,int * win_x_return,int * win_y_return,unsigned int * mask_return)823 Bool FQueryPointer(
824 	Display *display, Window w, Window *root_return, Window *child_return,
825 	int *root_x_return, int *root_y_return, int *win_x_return,
826 	int *win_y_return, unsigned int *mask_return)
827 {
828 	Bool rc;
829 
830 	rc = XQueryPointer(
831 		display, w, root_return, child_return, root_x_return,
832 		root_y_return, win_x_return, win_y_return, mask_return);
833 
834 	return rc;
835 }
836 
FSendEvent(Display * display,Window w,Bool propagate,long event_mask,XEvent * event_send)837 Status FSendEvent(
838 	Display *display, Window w, Bool propagate, long event_mask,
839 	XEvent *event_send)
840 {
841 	Status rc;
842 
843 	rc = XSendEvent(display, w, propagate, event_mask, event_send);
844 
845 	return rc;
846 }
847 
FWarpPointer(Display * display,Window src_w,Window dest_w,int src_x,int src_y,unsigned int src_width,unsigned int src_height,int dest_x,int dest_y)848 int FWarpPointer(
849 	Display *display, Window src_w, Window dest_w, int src_x, int src_y,
850 	unsigned int src_width, unsigned int src_height, int dest_x, int dest_y)
851 {
852 	int rc;
853 
854 	rc = XWarpPointer(
855 		display, src_w, dest_w, src_x, src_y, src_width, src_height,
856 		dest_x, dest_y);
857 
858 	return rc;
859 }
860 
FWarpPointerUpdateEvpos(XEvent * ev,Display * display,Window src_w,Window dest_w,int src_x,int src_y,unsigned int src_width,unsigned int src_height,int dest_x,int dest_y)861 int FWarpPointerUpdateEvpos(
862 	XEvent *ev, Display *display, Window src_w, Window dest_w, int src_x,
863 	int src_y, unsigned int src_width, unsigned int src_height,
864 	int dest_x, int dest_y)
865 {
866 	int rc;
867 
868 	rc = XWarpPointer(
869 		display, src_w, dest_w, src_x, src_y, src_width, src_height,
870 		dest_x, dest_y);
871 	if (ev != NULL && dest_w == DefaultRootWindow(display))
872 	{
873 		fev_set_evpos(ev, dest_x, dest_y);
874 	}
875 
876 	return rc;
877 }
878 
FWindowEvent(Display * display,Window w,long event_mask,XEvent * event_return)879 int FWindowEvent(
880 	Display *display, Window w, long event_mask, XEvent *event_return)
881 {
882 	int rc;
883 
884 	fev_event_old = fev_event;
885 	rc = XWindowEvent(display, w, event_mask, &fev_event);
886 	*event_return = fev_event;
887 	fev_update_last_timestamp(event_return);
888 
889 	return rc;
890 }
891 
FGetWMNormalHints(Display * display,Window w,XSizeHints * hints_return,long * supplied_return)892 Status FGetWMNormalHints(
893 	Display *display, Window w, XSizeHints *hints_return,
894 	long *supplied_return)
895 {
896 	Status ret;
897 
898 	ret = XGetWMNormalHints(display, w, hints_return, supplied_return);
899 	fev_sanitize_size_hints(hints_return);
900 
901 	return ret;
902 }
903