Created
September 6, 2014 16:19
-
-
Save hackorama/6f307d6b116c0f3a3c49 to your computer and use it in GitHub Desktop.
Utilities for X/Motif debugging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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