home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xtolplcs / part01 < prev    next >
Encoding:
Text File  |  1993-04-27  |  52.2 KB  |  1,572 lines

  1. Newsgroups: comp.sources.x
  2. From: adam@iset.scan.mc.xerox.com (Adam Stein)
  3. Subject: v19i075:  Xtoolplaces - save current X desktop window information, Part01/03
  4. Message-ID: <csx-v19i075=Xtoolplaces.093059@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: ee6cdb13b3ce79f2936f441d464109f3
  6. Date: Tue, 6 Apr 1993 14:34:34 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: adam@iset.scan.mc.xerox.com (Adam Stein)
  10. Posting-number: Volume 19, Issue 75
  11. Archive-name: Xtoolplaces/part01
  12. Environment: X11, !mwm, !tvtwm
  13. Supersedes: Xtoolplaces: Volume 14, Issue 2-3
  14.  
  15. This is from the README file for xtoolplaces:
  16.  
  17.   This program will collect state information from any windows
  18.   currently running on an X desktop.  This information can then
  19.   be used to start X to return to the current desktop state.  This
  20.   is the X equivalent of Sunview's toolplaces program.
  21.  
  22. -------------
  23. #! /bin/sh
  24. # This is a shell archive.  Remove anything before this line, then feed it
  25. # into a shell via "sh file" or similar.  To overwrite existing files,
  26. # type "sh file -c".
  27. # Contents:  README Imakefile getargs.c getinfo.c is.c missing.c
  28. # Wrapped by chris@sparky on Tue Apr  6 09:15:54 1993
  29. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  30. echo If this archive is complete, you will see the following message:
  31. echo '          "shar: End of archive 1 (of 3)."'
  32. if test -f 'README' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'README'\"
  34. else
  35.   echo shar: Extracting \"'README'\" \(4615 characters\)
  36.   sed "s/^X//" >'README' <<'END_OF_FILE'
  37. XThis is the README file for xtoolplaces.
  38. X
  39. XAuthor:
  40. X
  41. X  Adam Stein (adam@iset.scan.mc.xerox.com)
  42. X
  43. XCopyright:
  44. X
  45. X  Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  46. X
  47. X  Permission to use,  copy,  modify  and  distribute  without
  48. X  charge this software, documentation, images, etc. is grant-
  49. X  ed, provided that this copyright and the author's  name  is
  50. X  retained.
  51. X
  52. X  A fee may be charged for this program ONLY to recover costs
  53. X  for distribution (i.e. media costs).  No profit can be made
  54. X  on this program.
  55. X
  56. X  The author assumes no responsibility for disasters (natural
  57. X  or otherwise) as a consequence of use of this software.
  58. X
  59. XDescription:
  60. X
  61. X  This program will collect state information from any windows
  62. X  currently running on an X desktop.  This information can then
  63. X  be used to start X to return to the current desktop state.  This
  64. X  is the X equivalent of Sunview's toolplaces program.
  65. X
  66. X  Xtoolplaces is currently at v1.3 patchlevel 3.  Don't worry if
  67. X  you never saw patchlevel 1, it never made it out.
  68. X
  69. X  This will most likely be the last release unless something major
  70. X  is wrong.
  71. X
  72. XInstallation:
  73. X
  74. X  This program has only been compiled and tested on BSD or BSD/SYS5
  75. X  mixed systems.  I have no idea what would have to be changed for
  76. X  a SYS5 only system (probably only index to strchr and that sort of
  77. X  stuff).
  78. X  
  79. X  This program can be compiled with gcc.  Commented out gcc lines have
  80. X  been added to Imakefile and Makefile.simple.  To use gcc instead of
  81. X  cc, comment/uncomment the appropriate lines in whichever dependency
  82. X  file you plan using for compiling.
  83. X
  84. X  To compile using imake use:
  85. X
  86. X        imake
  87. X
  88. X  and to install the program and man page use
  89. X
  90. X        imake install install.man
  91. X
  92. X  To compile using make instead, use:
  93. X
  94. X        make -f Makefile.simple
  95. X
  96. X  and to install the program and man page use
  97. X
  98. X        make -f Makefile.simple install
  99. X
  100. X
  101. XMethodology:
  102. X
  103. X  This program works by following these steps:
  104. X
  105. X  I.   Change cursor to a watch, grab the pointer so that the
  106. X       user can't change anything during execution, and ring
  107. X       the bell once to let the user know the program has started.
  108. X
  109. X  II.  Loop through each screen to save from:
  110. X
  111. X       a. Loop through each window in the tree to:
  112. X
  113. X          1. See if it's a window worth saving.  It has to meet
  114. X         four conditions:
  115. X
  116. X         a. it has WM_NAME set (so we know it's not a pop-up, etc)
  117. X
  118. X         b. it's a group leader or assume it's ok if group leader
  119. X            isn't set
  120. X
  121. X         c. it's parent is the root window
  122. X
  123. X         d. it has a WM_COMMAND property to save, is a console
  124. X        window or is on a list specified with the '-m' option
  125. X
  126. X          2. Tell window to update it's current state if it knows
  127. X         about the WM_SAVE_YOURSELF message.
  128. X  
  129. X          3. See if it either:  has a state to save (WM_COMMAND);
  130. X         is a console window or is on the missing applications
  131. X         list (-m option)
  132. X
  133. X      4. If window doesn't know how to save itself (doesn't
  134. X         understand WM_SAVE_YOURSELF), extract geometry
  135. X         information manually.
  136. X
  137. X          5. If console checking is enabled (-c), check to see if
  138. X         window is a console and write 'if ... fi' clause to
  139. X         only have it start up if X is starting on /dev/console.
  140. X
  141. X          6. Check to see if window is a remote application and
  142. X         put the appropriate remote command (default 'rsh -n') to
  143. X         start application.
  144. X
  145. X          7. Save current window state.
  146. X
  147. X          8. If add arguments is enabled (-a), check to see if this
  148. X         window applications has any arguments to add to it's
  149. X         command line.
  150. X
  151. X  III. Release pointer (which changes the cursor back to normal) and ring
  152. X       the bell twice to let the user know that the program is finished.
  153. X
  154. XBugs/Additions:
  155. X
  156. X  I would appreciate knowing about any bugs either found or
  157. X  fixed and any enhancements made.  I would like to keep a
  158. X  centralized version with the upgrades so that there aren't
  159. X  50 million versions posted to the net.  I can't make any
  160. X  guarantees to when bug fixes would be made (if any are
  161. X  found :-{), but I'll do my best.
  162. X
  163. X  I hope this program is of use to you, either in it's capacity or as simple
  164. X  example in X programming.
  165. X
  166. X  It is known that xtoolplaces won't work with the Motif window manager (mwm)
  167. X  or the virtual version of TWM (tvtwm).  Neither of these window managers
  168. X  seem to return the queried information correctly.
  169. X
  170. XAcknowledgements:
  171. X
  172. X  For v1.0
  173. X  --------
  174. X  I would like to thank my original beta testers, Donn Morrill and
  175. X  Bill Fuss for helping to make sure the first version of this  program
  176. X  worked and keeping me honest.
  177. X
  178. X  For v1.1 Beta -> present
  179. X  --------------------------
  180. X  See CHANGES file.
  181. END_OF_FILE
  182.   if test 4615 -ne `wc -c <'README'`; then
  183.     echo shar: \"'README'\" unpacked with wrong size!
  184.   fi
  185.   # end of 'README'
  186. fi
  187. if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  188.   echo shar: Will not clobber existing file \"'Imakefile'\"
  189. else
  190.   echo shar: Extracting \"'Imakefile'\" \(1397 characters\)
  191.   sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
  192. X# Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  193. X#
  194. X# Permission to use,  copy,  modify  and  distribute  without
  195. X# charge this software, documentation, images, etc. is grant-
  196. X# ed, provided that this copyright and the author's  name  is
  197. X# retained.
  198. X#
  199. X# A fee may be charged for this program ONLY to recover costs
  200. X# for distribution (i.e. media costs).  No profit can be made
  201. X# on this program.
  202. X#
  203. X# The author assumes no responsibility for disasters (natural
  204. X# or otherwise) as a consequence of use of this software.
  205. X#
  206. X# Adam Stein (adam@iset.scan.mc.xerox.com)
  207. X
  208. X# Name of program to build
  209. XTARGET=xtoolplaces
  210. X
  211. X# Name of resource file
  212. XRESOURCE=Xtoolplaces
  213. X
  214. X#Uncomment the next 2 lines if using gcc
  215. X#EXTRA_DEFINES=-traditional -fpcc-struct-return -c -O
  216. X#CC=gcc
  217. X
  218. XINCS=addon.h patchlevel.h xtoolplaces.h
  219. XSRCS=copyright.c adddisplay.c addon.c combine.c fix_command.c\
  220. X     getargs.c getgeom.c getinfo.c is.c make_list.c missing.c\
  221. X     strdup.c strstr.c xtoolplaces.c
  222. XOBJS=copyright.o adddisplay.o addon.o combine.o fix_command.o\
  223. X     getargs.o getgeom.o getinfo.o is.o make_list.o missing.o\
  224. X     strdup.o strstr.o xtoolplaces.o
  225. X
  226. XLOCAL_LIBRARIES = ${XLIB}
  227. X
  228. XComplexProgramTarget(${TARGET})
  229. X
  230. XInstallAppDefaults(${RESOURCE})
  231. X
  232. Xshar:
  233. X    shar -c -o ${TARGET} -l50 README CHANGES MANIFEST Imakefile \
  234. X    Makefile.simple ${RESOURCE}.ad xtoolplaces.man ${SRCS} ${INCS} \
  235. X    addon.sample missing.sample
  236. X
  237. END_OF_FILE
  238.   if test 1397 -ne `wc -c <'Imakefile'`; then
  239.     echo shar: \"'Imakefile'\" unpacked with wrong size!
  240.   fi
  241.   # end of 'Imakefile'
  242. fi
  243. if test -f 'getargs.c' -a "${1}" != "-c" ; then 
  244.   echo shar: Will not clobber existing file \"'getargs.c'\"
  245. else
  246.   echo shar: Extracting \"'getargs.c'\" \(13930 characters\)
  247.   sed "s/^X//" >'getargs.c' <<'END_OF_FILE'
  248. X/*Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  249. X
  250. X  Permission to use,  copy,  modify  and  distribute  without
  251. X  charge this software, documentation, images, etc. is grant-
  252. X  ed, provided that this copyright and the author's  name  is
  253. X  retained.
  254. X
  255. X  A fee may be charged for this program ONLY to recover costs
  256. X  for distribution (i.e. media costs).  No profit can be made
  257. X  on this program.
  258. X
  259. X  The author assumes no responsibility for disasters (natural
  260. X  or otherwise) as a consequence of use of this software.
  261. X
  262. X  Adam Stein (adam@iset.scan.mc.xerox.com)
  263. X*/
  264. X
  265. X#include <stdio.h>
  266. X#include <pwd.h>
  267. X#include <X11/Xlib.h>
  268. X#include <X11/Xutil.h>
  269. X#include <X11/Xresource.h>
  270. X#include "xtoolplaces.h"
  271. X#include "patchlevel.h"
  272. X
  273. Xint num_op_entries = 8;            /*Number of entries in OP table*/
  274. Xchar use_display[256];            /*Display to use*/
  275. XXrmDatabase cmmd_line_db;        /*Command line arguments*/
  276. XXrmDatabase database;            /*Database containing ALL resources*/
  277. XXrmOptionDescRec op_table[] = {        /*Argument operation resource table*/
  278. X        {"-a", ".addon",     XrmoptionSepArg, (caddr_t) NULL},
  279. X        {"-c", ".console",   XrmoptionIsArg,  (caddr_t) NULL},
  280. X        {"-d", ".display",   XrmoptionSepArg, (caddr_t) NULL},
  281. X        {"-f", ".saveto",    XrmoptionSepArg, (caddr_t) NULL},
  282. X        {"-m", ".missing",   XrmoptionSepArg, (caddr_t) NULL},
  283. X        {"-r", ".remote",    XrmoptionSepArg, (caddr_t) NULL},
  284. X        {"-s", ".screens",   XrmoptionSepArg, (caddr_t) NULL},
  285. X        {"-v", ".version",   XrmoptionIsArg,  (caddr_t) NULL}
  286. X};
  287. Xextern char *program;
  288. Xextern Display *display;
  289. Xchar *malloc(),*strdup(),*getenv();
  290. X
  291. X/*This function will gather all the arguments for this program, either through
  292. X  the command line or from resource databases.  The order for overriding options
  293. X  is as follows:
  294. X
  295. X    1) Hardcoded defaults
  296. X    2) Values in /usr/lib/X11/app-defaults/Xtoolplaces
  297. X    3) Values in $XUSERFILESEARCHPATH/Xtoolplaces or
  298. X       $XAPPLRESDIR/Xtoolplaces
  299. X    4) Values set using xrdb, either through the
  300. X       XResourceMangerString macro or, if that's empty, the
  301. X       .Xdefaults file in the user's home directory
  302. X    5) Values in the file specified by the XENVIRONMENT
  303. X       environment variable or, if that's not set, the
  304. X       .Xdefaults-hostname file in the user's home directory
  305. X       (where hostname is the name of the machine)
  306. X    6) Command line arguments
  307. X
  308. X  Each order overrides anything before it (i.e. command line arguments override
  309. X  everything, while /usr/lib/X11/app-defaults/Xtoolplaces only override
  310. X  hardcoded defaults).
  311. X
  312. X  Inputs:  argc - number of command line arguments
  313. X       argv - command line arguments
  314. X  Outputs: none
  315. X  Locals:  none
  316. X  Globals: none
  317. X*/
  318. Xgetargs(argc,argv)
  319. Xint argc;
  320. Xregister char *argv[];
  321. X{
  322. X    /*Initialize resource manager*/
  323. X    XrmInitialize();
  324. X
  325. X    /*Parse command line first so we can open the display*/
  326. X    parse_cmmd_args(&argc,argv);
  327. X
  328. X    /*Get server defaults, program defaults, .Xdefaults,
  329. X      command line, etc. and merge them*/
  330. X    merge_databases();
  331. X
  332. X    /*Extract values from database for use*/
  333. X    extract_options();
  334. X}
  335. X
  336. X/*This function will parse the command line options to get a display (-d)
  337. X  option if one is given.  It will also check for the '-v' option and act
  338. X  on it if it's given.
  339. X
  340. X  Inputs:  argc           - number of command line arguments
  341. X       argv           - command line arguments
  342. X  Outputs: none
  343. X  Locals:  resource       - name of resource to find
  344. X       str_type       - representation type (ignored)
  345. X       value          - value in the database
  346. X  Globals: display        - interface info to X display
  347. X       cmmd_line_db   - command line arguments in database form
  348. X       num_op_entries - number of entries in the OP table
  349. X       op_table       - argument operation resource table
  350. X       program        - name of currently executing program
  351. X       stderr         - standard error
  352. X       use_display    - display to use
  353. X       PATCHLEVEL     - current program patchlevel
  354. X       NULL          - 0
  355. X       USAGE      - usage line
  356. X       VERSION      - current program version
  357. X*/
  358. Xparse_cmmd_args(argc,argv)
  359. Xregister int *argc;
  360. Xregister char *argv[];
  361. X{
  362. X    register char *str_type[20],*resource;
  363. X    XrmValue value;
  364. X
  365. X    /*Allocate space for the names of the 2 resources we'll be looking
  366. X      for (the display and version resources)*/
  367. X    if((resource = malloc(strlen(program)+9)) == NULL) {
  368. X      perror(program);
  369. X      exit(1);
  370. X    }
  371. X
  372. X    use_display[0] = '\0';
  373. X
  374. X    /*Put command line arguments into database form*/
  375. X    XrmParseCommand(&cmmd_line_db,op_table,num_op_entries,argv[0],
  376. X            argc,argv);
  377. X
  378. X    /*Usage error if any arguments left*/
  379. X    if(*argc != 1) {
  380. X      fprintf(stderr,"usage: %s %s\n",program,USAGE);
  381. X      exit(1);
  382. X    }
  383. X
  384. X    /*If the -v option is given, just print the version and quit*/
  385. X    sprintf(resource,"%s.version",program);
  386. X    if(XrmGetResource(cmmd_line_db,resource,"xtoolplaces.display",
  387. X       str_type,&value) == True) {
  388. X      fprintf(stderr,"%s: version %s, patchlevel %s\n",program,VERSION,
  389. X          PATCHLEVEL);
  390. X      exit(0);
  391. X    }
  392. X
  393. X    /*Get display now because we need it to get other databases*/
  394. X    sprintf(resource,"%s.display",program);
  395. X    if(XrmGetResource(cmmd_line_db,resource,"xtoolplaces.display",
  396. X       str_type,&value) == True)
  397. X      strcpy(use_display,value.addr);
  398. X
  399. X    /*Open a connection to the X server*/
  400. X    if(!(display = XOpenDisplay(use_display))) {
  401. X      fprintf(stderr,"%s: can't open display (%s)\n",program,
  402. X          XDisplayName(use_display));
  403. X      exit(1);
  404. X    }
  405. X
  406. X    free(resource);
  407. X}
  408. X
  409. X/*This function will get resources from all the standard X resource
  410. X  places in the standard X order of looking and merge them into one
  411. X  database.  Resources are read in and merged into the global database
  412. X  according to the following order:
  413. X
  414. X    1) Values in /usr/lib/X11/app-defaults/Xtoolplaces
  415. X    2) Values in $XUSERFILESEARCHPATH/Xtoolplaces or
  416. X       $XAPPLRESDIR/Xtoolplaces
  417. X    3) Values set using xrdb, either through the
  418. X       XResourceMangerString macro or, if that's empty, the
  419. X       .Xdefaults file in the user's home directory
  420. X    4) Values in the file specified by the XENVIRONMENT
  421. X       environment variable or, if that's not set, the
  422. X       .Xdefaults-hostname file in the user's home directory
  423. X       (where hostname is the name of the machine)
  424. X    5) Command line arguments
  425. X
  426. X  Inputs:  none
  427. X  Outputs: none
  428. X  Locals:  db        - database of read in resource file
  429. X       db_file    - name of resource file to read in
  430. X       env_var    - environment variable value
  431. X       home        - user's home directory
  432. X  Globals: cmmd_line_db - command line arguments in database form
  433. X       database    - database containing ALL resources for this application
  434. X       display    - interface info to X display
  435. X       program    - name of currently executing program
  436. X       stderr    - standard error
  437. X       APPSDIR      - default resource directory
  438. X       APPSFILENAME - class name of this application
  439. X       NULL        - 0
  440. X*/
  441. Xmerge_databases()
  442. X{
  443. X    register char db_file[1024],*env_var,*home;
  444. X    register XrmDatabase db;
  445. X    char *gethomedir();
  446. X
  447. X    /*Get application defaults file, if any*/
  448. X    sprintf(db_file,"%s/%s",APPSDIR,APPSFILENAME);
  449. X    db = XrmGetFileDatabase(db_file);
  450. X    XrmMergeDatabases(db,&database);
  451. X
  452. X    /*Merge $XUSERFILESEARCHPATH/Xtoolplaces, if XUSERFILESEARCHPATH
  453. X      is defined; otherwise merge $XAPPLRESDIR/Xtoolplaces if it's
  454. X      defined*/
  455. X    if((env_var = getenv("XUSERFILESEARCHPATH")) == NULL)
  456. X      env_var = getenv("XAPPLRESDIR");
  457. X    if(env_var) {
  458. X      sprintf(db_file,"%s/%s",env_var,APPSFILENAME);
  459. X      db = XrmGetFileDatabase(db_file);
  460. X      XrmMergeDatabases(db,&database);
  461. X    }
  462. X
  463. X    /*Merge server defaults (these are created by xrdb).  If not
  464. X      defined, use ~/.Xdefaults*/
  465. X    if(XResourceManagerString(display) != NULL)
  466. X      db = XrmGetStringDatabase(XResourceManagerString(display));
  467. X    else {
  468. X           /*Open .Xdefaults file and merge into existing database*/
  469. X           if((home = gethomedir()) == NULL) {
  470. X         fprintf(stderr,"%s: can't find home directory\n",program);
  471. X         exit(1);
  472. X           }
  473. X           sprintf(db_file,"%s/.Xdefaults",home);
  474. X
  475. X           db = XrmGetFileDatabase(db_file);
  476. X         }
  477. X    XrmMergeDatabases(db,&database);
  478. X
  479. X    /*Open XENVIRONMENT file if defined or the ~/.Xdefaults-hostname file
  480. X      if not*/
  481. X    if((env_var = getenv("XENVIRONMENT")) == NULL) {
  482. X      if((home = gethomedir()) == NULL) {
  483. X        fprintf(stderr,"%s: can't find home directory\n",program);
  484. X        exit(1);
  485. X      }
  486. X      sprintf(db_file,"%s/.Xdefaults-",home);
  487. X      gethostname(&db_file[strlen(db_file)],1024-strlen(db_file));
  488. X    } else strcpy(db_file,env_var);
  489. X    db = XrmGetFileDatabase(db_file);
  490. X    XrmMergeDatabases(db,&database);
  491. X
  492. X    /*Command line overrides everything, merge that in last*/
  493. X    XrmMergeDatabases(cmmd_line_db,&database);
  494. X}
  495. X
  496. X/*This function will extract the options out of the database.
  497. X
  498. X  Inputs:  none
  499. X  Outputs: none
  500. X  Locals:  filename        - name of file to write window info to
  501. X       resource        - name of resource to find
  502. X       str_type        - representation type (ignored)
  503. X       value        - value in the database
  504. X  Globals: addon        - name of file containing commands to add on
  505. X       console_checking - indicates if the check console flag was given
  506. X       database        - database containing ALL resources
  507. X       list            - option list of screens to save from
  508. X       missing        - name of file containing X applications
  509. X       program        - name of currently executing program
  510. X       remote        - command to use for remote applications
  511. X       stderr        - standard error
  512. X       NULL            - 0
  513. X       True            - 'true' value
  514. X*/
  515. Xextract_options()
  516. X{
  517. X    register char *resource,*str_type[20],*filename;
  518. X    XrmValue value;
  519. X    char *malloc();
  520. X    extern int console_checking;
  521. X    extern char *addon,*missing,*remote,*list;
  522. X
  523. X    /*Allocate space for the names of the resources we'll be looking
  524. X      for*/
  525. X    if((resource = malloc(strlen(program)+11)) == NULL) {
  526. X      perror(program);
  527. X      exit(1);
  528. X    }
  529. X
  530. X    /*Get addon information (-a)*/
  531. X    addon = NULL;
  532. X    sprintf(resource,"%s.addon",program);
  533. X    if(XrmGetResource(database,resource,"xtoolplaces.addon",
  534. X              str_type,&value) == True)
  535. X      if(value.addr && ((addon = strdup(value.addr)) == NULL)) {
  536. X        perror(program);
  537. X        exit(1);
  538. X      }
  539. X
  540. X    /*Get console checking information (-c)*/
  541. X    console_checking = 0;
  542. X    sprintf(resource,"%s.console",program);
  543. X    if(XrmGetResource(database,resource,"xtoolplaces.console",
  544. X              str_type,&value) == True)
  545. X      console_checking = 1;
  546. X
  547. X    /*Get filename to save information to (-f)*/
  548. X    filename = NULL;
  549. X    sprintf(resource,"%s.saveto",program);
  550. X    if(XrmGetResource(database,resource,"xtoolplaces.saveto",
  551. X              str_type,&value) == True)
  552. X      if(value.addr && ((filename = strdup(value.addr)) == NULL)) {
  553. X        perror(program);
  554. X        exit(1);
  555. X      }
  556. X    open_file(filename);
  557. X
  558. X    /*Get missing applications list (-m)*/
  559. X    missing = NULL;
  560. X    sprintf(resource,"%s.missing",program);
  561. X    if(XrmGetResource(database,resource,"xtoolplaces.missing",
  562. X              str_type,&value) == True)
  563. X      if(value.addr && ((missing = strdup(value.addr)) == NULL)) {
  564. X        perror(program);
  565. X        exit(1);
  566. X      }
  567. X
  568. X    /*Get remote command to use (-r)*/
  569. X    remote = NULL;
  570. X    sprintf(resource,"%s.remote",program);
  571. X    if(XrmGetResource(database,resource,"xtoolplaces.remote",
  572. X              str_type,&value) == True)
  573. X      if(value.addr && ((remote = strdup(value.addr)) == NULL)) {
  574. X        perror(program);
  575. X        exit(1);
  576. X      }
  577. X
  578. X    /*Get list of screens to save window information from (-s)*/
  579. X    list = NULL;
  580. X    sprintf(resource,"%s.screens",program);
  581. X    if(XrmGetResource(database,resource,"xtoolplaces.screens",
  582. X              str_type,&value) == True)
  583. X      if(value.addr && ((list = strdup(value.addr)) == NULL)) {
  584. X        perror(program);
  585. X        exit(1);
  586. X      }
  587. X}
  588. X
  589. X/*This function will get the user's home directory, either from the HOME
  590. X  environment variable, or if that's not set, based on the USER environment
  591. X  variable (going through the password file).  If neither HOME or USER are
  592. X  set, the home directory is gotten by getting the user's uid and then going
  593. X  through the password file.  If this also fails, a NULL is returned,
  594. X  otherwise a valid home directory is returned.
  595. X
  596. X  Inputs:  none
  597. X  Outputs: ptr  - user's home directory if found, NULL if not
  598. X  Locals:  ptr  - user's home directory
  599. X       pw   - password entry of user
  600. X       uid  - uid of user
  601. X  Globals: HOME - environment variable containing the user's home directory
  602. X       NULL - 0
  603. X       USER - user's user name
  604. X*/
  605. Xchar *gethomedir()
  606. X{
  607. X    register int uid;
  608. X    register char *ptr;
  609. X    register struct passwd *pw;
  610. X
  611. X    if((ptr = getenv(HOME)) == NULL) {
  612. X      if((ptr = getenv(USER)) == NULL) {
  613. X         uid = getuid();
  614. X         pw = getpwuid(uid);
  615. X      } else pw = getpwnam(ptr);
  616. X
  617. X      if(pw) ptr = pw->pw_dir;
  618. X      else ptr = NULL;
  619. X    }
  620. X
  621. X    return(ptr);
  622. X}
  623. X
  624. X/*This will open the file to save information to.  If the filename isn't
  625. X  given on the command line (or resource files) (-f option), then use
  626. X  the default name of ~/.defaults.  If '-' is given as a filename, write
  627. X  to stdout.
  628. X
  629. X  Inputs:  filename         - name of file to write window info to
  630. X  Outputs: none
  631. X  Locals:  home             - user's home directory
  632. X  Globals: fp            - file pointer to write window information to
  633. X       program        - name of currently executing program
  634. X       stderr        - standard error
  635. X       stdout        - standard output
  636. X       DEFAULT_FILENAME - default filename to save to
  637. X       NULL            - 0
  638. X*/
  639. Xopen_file(filename)
  640. Xregister char *filename;
  641. X{
  642. X    register char *home;
  643. X    char *gethomedir();
  644. X    extern FILE *fp;
  645. X
  646. X    /*If filename isn't given, use default ~/.xtoolplaces
  647. X      else if filename matches -, write to stdout, else
  648. X      open the filename given for writing*/
  649. X        if(!filename) {
  650. X          /*Get home directory for default filename*/
  651. X      if((home = gethomedir()) == NULL) {
  652. X        fprintf(stderr,"%s: can't find home directory\n",program);
  653. X        exit(1);
  654. X      }
  655. X
  656. X      /*Allocate space for home directory, directory slash, and
  657. X        default filename*/
  658. X          if((filename = malloc(strlen(home)+strlen(DEFAULT_FILENAME)+2))
  659. X             == NULL) {
  660. X            perror(program);
  661. X            exit(1);
  662. X          }
  663. X            
  664. X          strcpy(filename,home);
  665. X          strcat(filename,"/");
  666. X          strcat(filename,DEFAULT_FILENAME);
  667. X        }
  668. X          
  669. X        if(strcmp(filename,"-")) {
  670. X          if((fp = fopen(filename,"w")) == NULL) {
  671. X           fprintf(stderr,"%s: can't open {%s} for writing\n",program,filename);           exit(1);
  672. X          }
  673. X        } else fp = stdout;
  674. X}
  675. X
  676. END_OF_FILE
  677.   if test 13930 -ne `wc -c <'getargs.c'`; then
  678.     echo shar: \"'getargs.c'\" unpacked with wrong size!
  679.   fi
  680.   # end of 'getargs.c'
  681. fi
  682. if test -f 'getinfo.c' -a "${1}" != "-c" ; then 
  683.   echo shar: Will not clobber existing file \"'getinfo.c'\"
  684. else
  685.   echo shar: Extracting \"'getinfo.c'\" \(12330 characters\)
  686.   sed "s/^X//" >'getinfo.c' <<'END_OF_FILE'
  687. X/*Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  688. X
  689. X  Permission to use,  copy,  modify  and  distribute  without
  690. X  charge this software, documentation, images, etc. is grant-
  691. X  ed, provided that this copyright and the author's  name  is
  692. X  retained.
  693. X
  694. X  A fee may be charged for this program ONLY to recover costs
  695. X  for distribution (i.e. media costs).  No profit can be made
  696. X  on this program.
  697. X
  698. X  The author assumes no responsibility for disasters (natural
  699. X  or otherwise) as a consequence of use of this software.
  700. X
  701. X  Adam Stein (adam@iset.scan.mc.xerox.com)
  702. X*/
  703. X
  704. X#include <stdio.h>
  705. X#include <signal.h>
  706. X#include <X11/Xlib.h>
  707. X#include <X11/Xutil.h>
  708. X#include <X11/cursorfont.h>
  709. X#include <X11/Xatom.h>
  710. X
  711. Xint mult_screens,screen_number,display_number;
  712. Xchar hostname[50];
  713. XAtom wm_save_yourself,wm_protocols,wm_client_machine;
  714. XDisplay *display;
  715. XWindow root_window;
  716. Xextern int console_checking;
  717. Xextern char *program,*addon;
  718. Xextern FILE *fp;
  719. X
  720. X/*This function will initialize the interface to X, lock the pointer and
  721. X  change it to a watch, start the recursive procedure of going through
  722. X  the window tree list, and then release the pointer and change the cursor
  723. X  back to normal when done.
  724. X
  725. X  Inputs:  none
  726. X  Outputs: none
  727. X  Locals:  child             - list of child window IDs
  728. X       cursor            - X cursor bitmap
  729. X       hostname         - name of host
  730. X       loop             - loop through screen number array
  731. X       num_child         - number of children under a parent
  732. X       parent            - parent window ID of child in the window tree
  733. X       root              - top window ID to start in window tree from
  734. X       screens         - array of screens to save from
  735. X  Globals: display           - interface info to X display
  736. X       display_number    - number of the display this will be working under
  737. X       mult_screens      - flag indicating if saving more than 1 screen
  738. X       program           - name of currently executing program
  739. X       root_window       - root window ID
  740. X       screen_number     - number of the screen this will be working under
  741. X       stderr         - standard error
  742. X       use_display       - display to use
  743. X       wm_client_machine - WM_CLIENT_MACHINE atom
  744. X       wm_protocols      - WM_PROTOCOLS atom
  745. X       wm_save_yourself  - WM_SAVE_YOURSELF atom
  746. X         CurrentTime         - indicates to execute action immediately
  747. X       False             - indicates not to do something
  748. X       GrabModeAsync     - indicates to grab device asynchronously
  749. X       GrabModeSync      - indicates to grab device synchronously
  750. X       None             - indicates no choice for an item
  751. X       NULL             - 0
  752. X       XC_watch          - indicates the watch bitmap
  753. X*/
  754. Xgetinfo()
  755. X{
  756. X    register int *screens,loop;
  757. X    unsigned int num_child;
  758. X    register Cursor cursor;
  759. X    Window root,parent,*child;
  760. X    extern char *use_display[256];
  761. X    int *make_list();
  762. X
  763. X    /*Get hostname*/
  764. X    if(gethostname(hostname,50)) {
  765. X      perror(program);
  766. X      exit(1);
  767. X    }
  768. X
  769. X    /*Find out what screens to save application states from*/
  770. X    display_number = display->ext_number;
  771. X    screens = make_list(DefaultScreen(display),ScreenCount(display));
  772. X    if(screens[1] != -1) mult_screens = 1;
  773. X    else mult_screens = 0;
  774. X
  775. X    /*Set up ATOMS to use*/
  776. X    wm_save_yourself = XInternAtom(display,"WM_SAVE_YOURSELF",False);
  777. X    wm_protocols = XInternAtom(display,"WM_PROTOCOLS",False);
  778. X    wm_client_machine = XInternAtom(display,"WM_CLIENT_MACHINE",False);
  779. X
  780. X    /*Change cursor to a watch and ring bell once to let user know
  781. X      that the server is tied up and the process has begun*/
  782. X    root_window = RootWindow(display,DefaultScreen(display));
  783. X    cursor = XCreateFontCursor(display,XC_watch);
  784. X    XGrabPointer(display,root_window,False,0,GrabModeSync,GrabModeAsync,
  785. X             None,cursor,CurrentTime);
  786. X    XBell(display,50);
  787. X
  788. X    /*Write Bourne shell header*/
  789. X    write_header();
  790. X
  791. X    /*Loop through the screens to save from*/
  792. X    for(loop = 0;screens[loop] != -1;++loop) {
  793. X      /*Get information about root window*/
  794. X      screen_number = screens[loop];
  795. X      root_window = RootWindow(display,screen_number);
  796. X
  797. X      /*Get list of root window's child*/
  798. X      if(!XQueryTree(display,root_window,&root,&parent,&child,&num_child)) {
  799. X        fprintf(stderr,"%s: couldn't get root window's child (window 0x%lx)\n",program,root_window);
  800. X        exit(1);
  801. X      }
  802. X
  803. X      /*Loop through children windows*/
  804. X      for(;num_child;--num_child)
  805. X        search(display,child[num_child-1],root_window);
  806. X  
  807. X      /*Free resources*/
  808. X      XFree(child);
  809. X    }
  810. X
  811. X    /*Change cursor back to normal and ring bell twice to signal that
  812. X      the process of saving the desktop is over*/
  813. X    XUngrabPointer(display,CurrentTime);
  814. X    XBell(display,50);
  815. X    XBell(display,50);
  816. X    XFlush(display);
  817. X
  818. X    /*Close the connection to the X server*/
  819. X    XCloseDisplay(display);
  820. X}
  821. X
  822. X/*This function will recursively search through the window tree.  It will check
  823. X  each window to see if it's state should be saved with a WM_SAVE_YOURSELF
  824. X  message and if it has a WM_COMMAND property to save.  A window is saved
  825. X  if:
  826. X    1.  it has WM_NAME set (so we know it's not a pop-up, etc)
  827. X    2.  it's a group leader or assume it's ok if group leader isn't set
  828. X    3.  it's parent is the root window
  829. X    4.  it has a WM_COMMAND property to save or is on a list specified
  830. X        with the '-m' option
  831. X
  832. X  Inputs:  display            - interface info to X display
  833. X       parent_window      - parent window ID of window we are examining
  834. X       window             - window we are examining
  835. X  Outputs: none
  836. X  Locals:  argc              - number of WM_COMMAND arguments
  837. X       argv                  - WM_COMMAND arguments
  838. X       child              - list of child window IDs
  839. X       command_line       - command line arguments in a single string
  840. X       console            - indicates if a window is a console
  841. X       count              - number of protocols that a window can receive
  842. X       event          - event information
  843. X       group_leader       - window ID of group leader
  844. X       hints              - window hints
  845. X       name              - X window name
  846. X       num_child          - number of children under a parent
  847. X       parent             - parent window ID of child in the window tree
  848. X       protocols          - list of protocols that a window can receive
  849. X       root               - top window ID to start in window tree from
  850. X       save_yourself      - flag indicating if window saved itself or not
  851. X       status             - status of get calls
  852. X  Globals: addon          - name of file containing commands to add on
  853. X       console_checking   - indicates if the check console flag was given
  854. X       fp              - file pointer to write window information to
  855. X       mult_screens       - flag indicating if saving more than 1 screen
  856. X       on_missing_list    - flag indicating if window is a missing app
  857. X       program            - name of currently executing program
  858. X       root_window        - root window ID
  859. X       screen_number      - number of the screen this will be working under
  860. X       stderr          - standard error
  861. X       wm_protocols          - WM_PROTOCOLS atom
  862. X       wm_save_yourself   - WM_SAVE_YOURSELF atom
  863. X       ClientMessage      - event that indicates a message from 1 client
  864. X                to another
  865. X       False          - indicates not to do something
  866. X       PropertyChangeMask - indicates a window property has changed
  867. X       PropertyNotify     - event that indicates a property has changed
  868. X       WindowGroupHint    - mask for group hint bit in hint flags
  869. X*/
  870. Xsearch(display,window,parent_window)
  871. Xregister Display *display;
  872. Xregister Window window,parent_window;
  873. X{
  874. X    register int save_yourself,on_missing_list,console = 0;
  875. X    unsigned int num_child;
  876. X    int count,argc,group_leader = 0;
  877. X    register char *command_line,*name;
  878. X    char **argv;
  879. X    Atom *protocols;
  880. X    register Status status;
  881. X    void getsignal();
  882. X    Window root,parent,*child;
  883. X    XEvent event;
  884. X    register XWMHints *hints;
  885. X    char *combine(),*getgeom(),*getname(),*lower();
  886. X
  887. X
  888. X    /*If a child had children of it's own, loop thru it's children
  889. X      recursively*/
  890. X    if(XQueryTree(display,window,&root,&parent,&child,&num_child)) {
  891. X      for(;num_child;--num_child)
  892. X        search(display,child[num_child-1],parent_window);
  893. X
  894. X      /*Free resources*/
  895. X      XFree(child);
  896. X    }
  897. X
  898. X    /*Don't report window if it doesn't have a name (in which case it's
  899. X      probably a pop-up or unmapped child*/
  900. X    if(name = getname(window)) XFree(name);
  901. X    else return;
  902. X
  903. X    /*Don't report window if it's not a group leader or isn't a top
  904. X      window*/
  905. X    hints = XGetWMHints(display,window);
  906. X
  907. X    /*Also check if program didn't set #!$% group leader, in this case
  908. X      assume it's ok (I'm sure that's asking for trouble!)*/
  909. X    if(hints) {
  910. X      if((hints->window_group == window) ||
  911. X         !(hints->flags & WindowGroupHint))
  912. X        group_leader = 1;
  913. X      XFree(hints);
  914. X    }
  915. X    if(!group_leader || (parent_window != root_window)) return;
  916. X
  917. X    /*Determine if window has WM_SAVE_YOURSELF ATOM and send it if
  918. X      it does to save it's state*/
  919. X    status = XGetWMProtocols(display,window,&protocols,&count);
  920. X    if(status && is_save_yourself(protocols,count)) {
  921. X      save_yourself = 1;
  922. X
  923. X      /*If window does have WM_SAVE_YOURSELF, send it a message to
  924. X        save it's state and wait for the PropertyNotify response*/
  925. X      event.type = ClientMessage;
  926. X      event.xclient.window = window;
  927. X      event.xclient.message_type = wm_protocols;
  928. X      event.xclient.format = 32;
  929. X      event.xclient.data.l[0] = (long) wm_save_yourself;
  930. X      XSelectInput(display,window,PropertyChangeMask);
  931. X      XSendEvent(display,window,False,0L,&event);
  932. X      XNextEvent(display,&event);
  933. X      if(event.type == PropertyNotify) {
  934. X        if(event.xproperty.window != window) {
  935. X          fprintf(stderr,"%s: unexpected PropertyNotify event\n",program);
  936. X          exit(1);
  937. X        }
  938. X      } else {
  939. X           fprintf(stderr,"%s: unexpected event\n",program);
  940. X           exit(1);
  941. X         }
  942. X    } else save_yourself = 0;
  943. X
  944. X    /*Free resources*/
  945. X    if(status) XFree(protocols);
  946. X
  947. X    /*Determine if window is on missing apps list*/
  948. X    on_missing_list = on_list(window);
  949. X
  950. X    /*Get WM_COMMAND.  If window doesn't have it set or isn't a console
  951. X      tool, skip it, otherwise write it out*/
  952. X    status = XGetCommand(display,window,&argv,&argc);
  953. X    if((status && !isnull(window)) || on_missing_list ||
  954. X       is_console(window,NULL)) {
  955. X      /*Put arguments into a single string and free up argv.  Makes it
  956. X        easier to check for things*/
  957. X      if(status) {
  958. X        command_line = combine(argc,argv);
  959. X        XFreeStringList(argv);
  960. X      } else {
  961. X           /*It is ASSUMED that if we have to save a window that
  962. X            doesn't have WM_COMMAND set, it's name is the basename
  963. X            of WM_NAME in all lower case (i.e. xman sets WM_NAME to
  964. X            Xman)*/
  965. X           command_line = lower(getname(window));
  966. X           save_yourself = 0;
  967. X         }
  968. X
  969. X      if(!save_yourself) command_line = getgeom(window,command_line);
  970. X
  971. X      /*If console checking flag was given, check each window to see
  972. X        if it's a console window*/
  973. X      if(console_checking)
  974. X        console = is_console(window,command_line);
  975. X
  976. X      /*If this window is a console window, write out the special
  977. X        'if ... fi' clause*/
  978. X      if(console)
  979. X        fputs("if [ \"`tty`\" = \"/dev/console\" ]\nthen\n  ",fp);
  980. X
  981. X      /*Check to see if window is a remote application*/
  982. X      is_remote(window);
  983. X
  984. X      /*Fix Xview's long label problem*/
  985. X      fix_command(command_line);
  986. X
  987. X      /*If saving from more than 1 screen, make sure each application
  988. X        has the correct -display option to put it back onto the correct
  989. X        screen*/
  990. X
  991. X      /*Write out all the arguments in WM_COMMAND*/
  992. X      fprintf(fp,"%s ",command_line);
  993. X
  994. X      if(mult_screens) adddisplay(command_line,screen_number);
  995. X
  996. X      /*If -a option given, search for any addon commands for this window*/
  997. X      if(addon) addto(command_line);
  998. X
  999. X      /*Write out ampersand to put command into the background*/
  1000. X      fputs("&\n",fp);
  1001. X
  1002. X      if(console)
  1003. X        fputs("fi\n",fp);
  1004. X
  1005. X      /*Free resources*/
  1006. X      free(command_line);
  1007. X    }
  1008. X}
  1009. X
  1010. X/*This function will convert all letters in a string to lower case (if not
  1011. X  already lower case).  It will also take the basename of the string.
  1012. X
  1013. X  Inputs:  string    - string to turn all characters to lower case
  1014. X  Outputs: string    - string of all lower case characters
  1015. X  Locals:  loop      - loop through string
  1016. X       newstring - lower case basename of original string
  1017. X       pointer   - pointer to directory slash to get basename
  1018. X  Globals: none
  1019. X*/
  1020. Xchar *lower(string)
  1021. Xregister char *string;
  1022. X{
  1023. X    register int loop;
  1024. X    register char *pointer,*newstring;
  1025. X    char *rindex(),*strdup();
  1026. X
  1027. X    if((pointer = rindex(string,'/')) == NULL) pointer = string;
  1028. X    else ++pointer;
  1029. X
  1030. X    if((newstring = strdup(pointer)) == NULL) {
  1031. X      perror(program);
  1032. X      exit(1);
  1033. X    }
  1034. X
  1035. X    for(loop = 0;loop < strlen(newstring);++loop)
  1036. X      if(isupper(newstring[loop]))
  1037. X        newstring[loop] = tolower(newstring[loop]);
  1038. X
  1039. X    return(newstring);
  1040. X}
  1041. X
  1042. END_OF_FILE
  1043.   if test 12330 -ne `wc -c <'getinfo.c'`; then
  1044.     echo shar: \"'getinfo.c'\" unpacked with wrong size!
  1045.   fi
  1046.   # end of 'getinfo.c'
  1047. fi
  1048. if test -f 'is.c' -a "${1}" != "-c" ; then 
  1049.   echo shar: Will not clobber existing file \"'is.c'\"
  1050. else
  1051.   echo shar: Extracting \"'is.c'\" \(12708 characters\)
  1052.   sed "s/^X//" >'is.c' <<'END_OF_FILE'
  1053. X/*Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  1054. X
  1055. X  Permission to use,  copy,  modify  and  distribute  without
  1056. X  charge this software, documentation, images, etc. is grant-
  1057. X  ed, provided that this copyright and the author's  name  is
  1058. X  retained.
  1059. X
  1060. X  A fee may be charged for this program ONLY to recover costs
  1061. X  for distribution (i.e. media costs).  No profit can be made
  1062. X  on this program.
  1063. X
  1064. X  The author assumes no responsibility for disasters (natural
  1065. X  or otherwise) as a consequence of use of this software.
  1066. X
  1067. X  Adam Stein (adam@iset.scan.mc.xerox.com)
  1068. X*/
  1069. X
  1070. X#include <stdio.h>
  1071. X#include <X11/Xlib.h>
  1072. X#include <X11/Xutil.h>
  1073. X#include <X11/Xatom.h>
  1074. X#include "xtoolplaces.h"
  1075. X
  1076. Xextern char *remote,hostname[];
  1077. Xextern Atom wm_save_yourself,wm_client_machine;
  1078. Xextern Display *display;
  1079. Xextern FILE *fp;
  1080. X
  1081. X/*This function will check a list of protocols to see if the WM_SAVE_YOURSELF
  1082. X  protocol is in the list
  1083. X
  1084. X  Inputs:  count            - number of protocols in list
  1085. X       protocols        - protocol list
  1086. X  Outputs: 1 if WM_SAVE_YOURSELF is found, 0 otherwise
  1087. X  Locals:  none
  1088. X  Globals: wm_save_yourself - WM_SAVE_YOURSELF atom
  1089. X*/
  1090. Xis_save_yourself(protocols,count)
  1091. Xregister int count;
  1092. Xregister Atom *protocols;
  1093. X{
  1094. X    for(;count;--count)
  1095. X      if(protocols[count-1] == wm_save_yourself)
  1096. X        return(1);
  1097. X
  1098. X    return(0);
  1099. X}
  1100. X
  1101. X/*This function will read in WM_COMMAND from a window and determine if
  1102. X  WM_COMMAND is set, but null.  This is a problem which XGetCommand()
  1103. X  doesn't handle.  If WM_COMMAND is null, XGetCommand() still returns
  1104. X  an argv pointer with the number of arguments equal to 1.  This code
  1105. X  is lifted (and modified) from xprop (i.e. I didn't think of it myself).
  1106. X
  1107. X  This routine is needed because some windows are EXACTLY like a top-level
  1108. X  window to save EXCEPT their WM_COMMAND property is null (i.e. Filemgr's
  1109. X  wastebasket and Mailtool's Compose window -- both from the OpenWindow
  1110. X  deskset).
  1111. X
  1112. X  Inputs:  window        - window we are examining
  1113. X  Outputs: 1 if null (or no WM_COMMAND), 0 otherwise
  1114. X  Locals:  actual_format - actual data type of the returned data
  1115. X       actual_type   - actual type of WM_COMMAND
  1116. X       bytes_after   - number of bytes remaining to be read in if a
  1117. X               partial read was performed
  1118. X       nitems        - actual number of items returned in 'prop'.
  1119. X       prop         - pointer to the data in WM_COMMAND
  1120. X       status     - status of get call
  1121. X*/
  1122. Xisnull(window)
  1123. Xregister Window window;
  1124. X{
  1125. X    register int status;
  1126. X    int actual_format;
  1127. X    unsigned long nitems,bytes_after;
  1128. X    unsigned char *prop;
  1129. X    Atom actual_type;
  1130. X
  1131. X    status = XGetWindowProperty(display,window,XA_WM_COMMAND,0,2500,False,
  1132. X                    AnyPropertyType,&actual_type,
  1133. X                    &actual_format,&nitems,&bytes_after,&prop);
  1134. X
  1135. X    if((status == Success) && nitems) return(0);
  1136. X    else return(1);
  1137. X}
  1138. X
  1139. X
  1140. X/*This function will determine if a window is acting as a console window.  It
  1141. X  does this by first checking the class of the window.  Since there is no
  1142. X  standard class for consoles, maybe this program will start one.  The window
  1143. X  is considered a console if it's class is XConsole.  If the class isn't
  1144. X  XConsole (which is most likely the case), functions are called to check
  1145. X  for each console type that I could think of.  This includes contool,
  1146. X  Sun's shelltool & cmdtool, and xterm.  Each (of course) has a different
  1147. X  way of identifying when it's on console mode.  To add other consoles, just
  1148. X  add another function call here and the function to make the check.  A 1
  1149. X  is returned if the window is a console, 0 otherwise.
  1150. X
  1151. X  Inputs:  command_line  - WM_COMMAND arguments in a single string
  1152. X       window        - ID of the window that we are going to check
  1153. X  Outputs: console       - indicates if a window is a console
  1154. X  Locals:  class_hints   - window class
  1155. X       console       - indicates if a window is a console
  1156. X       status        - status of get call
  1157. X  Globals: display       - interface info to X display
  1158. X       CONSOLE_CLASS - class name for console windows
  1159. X*/
  1160. Xis_console(window,command_line)
  1161. Xregister char *command_line;
  1162. Xregister Window window;
  1163. X{
  1164. X    register int console = 0;
  1165. X    register Status status;
  1166. X    XClassHint class_hints;
  1167. X
  1168. X    /*Get window class and check it against what a class for a console
  1169. X      window should be*/
  1170. X    status = XGetClassHint(display,window,&class_hints);
  1171. X    if(status && !strcmp(class_hints.res_class,CONSOLE_CLASS))
  1172. X      console = 1;
  1173. X    XFree(class_hints.res_name);
  1174. X    XFree(class_hints.res_class);
  1175. X
  1176. X    /*If the class doesn't match, check for each type of console
  1177. X      window possible*/
  1178. X    if(!console)
  1179. X      if(!(console = check_contool(window)))
  1180. X        if(command_line && !(console = check_sun_tools(window)))
  1181. X          console = check_xterm(window,command_line);
  1182. X
  1183. X    return(console);
  1184. X}
  1185. X
  1186. X/*This function will check to see if a window is the contool window.  Since
  1187. X  contool is always a console, we only have to check the window name to see
  1188. X  if the word 'Contool' is in the name.  A 1 is returned if it is a contool
  1189. X  window, 0 otherwise.
  1190. X
  1191. X  Inputs:  window       - ID of the window that we are going to check
  1192. X  Outputs: contool      - flag indicating if window is contool window or not
  1193. X  Locals:  contool      - flag indicating if window is contool window or not
  1194. X       name        - X window name
  1195. X  Globals: display      - interface info to X display
  1196. X       CONTOOL_NAME - name of contool window
  1197. X*/
  1198. Xcheck_contool(window)
  1199. Xregister Window window;
  1200. X{
  1201. X    register int contool = 0;
  1202. X    register char *name;
  1203. X    char *getname();
  1204. X
  1205. X    /*Get the name of the window to compare it against the name contool
  1206. X      gives it's window*/
  1207. X    name = getname(window);
  1208. X    if(name && strstr(name,CONTOOL_NAME)) {
  1209. X      contool = 1;
  1210. X      XFree(name);
  1211. X    }
  1212. X
  1213. X    return(contool);
  1214. X}
  1215. X
  1216. X/*This function will check to see if a window is either a shelltool or
  1217. X  cmdtool in the console mode.  Since the icon name is CONSOLE only when
  1218. X  either is started up in console mode, we can check that.  A 1 is returned
  1219. X  if it is in console mode, 0 otherwise.
  1220. X
  1221. X  Inputs:  window              - ID of the window that we are going to check
  1222. X  Outputs: sun_tools           - flag indicating if window is in console mode
  1223. X  Locals:  status              - status of get call
  1224. X       sun_tools            - flag indicating if window is in console mode
  1225. X       tp                   - window's text property
  1226. X  Globals: display           - interface info to X display
  1227. X       SUN_TOOLS_ICON_NAME - icon name for {shell,cmd}tool in console mode
  1228. X*/
  1229. Xcheck_sun_tools(window)
  1230. Xregister Window window;
  1231. X{
  1232. X    register int sun_tools = 0;
  1233. X    register Status status;
  1234. X    XTextProperty tp;
  1235. X
  1236. X    /*Get window's icon name and check it against what Sun labels the icon
  1237. X      of either shelltool or cmdtool in console mode*/
  1238. X    status = XGetWMIconName(display,window,&tp);
  1239. X    if(status && !strcmp(tp.value,SUN_TOOLS_ICON_NAME))
  1240. X      sun_tools = 1;
  1241. X
  1242. X    XFree(tp.value);
  1243. X
  1244. X    return(sun_tools);
  1245. X}
  1246. X
  1247. X/*This function will check to see if a window is xterm in the console mode.
  1248. X  The only way to determine if xterm is in console mode is to check the
  1249. X  options to see if it was started with the -C option.  A 1 is returned
  1250. X  if it is in console mode, 0 otherwise.
  1251. X
  1252. X  Inputs:  command_line - WM_COMMAND arguments in a single string
  1253. X       window       - ID of the window that we are going to check
  1254. X  Outputs: xterm        - flag indicating if window is xterm in console mode
  1255. X  Locals:  xterm        - flag indicating if window is xterm in console mode
  1256. X  Globals: XTERM_OPTION - xterm option to put it into console mode
  1257. X*/
  1258. Xcheck_xterm(window,command_line)
  1259. Xregister char *command_line;
  1260. Xregister Window window;
  1261. X{
  1262. X    register int xterm = 0;
  1263. X
  1264. X    /*See if it's xterm*/
  1265. X    if(is_xterm(window) == 1)
  1266. X      /*If window is xterm, then check argument list for xterm console
  1267. X        mode option*/
  1268. X      if(strstr(command_line,XTERM_OPTION)) xterm = 1;
  1269. X
  1270. X    return(xterm);
  1271. X}
  1272. X
  1273. X/*This function determines if a particular window is an xterm window.  To
  1274. X  see if a window is an xterm window, we check it's class.  Xterm always sets
  1275. X  it's class to "XTerm".  1 is returned if it is an xterm window, 0 if it
  1276. X  isn't, -1 if there is an error in getting the class of the window.
  1277. X
  1278. X  Inputs:  window   - ID of the window that we are going to check
  1279. X  Outputs: 1 if xterm, 0 if not xterm, -1 if error in getting class
  1280. X  Locals:  match    - flag indicating if window is xterm window or not
  1281. X       status   - status of get call
  1282. X       tp        - window's text property
  1283. X  Globals: display  - interface info to X display
  1284. X*/
  1285. Xis_xterm(window)
  1286. Xregister Window window;
  1287. X{
  1288. X    register int match;
  1289. X    register Status status;
  1290. X    XClassHint class_hints;
  1291. X
  1292. X    /*Get window class to see if it's xterm*/
  1293. X    status = XGetClassHint(display,window,&class_hints);
  1294. X
  1295. X    if(status) {
  1296. X      match = strcmp(class_hints.res_class,"XTerm");
  1297. X      XFree(class_hints.res_name);
  1298. X      XFree(class_hints.res_class);
  1299. X
  1300. X      return((!match)?1:0);
  1301. X    } else return(-1);
  1302. X}
  1303. X
  1304. X/*This function determines if a particular window is an emacs window.  To
  1305. X  see if a window is an emacs window, we check it's class.  Emacs always sets
  1306. X  it's class to "Emacs".  1 is returned if it is an emacs window, 0 if it
  1307. X  isn't, -1 if there is an error in getting the name of the window.
  1308. X
  1309. X  Inputs:  window   - ID of the window that we are going to check
  1310. X  Outputs: 1 if emacs, 0 if not emacs, -1 if error in getting class
  1311. X  Locals:  match    - flag indicating if window is emacs window or not
  1312. X       status   - status of get call
  1313. X       tp        - window's text property
  1314. X  Globals: display  - interface info to X display
  1315. X*/
  1316. Xis_emacs(window)
  1317. Xregister Window window;
  1318. X{
  1319. X    register int match,propstatus;
  1320. X    int actual_format;
  1321. X    unsigned long nitems,bytes_after;
  1322. X    unsigned char *prop;
  1323. X    register Atom epoch_current;
  1324. X    Atom actual_type;
  1325. X    register Status status;
  1326. X    XClassHint class_hints;
  1327. X
  1328. X    /*Get window class to see if it's emacs*/
  1329. X    status = XGetClassHint(display,window,&class_hints);
  1330. X
  1331. X    if(status) {
  1332. X      match = strcmp(class_hints.res_class,"Emacs");
  1333. X
  1334. X      epoch_current = XInternAtom(display,"EPOCH_CURRENT",True);
  1335. X      if(epoch_current != None) {
  1336. X        propstatus = XGetWindowProperty(display,window,epoch_current,0,1,
  1337. X                        False,AnyPropertyType,&actual_type,
  1338. X                        &actual_format,&nitems,&bytes_after,
  1339. X                        &prop);
  1340. X
  1341. X      /*It's weird that XGetWindowProperty() would return Success without
  1342. X        sending back any properties (prop = NULL)*/
  1343. X      if((propstatus == Success) && prop && strcmp(prop,"minibuf"))
  1344. X        match = 0;
  1345. X      else match = 1;
  1346. X
  1347. X      XFree(class_hints.res_name);
  1348. X      XFree(class_hints.res_class);
  1349. X      if(prop) XFree(prop);
  1350. X      }
  1351. X
  1352. X      return((!match)?1:0);
  1353. X    } else return(-1);
  1354. X}
  1355. X
  1356. X/*This function determines if a particular window is a calctool window.  To
  1357. X  see if a window is a calctool window, we check it's name.  Calctool always
  1358. X  sets it's name to "calctool".  1 is returned if it is a calctool window, 0
  1359. X  if it isn't, -1 if there is an error in getting the name of the window.
  1360. X
  1361. X  Inputs:  window    - ID of the window that we are going to check
  1362. X  Outputs: 1 if calctool, 0 if not calctool, -1 if error in getting name
  1363. X  Locals:  status    - status of get call
  1364. X       text_prop - window's text property
  1365. X  Globals: display   - interface info to X display
  1366. X*/
  1367. Xis_calctool(window)
  1368. Xregister Window window;
  1369. X{
  1370. X    register Status status;
  1371. X    XTextProperty text_prop;
  1372. X
  1373. X    /*Get window name to see if it's calctool*/
  1374. X    status = XGetWMName(display,window,&text_prop);
  1375. X
  1376. X    if(status) return((!strcmp(text_prop.value,"calctool"))?1:0);
  1377. X    else return(-1);
  1378. X}
  1379. X
  1380. X/*This function checks to see if an application is being executed remotely.
  1381. X  If it is, it prints out the remote execution command (typically 'rsh -n') and
  1382. X  the name of the remote machine to execute on.
  1383. X
  1384. X  Inputs:  window          - ID of the window that we are going to check
  1385. X  Outputs: none
  1386. X  Locals:  status          - status of get call
  1387. X       tp              - window's text property
  1388. X  Globals: display         - interface info to X display
  1389. X       fp             - file pointer to write window information to
  1390. X       hostname         - name of host
  1391. X       remote         - command to use for remote applications
  1392. X       wm_client_machine - WM_CLIENT_MACHINE atom
  1393. X*/
  1394. Xis_remote(window)
  1395. Xregister Window window;
  1396. X{
  1397. X    register Status status;
  1398. X    XTextProperty tp;
  1399. X
  1400. X    status = XGetTextProperty(display,window,&tp,wm_client_machine);
  1401. X
  1402. X    /*Check if WM_CLIENT_MACHINE exists and isn't the name of the
  1403. X      machine we are currently executing on*/
  1404. X    if(status && strcmp(tp.value,hostname))
  1405. X      fprintf(fp,"%s %s ",remote,tp.value);
  1406. X}
  1407. X
  1408. X/*This function gets the name of an X window and returns it.
  1409. X
  1410. X  Inputs:  window   - ID of the window that we are going to check
  1411. X  Outputs: tp.value - name of X window
  1412. X  Locals:  status   - status of get call
  1413. X       tp       - window's text property
  1414. X  Globals: display  - interface info to X display
  1415. X       NULL     - 0
  1416. X*/
  1417. Xchar *getname(window)
  1418. Xregister Window window;
  1419. X{
  1420. X    register Status status;
  1421. X    XTextProperty tp;
  1422. X
  1423. X    /*Get the name of the window*/
  1424. X    status = XGetWMName(display,window,&tp);
  1425. X
  1426. X    if(status) return((char *) tp.value);
  1427. X    else return(NULL);
  1428. X}
  1429. X
  1430. END_OF_FILE
  1431.   if test 12708 -ne `wc -c <'is.c'`; then
  1432.     echo shar: \"'is.c'\" unpacked with wrong size!
  1433.   fi
  1434.   # end of 'is.c'
  1435. fi
  1436. if test -f 'missing.c' -a "${1}" != "-c" ; then 
  1437.   echo shar: Will not clobber existing file \"'missing.c'\"
  1438. else
  1439.   echo shar: Extracting \"'missing.c'\" \(2855 characters\)
  1440.   sed "s/^X//" >'missing.c' <<'END_OF_FILE'
  1441. X/*Copyright (c) 1993 Xerox Corporation.  All Rights Reserved.
  1442. X
  1443. X  Permission to use,  copy,  modify  and  distribute  without
  1444. X  charge this software, documentation, images, etc. is grant-
  1445. X  ed, provided that this copyright and the author's  name  is
  1446. X  retained.
  1447. X
  1448. X  A fee may be charged for this program ONLY to recover costs
  1449. X  for distribution (i.e. media costs).  No profit can be made
  1450. X  on this program.
  1451. X
  1452. X  The author assumes no responsibility for disasters (natural
  1453. X  or otherwise) as a consequence of use of this software.
  1454. X
  1455. X  Adam Stein (adam@iset.scan.mc.xerox.com)
  1456. X*/
  1457. X
  1458. X#include <stdio.h>
  1459. X#include <X11/Xos.h>
  1460. X#include <X11/Xlib.h>
  1461. X
  1462. Xint aindex;
  1463. Xchar *missing_list[50];
  1464. Xextern char *missing,*program;
  1465. X
  1466. X/*This function will read in the list of X applications that don't set
  1467. X  WM_COMMAND and need to be saved.
  1468. X
  1469. X  Inputs:  none
  1470. X  Outputs: none
  1471. X  Locals:  fp           - file pointer to read from
  1472. X       line         - line of text read in
  1473. X  Globals: aindex    - index into name list
  1474. X       missing    - name of file containing X applications
  1475. X       missing_list - list of X applications that don't set WM_COMMAND
  1476. X       program      - name of currently executing program
  1477. X       stderr    - standard error
  1478. X       NULL        - 0
  1479. X*/
  1480. Xread_missing()
  1481. X{
  1482. X    register char line[200];
  1483. X    register FILE *fp;
  1484. X    char *strdup();
  1485. X
  1486. X    /*Open the file for reading*/
  1487. X    if((fp = fopen(missing,"r")) == NULL) {
  1488. X      fprintf(stderr,"%s: can't open {%s}\n",program,missing);
  1489. X      exit(1);
  1490. X    }
  1491. X
  1492. X    aindex = 0;
  1493. X
  1494. X    /*Read lines from file until there is no more*/
  1495. X    while(fgets(line,200,fp) != NULL)
  1496. X      switch(line[0]) {
  1497. X            case '#':                   /*Comment character - ignore line*/
  1498. X            case '\n':                  /*Blank line - ignore line*/
  1499. X                        break;
  1500. X            default:
  1501. X            line[strlen(line)-1] = '\0';  /*Take out NL char*/
  1502. X            if((missing_list[aindex++] = strdup(line)) == NULL) {
  1503. X              perror(program);
  1504. X              exit(1);
  1505. X            }
  1506. X
  1507. X            break;
  1508. X      }
  1509. X}
  1510. X
  1511. X/*This function will determine if an application's window is on the missing
  1512. X  applications list.  A 1 is returned if on the list, 0 if not.
  1513. X
  1514. X  Inputs:  window     - ID of the window that we are going to check
  1515. X  Outputs: result     - 1 if application is on the list, 0 if not
  1516. X  Locals:  loop       - loop through name list
  1517. X       name       - name of window
  1518. X       result     - flag indicating if window is on list or not
  1519. X  Globals: aindex    - number of entries in the name list
  1520. X       missing    - name of file containing X applications
  1521. X       missing_list - list of X applications that don't set WM_COMMAND
  1522. X*/
  1523. Xon_list(window)
  1524. Xregister Window window;
  1525. X{
  1526. X    register int loop,result;
  1527. X    register char *name;
  1528. X    char *getname();
  1529. X
  1530. X    result = 0;
  1531. X
  1532. X    /*Check name list if '-m' was given*/
  1533. X    if(missing)
  1534. X      if(name = getname(window)) {
  1535. X        for(loop = 0;!result && (loop < aindex);++loop)
  1536. X          if(!strcmp(name,missing_list[loop])) result = 1;
  1537. X
  1538. X        XFree(name);
  1539. X      }
  1540. X
  1541. X    return(result);
  1542. X}
  1543. X
  1544. END_OF_FILE
  1545.   if test 2855 -ne `wc -c <'missing.c'`; then
  1546.     echo shar: \"'missing.c'\" unpacked with wrong size!
  1547.   fi
  1548.   # end of 'missing.c'
  1549. fi
  1550. echo shar: End of archive 1 \(of 3\).
  1551. cp /dev/null ark1isdone
  1552. MISSING=""
  1553. for I in 1 2 3 ; do
  1554.     if test ! -f ark${I}isdone ; then
  1555.     MISSING="${MISSING} ${I}"
  1556.     fi
  1557. done
  1558. if test "${MISSING}" = "" ; then
  1559.     echo You have unpacked all 3 archives.
  1560.     rm -f ark[1-9]isdone
  1561. else
  1562.     echo You still must unpack the following archives:
  1563.     echo "        " ${MISSING}
  1564. fi
  1565. exit 0
  1566. exit 0 # Just in case...
  1567. -- 
  1568.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  1569. \X/  Amiga - The only way to fly!      |
  1570.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  1571.   casual observer..."                  |
  1572.