/* * 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 #include 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 */