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