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