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