1 /**
2 *
3 * $Header: /cvsroot/lesstif/lesstif/test/common/Test.c,v 1.37 2002/05/01 15:19:15 amai Exp $
4 *
5 * Copyright (C) 1996 Free Software Foundation, Inc.
6 * Copyright (C) 1996-2002 LessTif Development Team
7 *
8 * This file is part of the GNU LessTif Library.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 **/
25
26 #include "LTTconfig.h"
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include <X11/IntrinsicP.h>
33 #include <X11/StringDefs.h>
34 #include <X11/keysym.h>
35 #include <X11/Core.h>
36
37 #define LIB_LTTEST
38 #include "Test.h"
39
40 /* ************** */
41
42 int GlobalErrors = 0;
43
44 /* local prototypes */
45 static void Initialize(Widget w);
46 static void Delay(Widget w);
47 static void Exit(Widget w);
48 static void Popup(Widget w, Boolean *mapped, XEvent *event);
49 static void TimeOut(Boolean *mapped);
50 static void LessTifTestPrintEvent(Widget w, XEvent *event);
51 static void LessTifTestProcessEvent(Widget w);
52
53 typedef struct
54 {
55 Boolean autoExit;
56 int exitDelay;
57 int geometrySlop;
58 Boolean printEvents;
59 String dumpOnFailureFile;
60 } AppResources_t, *AppResourcesPtr;
61 static AppResources_t AppResources;
62
63 static XtResource resources[] =
64 {
65 {"autoExit", "AutoExit", XtRBoolean, sizeof(Boolean), XtOffset(AppResourcesPtr, autoExit), XtRImmediate, (void *)False},
66 {"exitDelay", "ExitDelay", XtRInt, sizeof(int), XtOffset(AppResourcesPtr, exitDelay), XtRImmediate, (void *)0},
67 {"geometrySlop", "GeometrySlop", XtRInt, sizeof(int), XtOffset(AppResourcesPtr, geometrySlop), XtRImmediate, (void *)0},
68 {"printEvents", "PrintEvents", XtRBoolean, sizeof(Boolean), XtOffset(AppResourcesPtr, printEvents), XtRImmediate, (void *)False},
69 {"dumpFile", "DumpFile", XtRString, sizeof(String), XtOffset(AppResourcesPtr, dumpOnFailureFile), XtRImmediate, (void *)NULL},
70 };
71
72 /* ************** */
73
74 extern const char *
XdbGeometryResult2String(XtGeometryResult r)75 XdbGeometryResult2String(XtGeometryResult r)
76 {
77 switch (r)
78 {
79 case XtGeometryYes:
80 return "Yes";
81
82 case XtGeometryNo:
83 return "No";
84
85 case XtGeometryAlmost:
86 return "Almost";
87
88 case XtGeometryDone:
89 return "Done";
90
91 default:
92 return "(invalid geometry result)";
93 }
94 }
95
96 /* ************** */
97
98 extern const char *
XdbWidgetGeometry2String(XtWidgetGeometry * g)99 XdbWidgetGeometry2String(XtWidgetGeometry *g)
100 {
101 static char o1[128], o2[128], b[20], *out = NULL;
102 int i;
103
104 if (g == NULL)
105 {
106 return "NULL_GEOMETRY";
107 }
108
109 if (g->request_mode == 0)
110 {
111 return "GEOMETRY_NO_FIELDS";
112 }
113
114 /* Some magic to ensure you can call this sucker twice in one C function call */
115 if (out == &o1[0])
116 {
117 out = &o2[0];
118 }
119 else
120 {
121 out = &o1[0];
122 }
123
124 out[0] = '\0';
125 if (g->request_mode & CWX)
126 {
127 sprintf(b, "x %d ", g->x);
128 strcat(out, b);
129 }
130 if (g->request_mode & CWY)
131 {
132 sprintf(b, "y %d ", g->y);
133 strcat(out, b);
134 }
135 if (g->request_mode & CWWidth)
136 {
137 sprintf(b, "w %d ", g->width);
138 strcat(out, b);
139 }
140 if (g->request_mode & CWHeight)
141 {
142 sprintf(b, "h %d ", g->height);
143 strcat(out, b);
144 }
145 if (g->request_mode & CWBorderWidth)
146 {
147 sprintf(b, "bw %d ", g->border_width);
148 strcat(out, b);
149 }
150
151 for (i = 0; out[i]; i++)
152 {
153 }
154
155 if (i > 0 && out[i - 1] == ' ')
156 {
157 out[i - 1] = '\0';
158 }
159
160 return out;
161 }
162
163
164 extern const char *
XdbBoolean2String(int b)165 XdbBoolean2String(int b)
166 {
167 if (b)
168 {
169 return "True";
170 } else
171 {
172 return "False";
173 }
174 }
175
176
177 /* ************** */
178
179 static void
Initialize(Widget w)180 Initialize(Widget w)
181 {
182 static Boolean inited = False;
183
184 if (!inited)
185 {
186 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
187
188 XtGetApplicationResources(w,
189 &AppResources,
190 resources, XtNumber(resources),
191 NULL, 0);
192 XSynchronize(display, True);
193 inited = True;
194 }
195 }
196
197 /* ************** */
198
199 extern int
LessTifTestGetSlop(Widget w)200 LessTifTestGetSlop(Widget w)
201 {
202 Initialize(w);
203 return (AppResources.geometrySlop);
204 }
205
206 /* ************** */
207
208 extern void
LessTifTestSetSlop(Widget w,int slop)209 LessTifTestSetSlop(Widget w, int slop)
210 {
211 Initialize(w);
212 AppResources.geometrySlop = slop;
213 }
214
215 /* ************** */
216
217 static void
Exit(Widget w)218 Exit(Widget w)
219 {
220 /* Display *display =
221 XtIsSubclass(w,coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
222 XtAppContext app_context=XtWidgetToApplicationContext(w); */
223
224 /* destroy application and reclaim memory */
225
226 /* works, but leaks memory */
227 XtDestroyWidget(w);
228 /* Adding this call causes a core dump in DeleteShellFromHookObj */
229 /* XtDestroyApplicationContext(app_context); */
230
231 /* XCloseDisplay(display); */
232
233 printf("exit status >%i<\n", GlobalErrors);
234 exit(GlobalErrors);
235 }
236
237 /* ************** */
238
239 static void
LessTifTestPrintEvent(Widget w,XEvent * event)240 LessTifTestPrintEvent(Widget w, XEvent *event)
241 {
242 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
243
244 switch (event->xany.type)
245 {
246 case KeyPress:
247 fprintf(stdout, "KeyPress\n");
248 break;
249 case KeyRelease:
250 fprintf(stdout, "KeyRelease\n");
251 break;
252 case ButtonPress:
253 fprintf(stdout, "ButtonPress %s %ld\n",
254 XtName(XtWindowToWidget(display, event->xany.window)),
255 event->xany.serial
256 );
257 break;
258 case ButtonRelease:
259 fprintf(stdout, "ButtonRelease %s %ld\n",
260 XtName(XtWindowToWidget(display, event->xany.window)),
261 event->xany.serial
262 );
263 break;
264 case MotionNotify:
265 fprintf(stdout, "MotionNotify\n");
266 break;
267 case EnterNotify:
268 fprintf(stdout, "EnterNotify %s %ld\n",
269 XtName(XtWindowToWidget(display, event->xany.window)),
270 event->xany.serial
271 );
272 break;
273 case LeaveNotify:
274 fprintf(stdout, "LeaveNotify %s %ld\n",
275 XtName(XtWindowToWidget(display, event->xany.window)),
276 event->xany.serial
277 );
278 break;
279 case FocusIn:
280 fprintf(stdout, "FocusIn %s %ld\n",
281 XtName(XtWindowToWidget(display, event->xany.window)),
282 event->xany.serial
283 );
284 break;
285 case FocusOut:
286 fprintf(stdout, "FocusOut %s %ld\n",
287 XtName(XtWindowToWidget(display, event->xany.window)),
288 event->xany.serial
289 );
290 break;
291 case KeymapNotify:
292 fprintf(stdout, "KeymapNotify\n");
293 break;
294 case Expose:
295 fprintf(stdout, "Expose %s %ld\n",
296 XtName(XtWindowToWidget(display, event->xany.window)),
297 event->xany.serial
298 );
299 break;
300 case GraphicsExpose:
301 fprintf(stdout, "GraphicsExpose\n");
302 break;
303 case NoExpose:
304 fprintf(stdout, "NoExpose\n");
305 break;
306 case VisibilityNotify:
307 fprintf(stdout, "VisibilityNotify\n");
308 break;
309 case CreateNotify:
310 fprintf(stdout, "CreateNotify\n");
311 break;
312 case DestroyNotify:
313 fprintf(stdout, "DestroyNotify\n");
314 break;
315 case UnmapNotify:
316 fprintf(stdout, "UnmapNotify %s %ld\n",
317 XtName(XtWindowToWidget(display, event->xany.window)),
318 event->xany.serial
319 );
320 break;
321 case MapNotify:
322 fprintf(stdout, "MapNotify %s %ld\n",
323 XtName(XtWindowToWidget(display, event->xany.window)),
324 event->xany.serial
325 );
326 break;
327 case MapRequest:
328 fprintf(stdout, "MapRequest\n");
329 break;
330 case ReparentNotify:
331 fprintf(stdout, "ReparentNotify\n");
332 break;
333 case ConfigureNotify:
334 fprintf(stdout, "ConfigureNotify %s %ld\n",
335 XtName(XtWindowToWidget(display, event->xany.window)),
336 event->xany.serial
337 );
338 break;
339 case ConfigureRequest:
340 fprintf(stdout, "ConfigureRequest\n");
341 break;
342 case GravityNotify:
343 fprintf(stdout, "GravityNotify\n");
344 break;
345 case ResizeRequest:
346 fprintf(stdout, "ResizeRequest\n");
347 break;
348 case CirculateNotify:
349 fprintf(stdout, "CirculateNotify\n");
350 break;
351 case CirculateRequest:
352 fprintf(stdout, "CirculateRequest\n");
353 break;
354 case PropertyNotify:
355 fprintf(stdout, "PropertyNotify\n");
356 break;
357 case SelectionClear:
358 fprintf(stdout, "SelectionClear\n");
359 break;
360 case SelectionRequest:
361 fprintf(stdout, "SelectionRequest\n");
362 break;
363 case SelectionNotify:
364 fprintf(stdout, "SelectionNotify\n");
365 break;
366 case ColormapNotify:
367 fprintf(stdout, "ColormapNotify\n");
368 break;
369 case ClientMessage:
370 fprintf(stdout, "ClientMessage\n");
371 break;
372 case MappingNotify:
373 fprintf(stdout, "MappingNotify\n");
374 break;
375 case LASTEvent:
376 fprintf(stdout, "LASTEvent\n");
377 break;
378
379 default:
380 fprintf(stdout, "Unknown event\n");
381 break;
382 }
383 }
384
385 /* ************** */
386
387 static void
LessTifTestProcessEvent(Widget w)388 LessTifTestProcessEvent(Widget w)
389 {
390 XEvent event;
391
392 if (XtIMXEvent == XtAppPending(XtWidgetToApplicationContext(w)))
393 {
394 XtAppNextEvent(XtWidgetToApplicationContext(w), &event);
395 if (AppResources.printEvents)
396 {
397 LessTifTestPrintEvent(w, &event);
398 }
399 if (XtDispatchEvent(&event))
400 {
401 }
402 else
403 {
404 if (AppResources.printEvents)
405 {
406 printf("\tNot Dispatched\n");
407 }
408 }
409 }
410 else
411 {
412 XtAppProcessEvent(XtWidgetToApplicationContext(w), XtIMTimer | XtIMAlternateInput);
413 }
414 }
415
416 /* ************** */
417
418 static void
Popup(Widget w,Boolean * mapped,XEvent * event)419 Popup(Widget w, Boolean *mapped, XEvent *event)
420 {
421 if (event->type == MapNotify)
422 {
423 *mapped = True;
424 }
425 }
426
427 /* ************** */
428
429 static void
TimeOut(Boolean * mapped)430 TimeOut(Boolean *mapped)
431 {
432 *mapped = True;
433 }
434
435 /* ************** */
436
437 extern void
LessTifTestDelay(Widget w,unsigned long interval)438 LessTifTestDelay(Widget w, unsigned long interval)
439 {
440 Boolean mapped = False;
441 XtAppContext app_context=XtWidgetToApplicationContext(w);
442
443 XtAppAddTimeOut(app_context, interval,
444 (XtTimerCallbackProc)TimeOut, (XtPointer)&mapped);
445 while (!mapped)
446 {
447 XtAppProcessEvent(app_context, XtIMTimer);
448 }
449 }
450
451 /* ************** */
452
453 static void
Delay(Widget w)454 Delay(Widget w)
455 {
456 LessTifTestDelay(w, AppResources.exitDelay);
457 }
458
459 /* ************** */
460
461 extern void
LessTifTestFlushEvents(Widget w)462 LessTifTestFlushEvents(Widget w)
463 {
464 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
465
466 XSync(display, False);
467 while (XtAppPending(XtWidgetToApplicationContext(w)))
468 {
469 LessTifTestProcessEvent(w);
470 XFlush(display);
471 }
472 Delay(w);
473 }
474
475 /* ************** */
476
477 extern void
LessTifTestPrintEvents(Widget w,Boolean flag)478 LessTifTestPrintEvents(Widget w, Boolean flag)
479 {
480 LessTifTestFlushEvents(w);
481 AppResources.printEvents = flag;
482 }
483
484 /* ************** */
485
486 extern int
LessTifTestResizeWidget(Widget w,Dimension wt,Dimension ht)487 LessTifTestResizeWidget(Widget w, Dimension wt, Dimension ht)
488 {
489 Dimension bw;
490
491 Initialize(w);
492 XtVaGetValues(w,
493 XtNborderWidth, &bw,
494 NULL);
495 XtResizeWidget(w, wt, ht, bw);
496 LessTifTestFlushEvents(w);
497 return (0);
498 }
499
500 /* ************** */
501
502 extern int
LessTifTestWaitForIt(Widget w)503 LessTifTestWaitForIt(Widget w)
504 {
505 XWindowAttributes window_attributes;
506 Boolean mapped = False;
507 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
508 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
509
510 Initialize(w);
511 XGetWindowAttributes(display, window, &window_attributes);
512 if (window_attributes.map_state == IsUnmapped)
513 {
514
515 XtAddEventHandler(w, StructureNotifyMask, False,
516 (XtEventHandler)Popup, (XtPointer)&mapped);
517 XSync(display, False);
518 while (!mapped || XtAppPending(XtWidgetToApplicationContext(w)))
519 {
520 XtAppProcessEvent(XtWidgetToApplicationContext(w), XtIMAll);
521 XFlush(display);
522 }
523 XtRemoveEventHandler(w, StructureNotifyMask, False,
524 (XtEventHandler)Popup, (XtPointer)&mapped);
525 }
526 Delay(w);
527 return (0);
528 }
529
530 /* ************** */
531
532 extern int
LessTifTestMainLoop(Widget w)533 LessTifTestMainLoop(Widget w)
534 {
535 Initialize(w);
536 if (!AppResources.autoExit)
537 {
538 XtAppMainLoop(XtWidgetToApplicationContext(w));
539 }
540 else
541 {
542 LessTifTestWaitForIt(w);
543 Delay(w);
544 if (AppResources.dumpOnFailureFile && GlobalErrors)
545 {
546 String cmd;
547 String format = "xwd -id 0x%x | xwdtopnm | ppmtogif -interlace >%s";
548
549 cmd = XtMalloc(strlen(AppResources.dumpOnFailureFile) + strlen(format) + 20);
550 sprintf(cmd, format, XtWindow(w), AppResources.dumpOnFailureFile);
551 system(cmd);
552 XtFree(cmd);
553 }
554 Exit(w);
555 }
556 return (0);
557 }
558
559 /* ************** */
560
561 extern void
LessTifTestWarpPointerAbove(Widget w)562 LessTifTestWarpPointerAbove(Widget w)
563 {
564 Dimension width, height;
565 Position x, y;
566 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
567 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
568
569 XtVaGetValues(w,
570 XtNwidth, &width,
571 XtNheight, &height,
572 XtNx, &x,
573 XtNy, &y,
574 NULL);
575 if (XtIsSubclass(w, coreWidgetClass))
576 {
577 x = y = 0;
578 }
579 XWarpPointer(display, None, window, 0, 0, 0, 0, x + (width / 2), y - 1);
580 LessTifTestFlushEvents(w);
581 Delay(w);
582 }
583
584 /* ************** */
585
586 extern void
LessTifTestWarpPointer(Widget w)587 LessTifTestWarpPointer(Widget w)
588 {
589 Dimension width, height;
590 Position x, y;
591 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
592 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
593
594 XtVaGetValues(w,
595 XtNwidth, &width,
596 XtNheight, &height,
597 XtNx, &x,
598 XtNy, &y,
599 NULL);
600 if (XtIsSubclass(w, coreWidgetClass))
601 {
602 x = y = 0;
603 }
604 XWarpPointer(display, None, window, 0, 0, 0, 0, x + (width / 2), y + (height / 2));
605 LessTifTestFlushEvents(w);
606 Delay(w);
607 }
608
609 /* ************** */
610
611 extern void
LessTifTestKeyRelease(Widget w,KeySym keysym,unsigned int state)612 LessTifTestKeyRelease(Widget w, KeySym keysym, unsigned int state)
613 {
614 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
615 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
616 XKeyEvent key_event =
617 {
618 KeyRelease,
619 0,
620 False,
621 NULL, /* display, */
622 None, /* window, */
623 None, /* root, */
624 None, /* subwindow, */
625 CurrentTime,
626 0, 0,
627 0, 0,
628 0,
629 0x09,
630 True
631 };
632 XEvent *event;
633 unsigned int keys_buttons;
634
635 key_event.keycode = XKeysymToKeycode(display, keysym);
636 key_event.display=display;
637 key_event.state=state;
638 key_event.window=key_event.root=key_event.subwindow=window;
639 LessTifTestWarpPointer(w);
640 XQueryPointer(display, window,
641 &key_event.root,
642 &key_event.subwindow,
643 &key_event.x_root, &key_event.y_root,
644 &key_event.x, &key_event.y,
645 &keys_buttons);
646 event = (XEvent*)&key_event;
647 event->xany.serial = NextRequest(display);
648 event->xbutton.time = XtLastTimestampProcessed(display);
649 LessTifTestDelay(w, 200);
650 XSendEvent(display, key_event.window, True, KeyReleaseMask, event);
651 LessTifTestFlushEvents(w);
652 Delay(w);
653 }
654
655 /* ************** */
656
657 extern void
LessTifTestKeyPress(Widget w,KeySym keysym,unsigned int state)658 LessTifTestKeyPress(Widget w, KeySym keysym, unsigned int state)
659 {
660 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
661 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
662 XKeyEvent key_event =
663 {
664 KeyPress,
665 0,
666 False,
667 NULL, /* display, */
668 None, /* window, */
669 None, /* root, */
670 None, /* subwindow, */
671 CurrentTime,
672 0, 0,
673 0, 0,
674 0,
675 0x09,
676 True
677 };
678 XEvent *event;
679 unsigned int keys_buttons;
680
681 key_event.keycode = XKeysymToKeycode(display, keysym);
682 key_event.display=display;
683 key_event.state=state;
684 key_event.window=key_event.root=key_event.subwindow=window;
685 LessTifTestWarpPointer(w);
686 XQueryPointer(display, window,
687 &key_event.root,
688 &key_event.subwindow,
689 &key_event.x_root, &key_event.y_root,
690 &key_event.x, &key_event.y,
691 &keys_buttons);
692 event = (XEvent*)&key_event;
693 event->xany.serial = NextRequest(display);
694 event->xbutton.time = XtLastTimestampProcessed(display);
695 LessTifTestDelay(w, 200);
696 XSendEvent(display, InputFocus, True, KeyPressMask, event);
697 LessTifTestFlushEvents(w);
698 Delay(w);
699 }
700
701 /* ************** */
702
703 extern void
LessTifTestKeysym(Widget w,KeySym keysym)704 LessTifTestKeysym(Widget w, KeySym keysym)
705 {
706 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
707 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
708 XKeyEvent key_event =
709 {
710 KeyPress,
711 0,
712 False,
713 NULL, /* display, */
714 None, /* window, */
715 None, /* root, */
716 None, /* subwindow, */
717 CurrentTime,
718 0, 0,
719 0, 0,
720 0,
721 0x09,
722 True
723 };
724 XEvent *event;
725 unsigned int keys_buttons;
726
727 key_event.keycode = XKeysymToKeycode(display, keysym);
728 key_event.display=display;
729 key_event.window=key_event.root=key_event.subwindow=window;
730 LessTifTestWarpPointer(w);
731 XQueryPointer(display, window,
732 &key_event.root,
733 &key_event.subwindow,
734 &key_event.x_root, &key_event.y_root,
735 &key_event.x, &key_event.y,
736 &keys_buttons);
737 event = (XEvent*)&key_event;
738 event->xany.serial = NextRequest(display);
739 event->xbutton.time = XtLastTimestampProcessed(display);
740 LessTifTestDelay(w, 200);
741 XSendEvent(display, InputFocus, True, KeyPressMask, event);
742 key_event.type = KeyRelease;
743 key_event.window = XtWindow(XtParent(w));
744 XSendEvent(display, key_event.window, True, KeyReleaseMask, event);
745 LessTifTestFlushEvents(w);
746 Delay(w);
747 }
748
749 /* ************** */
750
751 extern void
LessTifTestEsc(Widget w)752 LessTifTestEsc(Widget w)
753 {
754 LessTifTestKeysym(w, XK_Escape);
755 }
756
757 /* ************** */
758
759 extern void
LessTifTestBtnDown(Widget w,int button)760 LessTifTestBtnDown(Widget w, int button)
761 {
762 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
763 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
764 XButtonEvent button_event =
765 {
766 ButtonPress,
767 0,
768 False,
769 NULL, /* display, */
770 None, /* window, */
771 None, /* window, */
772 None, /* window, */
773 CurrentTime,
774 0, 0,
775 0, 0,
776 0,
777 Button1,
778 True
779 };
780 XEvent *event;
781 unsigned int keys_buttons;
782
783 button_event.button = button;
784 button_event.display=display;
785 button_event.window=button_event.root=button_event.subwindow=window;
786 LessTifTestWarpPointer(w);
787 XQueryPointer(display, window,
788 &button_event.root,
789 &button_event.subwindow,
790 &button_event.x_root, &button_event.y_root,
791 &button_event.x, &button_event.y,
792 &keys_buttons);
793 event = (XEvent*)&button_event;
794 event->xany.serial = NextRequest(display);
795 event->xbutton.time = XtLastTimestampProcessed(display);
796 LessTifTestDelay(w, 200);
797 XSendEvent(display, PointerWindow, True, ButtonPressMask, event);
798 LessTifTestFlushEvents(w);
799 Delay(w);
800 }
801
802 /* ************** */
803
804 extern void
LessTifTestBtnUp(Widget w,int button)805 LessTifTestBtnUp(Widget w, int button)
806 {
807 Display *display = XtIsSubclass(w, coreWidgetClass) ? XtDisplay(w) : XtDisplay(XtParent(w));
808 Window window = XtIsSubclass(w, coreWidgetClass) ? XtWindow(w) : XtWindow(XtParent(w));
809 XButtonEvent button_event =
810 {
811 ButtonRelease,
812 0,
813 False,
814 NULL, /* display, */
815 None, /* window, */
816 None, /* window, */
817 None, /* window, */
818 CurrentTime,
819 0, 0,
820 0, 0,
821 Button1Mask,
822 Button1,
823 True
824 };
825 XEvent *event;
826 unsigned int keys_buttons;
827
828 switch (button)
829 {
830 case 1:
831 button_event.state = Button1Mask;
832 break;
833 case 2:
834 button_event.state = Button2Mask;
835 break;
836 case 3:
837 button_event.state = Button3Mask;
838 break;
839 default:
840 button_event.state = 0;
841 break;
842 }
843 button_event.button = button;
844 button_event.display=display;
845 button_event.window=button_event.root=button_event.subwindow=window;
846 LessTifTestWarpPointer(w);
847 XQueryPointer(display, window,
848 &button_event.root,
849 &button_event.subwindow,
850 &button_event.x_root, &button_event.y_root,
851 &button_event.x, &button_event.y,
852 &keys_buttons);
853 event = (XEvent*)&button_event;
854 event->xany.serial = NextRequest(display);
855 event->xbutton.time = XtLastTimestampProcessed(display);
856 LessTifTestDelay(w, 200);
857 XSendEvent(display, PointerWindow, True, ButtonReleaseMask, event);
858 LessTifTestFlushEvents(w);
859 Delay(w);
860 }
861
862 /* ************** */
863
864 extern void
LessTifTestBtn1Down(Widget w)865 LessTifTestBtn1Down(Widget w)
866 {
867 LessTifTestBtnDown(w, 1);
868 }
869
870 /* ************** */
871
872 extern void
LessTifTestBtn1Up(Widget w)873 LessTifTestBtn1Up(Widget w)
874 {
875 LessTifTestBtnUp(w, 1);
876 }
877
878 /* ************** */
879
880 extern void
LessTifTestBtn2Down(Widget w)881 LessTifTestBtn2Down(Widget w)
882 {
883 LessTifTestBtnDown(w, 2);
884 }
885
886 /* ************** */
887
888 extern void
LessTifTestBtn2Up(Widget w)889 LessTifTestBtn2Up(Widget w)
890 {
891 LessTifTestBtnUp(w, 2);
892 }
893
894 /* ************** */
895
896 extern void
LessTifTestBtn3Down(Widget w)897 LessTifTestBtn3Down(Widget w)
898 {
899 LessTifTestBtnDown(w, 3);
900 }
901
902 /* ************** */
903
904 extern void
LessTifTestBtn3Up(Widget w)905 LessTifTestBtn3Up(Widget w)
906 {
907 LessTifTestBtnUp(w, 3);
908 }
909
910 /* ************** */
911
912 extern int
LessTifTestPushButton(Widget w)913 LessTifTestPushButton(Widget w)
914 {
915 Initialize(w);
916 if (XtIsSubclass(w, coreWidgetClass))
917 {
918 XtCallActionProc(w, "ArmAndActivate", NULL, NULL, 0);
919 }
920 else
921 {
922 LessTifTestBtn1Down(XtParent(w));
923 LessTifTestBtn1Up(XtParent(w));
924 }
925 LessTifTestFlushEvents(w);
926 return (0);
927 }
928
929 /* ************** */
930