Skip to content

Instantly share code, notes, and snippets.

@hackorama
Created September 6, 2014 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hackorama/6f307d6b116c0f3a3c49 to your computer and use it in GitHub Desktop.
Save hackorama/6f307d6b116c0f3a3c49 to your computer and use it in GitHub Desktop.
Utilities for X/Motif debugging
/*
* xutil.h - X/Motif debugging
*
* Either include this file into your code ( #include "xutil.h" )
* or cut and paste the functions as rerquired, to your code
*
* Either use the provided callback and eventhandler template
* or call the functions directly.
*
* By default all verbose gets printed out to "stdout"
*
* kishan@hackorama.com www.hackorama.com November 2001
*
*/
#ifndef _XUTIL_H
#define _XUTIl_H
#include <stdio.h>
#include <Xm/Xm.h>
void utilHandler(Widget w, XtPointer data, XEvent *event);
void utilCB(Widget w, XtPointer client_data, XtPointer call_data);
void scanChildren( Widget w );
void processWidget( Widget w, int detail );
void fakeEvent( Widget w );
/* a widget callback template */
void utilCB(Widget w, XtPointer client_data, XtPointer call_data )
{
if( w != NULL )
scanChildren( w );
}
/* an event handler template */
void utilHandler(Widget w, XtPointer data, XEvent *event)
{
if( w != NULL )
scanChildren( w );
}
/* recursive scan of all hierarchical children of a widget */
/*
* requires the function "processWidget" for printing
* out the widget details, else process the widget yourself
*/
void scanChildren(Widget w )
{
WidgetList children = NULL;
Cardinal num_children = 0 ;
int i = 0 , j = 0;
static int level = 0 ;
FILE *fp = stdout ;
if( fp == NULL ){ fp = fopen( "/tmp/debug.txt" , "r+" ); }
if( w == NULL ){
if(fp) { fprintf( fp, "\n ERROR: NULL Widget\n" ); fflush(fp); }
return ;
}
/* process the top */
if( level == 0 )
processWidget( w , 0 );
/* get the children */
XtVaGetValues( w,
XmNchildren, &children,
XmNnumChildren, &num_children,
NULL);
/* this is a leaf */
if( num_children == 0 ){
if(fp) { fprintf( fp, " [*]\n" ); fflush(fp); }
}else{
if(fp) { fprintf( fp, "\n" ); fflush(fp); }
}
/* process the children */
for( i = 0 ; i < num_children ; i++ ){
if(fp) {
/* spacing for readability */
for( j = 1 ; j <= level ; j++ )
fprintf( fp, " " );
fprintf( fp, "%2d ", i+1 );
fflush(fp);
}
/* use processWidget or process yourself like:
* if(fp) { fprintf( fp, "%s", XtName(children[i]) ); fflush(fp); }
*/
processWidget( children[i], 0 );
level++; /* push */
scanChildren( children[i] );
level--; /* pop */
}
}
/* prints the properties of a widget */
/* the second variable "detail" decides how much detail of the
* widget will be printed out "0" detail means only * the name
* will be printed , with higher values more details are printed.
*/
void processWidget(Widget w , int detail )
{
Widget focus_widget = NULL;
Widget parent_widget = NULL;
Window window = NULL;
int x = 0, y = 0, height = 0, width = 0;
FILE *fp = stdout ;
if( fp == NULL ){ fp = fopen( "/tmp/debug.txt" , "r+" ); }
/* force the details */
detail = 5;
if( w == NULL ){
if(fp) { fprintf( fp, "\n ERROR [ processWidget ] : NULL widget \n" ); fflush(fp); }
return ;
}
/* 1. name */
if(fp) { fprintf( fp, " %s ", XtName(w) ); fflush(fp); }
detail--; if( detail < 0 ) return;
/* 2. parent */
parent_widget = XtParent( w );
if( parent_widget != NULL ){
if(fp) { fprintf( fp, "| p-%s " , XtName(parent_widget) ); fflush(fp); }
} else {
if(fp) { fprintf( fp, "| p-NULL " ); fflush(fp); }
}
detail--; if( detail < 0 ) return;
/* 3. geometry */
XtVaGetValues( w,
XtNx, &x,
XtNy, &y,
XtNheight, &height,
XtNwidth, &width,
NULL);
if(fp) { fprintf( fp, "| x=%d y=%d w=%d h=%d ", x, y, width, height ); fflush(fp); }
detail--; if( detail < 0 ) return;
/* 4. focus */
focus_widget = XmGetFocusWidget( w );
if( focus_widget != NULL ){
if(fp) { fprintf( fp, "| f-%s ", XtName(focus_widget) ); fflush(fp); }
} else {
if(fp) { fprintf( fp, "| f-NULL " ); fflush(fp); }
}
detail--; if( detail < 0 ) return;
}
/* send a synthesised event */
void fakeEvent(Widget w )
{
FILE *fp = stdout ;
if( fp == NULL ){ fp = fopen( "/tmp/debug.txt" , "r+" ); }
XButtonEvent myevent;
Position x = 1, y = 1;
/* XtTranslateCoords( w, 5, 5, &x, &y ); */
myevent.display = XtDisplay(w) ;
myevent.window = XtWindow(w) ;
myevent.root = DefaultRootWindow(XtDisplay(w));
myevent.time = CurrentTime ;
myevent.x = x ;
myevent.y = y ;
myevent.same_screen = TRUE ;
myevent.type = ButtonPress ;
myevent.button = Button1 ;
myevent.send_event = TRUE ;
/* myevent.window = DefaultRootWindow(XtDisplay(w)); */
/* myevent.subwindow = None ; */
/* myevent.state = Button1Mask ; */
/* myevent.x_root = x ; */
/* myevent.y_root = y ;*/
/* XSetInputFocus( XtDisplay(w), myevent.window, RevertToParent, CurrentTime ); */
/* XWarpPointer(XtDisplay(w), None, XtWindow(w) , x, y, x, y, x, y); */
if ( XtDispatchEvent( (XEvent*) &myevent ) == FALSE ){
if(fp) { fprintf( fp , "failed to send\n" ); fflush(fp); }
}
if ( XSendEvent(myevent.display, myevent.window, FALSE,
ButtonPressMask, (XEvent *) &myevent) == 0 ){
if(fp) { fprintf( fp , "failed to send\n" ); fflush(fp); }
}
XFlush( XtDisplay(w) );
XSync( XtDisplay(w), False );
}
#endif /* _XUTIL_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment