home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1680 / xse.c < prev   
Encoding:
C/C++ Source or Header  |  1990-12-28  |  9.2 KB  |  383 lines

  1. /*
  2.  *    xse - an interface to XSendEvent()
  3.  *
  4.  *    George Ferguson, ferguson@cs.rochester.edu,  1 Jun 1990.
  5.  *
  6.  *    $Id: xse.c,v 1.4 90/08/15 11:32:30 ferguson Exp $
  7.  *
  8.  */
  9. static char *rcsid = "$Id: xse.c,v 1.4 90/08/15 11:32:30 ferguson Exp $";
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <X11/Intrinsic.h>
  13. #include <X11/StringDefs.h>
  14. #include <X11/Shell.h>    
  15. #include <X11/Xaw/Form.h>    
  16. #include <X11/Xaw/Command.h>    
  17. #include <X11/Xaw/Cardinals.h>    
  18. #include "app-resources.h"
  19. #include "translate.h"
  20. #include "parse.h"
  21.  
  22. /*    -    -    -    -    -    -    -    -    */
  23. /*
  24.  * Functions defined in this file
  25.  */
  26. static void initGraphics(),initWidgets();
  27. static void quit(),send();
  28. static void parseAndSendEvents(), fail();
  29. static Window windowFromString(), Window_With_Name(), Select_Window();
  30.  
  31. /*
  32.  * Action binding table
  33.  */
  34. static XtActionsRec cmdActionsTable[] = {
  35.     { "xse-quit", quit },
  36.     { "xse-send", send },
  37. };
  38.  
  39. /*
  40.  * Global graphics data, needed in parse.c
  41.  */
  42. Display *display;
  43. Window root;
  44.  
  45. /*
  46.  * Global widget data
  47.  */
  48. static XtAppContext app_con;
  49. static Widget toplevel;
  50.  
  51. /*
  52.  * The application resources struct
  53.  */
  54. static AppResources appResources;
  55.  
  56. /*
  57.  *    Non-widget resources obtained from resource manager
  58.  */
  59. static XtResource resources[] = {
  60.     { "widgets", "Widgets", XtRString, sizeof(String),
  61.       XtOffset(AppResources *,widgets), XtRImmediate, NULL },
  62.     { "window", "Window", XtRString, sizeof(String),
  63.       XtOffset(AppResources *,window), XtRImmediate, "InputFocus" },
  64.     { "revision", "Revision", XtRString, sizeof(String),
  65.       XtOffset(AppResources *,revision), XtRImmediate, "" },
  66. };
  67.  
  68. /*
  69.  *    Non-widget resources set on command line.
  70.  */
  71. static XrmOptionDescRec options[] = {
  72.     { "-window",    "window",    XrmoptionSepArg,    "InputFocus"},
  73. };
  74.  
  75. /*
  76.  *    Widget and non-widget resources if the application defaults
  77.  *    file can't be found.
  78.  *    [ Generated automatically from Xse.ad. ]
  79.  */
  80. static String fallbackResources[] = {
  81. #include "Xse.ad.h"
  82.     NULL
  83. };
  84.  
  85. /*    -    -    -    -    -    -    -    -    */
  86. /*
  87.  * main() : Initialize the graphics, then if args remain send them directly
  88.  *        (ie. we are in command mode) otherwise initialize the widgets
  89.  *        (ie. we are in widget mode) and call XtAppMainLoop().
  90.  */
  91. main(argc, argv)
  92. int argc;
  93. char **argv;
  94. {
  95.     Window win;
  96.  
  97.     initGraphics(&argc,argv);
  98.     argv += 1;
  99.     argc -= 1;
  100.     if (argc > 0) {
  101.     win = windowFromString(appResources.window);
  102.     while (argc--)
  103.         parseAndSendEvents(win,*argv++);
  104.     XtDestroyApplicationContext(app_con);
  105.     exit(0);
  106.     }
  107.     initWidgets();
  108.     XtRealizeWidget(toplevel);
  109.     XtAppMainLoop(app_con);
  110. }
  111.  
  112. /*
  113.  * initGraphics() : Initialize the application context and set global
  114.  *            graphics variables.
  115.  */
  116. static void
  117. initGraphics(argcp,argv)
  118. int *argcp;
  119. char **argv;
  120. {
  121.     toplevel = XtAppInitialize(&app_con, "Xse",
  122.                    options, XtNumber(options),
  123.                    argcp,argv,fallbackResources,NULL,ZERO);
  124.     XtGetApplicationResources(toplevel,(XtPointer)&appResources,
  125.                               resources,XtNumber(resources),NULL,ZERO);
  126.     display = XtDisplay(toplevel);
  127.     root = RootWindowOfScreen(XtScreen(toplevel));
  128.     XtAppAddActions(app_con,cmdActionsTable,XtNumber(cmdActionsTable));
  129. }
  130.  
  131. /*
  132.  * initWidgets() : Parse the widgets resource and create whatever widgets
  133.  *           specified in it as children of toplevel (or sub-children,
  134.  *           etc.).
  135.  */
  136. static void
  137. initWidgets()
  138. {
  139.     char name[32],class[32],parent[32];
  140.     char *s;
  141.     int i;
  142.     Boolean isShell;
  143.     WidgetClass wc;
  144.     Widget w;
  145.  
  146.     if ((s=appResources.widgets) == NULL)
  147.     fail("no widgets specified!\n","");
  148.     while (*s) {
  149.         while (isspace(*s))
  150.             s += 1;
  151.     if (!*s)
  152.         break;
  153.         i = 0;
  154.         while (*s && !isspace(*s))
  155.             class[i++] = *s++;
  156.         class[i] = '\0';
  157.         while (isspace(*s))
  158.             s += 1;
  159.         i = 0;
  160.         while (*s && !isspace(*s))
  161.             name[i++] = *s++;
  162.         name[i] = '\0';
  163.         while (isspace(*s))
  164.             s += 1;
  165.         i = 0;
  166.         while (*s && !isspace(*s))
  167.             parent[i++] = *s++;
  168.         parent[i] = '\0';
  169.     isShell = False;
  170.         if ((wc=classNameToWidgetClass(class,&isShell)) == NULL)
  171.         fail("can't convert string \"%s\" to widgetClass\n",class);
  172.     if (strcmp(parent,"toplevel") == 0)
  173.         w = toplevel;
  174.     else if ((w=XtNameToWidget(toplevel,parent)) == NULL)
  175.         fail("can't convert string \"%s\" to widget\n",parent);
  176.     if (isShell)
  177.             w = XtCreatePopupShell(name,wc,w,NULL,ZERO);
  178.         else
  179.             w = XtCreateManagedWidget(name,wc,w,NULL,ZERO);
  180.     }
  181. }
  182.  
  183. /*    -    -    -    -    -    -    -    -    */
  184. /*
  185.  * windowFromString() : Convert a string to a Window, handling our special
  186.  *            cases of PointerWindow, InputFocus, or ClickWindow.
  187.  */
  188. static Window
  189. windowFromString(str)
  190. char *str;
  191. {
  192.     Window w;
  193.  
  194.     if (strcmp(str,"PointerWindow") == 0)
  195.     return(PointerWindow);
  196.     else if (strcmp(str,"InputFocus") == 0)
  197.     return(InputFocus);
  198.     else if (strcmp(str,"ClickWindow") == 0)
  199.     return(Select_Window(display));
  200.     else if ((w=Window_With_Name(display,root,str)) != NULL)
  201.     return(w);
  202.     else
  203.     return((Window)strtol(str,NULL,0));
  204. }
  205.  
  206. /*    -    -    -    -    -    -    -    -    */
  207. /* Action procedures */
  208.  
  209. /*
  210.  * quit() : Quit the tool.
  211.  */
  212. static void
  213. quit(w,event,params,num_params)
  214. Widget w;
  215. XEvent *event;
  216. String *params;
  217. Cardinal *num_params;
  218. {
  219.     XtDestroyApplicationContext(app_con);
  220.     exit(0);
  221. }
  222.  
  223. /*
  224.  * send() : With one argument, send the event sequence given by the first
  225.  *        argument to the default window. With two arguments, the first
  226.  *        is the window to send the event sequence given by the second
  227.  *        to.
  228.  */
  229. static void
  230. send(w,event,params,num_params)
  231. Widget w;
  232. XEvent *event;
  233. String *params;
  234. Cardinal *num_params;
  235. {
  236.     char *estr,*wstr;
  237.  
  238.     if (*num_params == ONE) {
  239.     wstr = appResources.window;
  240.         estr = params[0];
  241.     } else if (*num_params == TWO) {
  242.     wstr = params[0];
  243.         estr = params[1];
  244.     } else {
  245.     fprintf(stderr,"xse: too many arguments to xse-send()\n");
  246.         return;
  247.     }
  248.     parseAndSendEvents(windowFromString(wstr),estr);
  249. }
  250.  
  251. /*
  252.  * parseAndSendEvents() : Calls parseEventList() then dispatches the list
  253.  *              of returned events.
  254.  */
  255. static void
  256. parseAndSendEvents(window,str)
  257. Window window;
  258. char *str;
  259. {
  260.     char *s;
  261.     EventListPtr list = NULL;
  262.  
  263.     s = parseEventList(str,&list);
  264.     if (*s != '\0') {
  265.     fprintf("xse: garbage at end of event spec: \"%s\"\n",s);
  266.     return;
  267.     }
  268.     while (list != NULL) {
  269.     if (list->event.xany.type != -1) {
  270.         list->event.xany.display = display;
  271.         list->event.xany.window = window;
  272.         while (list->count-- != 0)
  273.         XSendEvent(display,window,True,0xfff,&(list->event));
  274.     }
  275.     list = list->next;
  276.     }
  277.     freeEventList(&list);
  278. }
  279.  
  280. /*    -    -    -    -    -    -    -    -    */
  281. /*
  282.  *    fail() : Print a message and die.
  283.  */
  284. static void
  285. fail(fmt,arg)
  286. char *fmt,*arg;
  287. {
  288.     fprintf(stderr,fmt,arg);
  289.     XtDestroyApplicationContext(app_con);
  290.     exit(1);
  291. }
  292.  
  293. /*    -    -    -    -    -    -    -    -    */
  294. /*    -    -    -    -    -    -    -    -    */
  295. /*
  296.  * [These functions are from the file "dsimple.c" used with xwininfo.]
  297.  *
  298.  * Written by Mark Lillibridge.   Last updated 7/1/87
  299.  *
  300.  * Send bugs, etc. to chariot@athena.mit.edu.
  301.  *
  302.  * Window_With_Name: routine to locate a window with a given name on a display.
  303.  *                   If no window with the given name is found, 0 is returned.
  304.  *                   If more than one window has the given name, the first
  305.  *                   one found will be returned.  Only top and its subwindows
  306.  *                   are looked at.  Normally, top should be the RootWindow.
  307.  */
  308. static Window
  309. Window_With_Name(dpy, top, name)
  310.      Display *dpy;
  311.      Window top;
  312.      char *name;
  313. {
  314.     Window *children, dummy;
  315.     unsigned int nchildren;
  316.     int i;
  317.     Window w=0;
  318.     char *window_name;
  319.  
  320.     if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
  321.       return(top);
  322.  
  323.     if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
  324.       return(0);
  325.  
  326.     for (i=0; i<nchildren; i++) {
  327.         w = Window_With_Name(dpy, children[i], name);
  328.         if (w)
  329.           break;
  330.     }
  331.     if (children) XFree ((char *)children);
  332.     return(w);
  333. }
  334.  
  335. /*
  336.  * Routine to let user select a window using the mouse
  337.  * gf: Doesn't need "screen" defined.
  338.  */
  339. #include <X11/cursorfont.h>
  340.  
  341. static Window
  342. Select_Window(dpy)
  343.       Display *dpy;
  344. {
  345.   static Cursor cursor = NULL;
  346.   Window target_win = None, root = DefaultRootWindow(dpy);
  347.   XEvent event;
  348.   int status;
  349.   int buttons = 0;
  350.  
  351.   if (cursor == NULL)
  352.     cursor = XCreateFontCursor(dpy, XC_crosshair);
  353.   /* Grab the pointer using target cursor, letting it room all over */
  354.   status = XGrabPointer(dpy, root, False,
  355.             ButtonPressMask|ButtonReleaseMask, GrabModeSync,
  356.             GrabModeAsync, root, cursor, CurrentTime);
  357.   if (status != GrabSuccess) {
  358.     fprintf(stderr,"xse: can't grab pointer");
  359.     return(None);
  360.   }
  361.   /* Let the user select a window... */
  362.   while ((target_win == None) || (buttons != 0)) {
  363.     /* allow one more event */
  364.     XAllowEvents(dpy, SyncPointer, CurrentTime);
  365.     XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
  366.     switch (event.type) {
  367.     case ButtonPress:
  368.       if (target_win == None) {
  369.     target_win = event.xbutton.subwindow; /* window selected */
  370.     if (target_win == None) target_win = root;
  371.       }
  372.       buttons++;
  373.       break;
  374.     case ButtonRelease:
  375.       if (buttons > 0) /* there may have been some down before we started */
  376.     buttons--;
  377.        break;
  378.     }
  379.   } 
  380.   XUngrabPointer(dpy, CurrentTime);      /* Done with pointer */
  381.   return(target_win);
  382. }
  383.