home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xwps2 / part01 next >
Encoding:
Internet Message Format  |  1989-08-25  |  32.2 KB

  1. Path: uunet!island!argv
  2. From: argv@island.uu.net (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v04i095: Another xwps program, Part01/01
  5. Message-ID: <1030@island.uu.net>
  6. Date: 25 Aug 89 18:16:11 GMT
  7. Organization: Island Graphics, Marin County, California
  8. Lines: 1249
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: bchen@esvax.Berkeley.EDU (Benjamin Chen)
  12. Posting-number: Volume 4, Issue 95
  13. Archive-name: xwps2/part01
  14.  
  15. [ Here's another xwps program.  What I like best about it is that it has
  16.   a set of common routines that all beginning X programmers are always
  17.   asking how to do.  Novices: check out dsimple.c.  Much content of this
  18.   program was taken from other existing programs.  Works under R2 and does
  19.   not use widgets.  README is at the end of the file.  --argv ]
  20.  
  21. #! /bin/sh
  22. export PATH || exec /bin/sh $0 $*
  23. : # This is a shell archive.  Remove anything before #! /bin/sh line, then
  24. : # unpack it by saving it in a file and typing "sh file", creating files:
  25. : #    'dsimple.c'
  26. : #    'psfile.c'
  27. : #    'xwps.c'
  28. : #    'dsimple.h'
  29. : #    'extern.h'
  30. : #    'Makefile'
  31. : #    'README'
  32. : # Made by wong on Thu Jul 20 14:31:47 PDT 1989
  33. PATH="/bin:/usr/bin:/usr/ucb:$PATH"
  34. export PATH
  35. prog="`basename \"$0\"`"
  36. error=0
  37. if test -f 'dsimple.c' -o -d 'dsimple.c'; then
  38.     echo "$prog: \"dsimple.c\" exists, skipping" >&2
  39.     error=1
  40. else
  41.     echo 'x - dsimple.c'
  42.     sed -e 's/^X//' << 'EOF dsimple.c' > 'dsimple.c'
  43. X/* $Header: dsimple.c,v 1.5 88/02/09 11:28:35 jim Exp $ */
  44. X#include <X11/Xos.h>
  45. X#include <X11/Xlib.h>
  46. X#include <X11/Xutil.h>
  47. X#include <X11/cursorfont.h>
  48. X#include <stdio.h>
  49. X/*
  50. X * Other_stuff.h: Definitions of routines in other_stuff.
  51. X *
  52. X * Written by Mark Lillibridge.   Last updated 7/1/87
  53. X *
  54. X * Send bugs, etc. to chariot@athena.mit.edu.
  55. X */
  56. X
  57. Xunsigned long Resolve_Color();
  58. XPixmap Bitmap_To_Pixmap();
  59. XWindow Select_Window();
  60. Xvoid out();
  61. Xvoid blip();
  62. XWindow Window_With_Name();
  63. X/*
  64. X * Just_display: A group of routines designed to make the writting of simple
  65. X *               X11 applications which open a display but do not open
  66. X *               any windows much faster and easier.  Unless a routine says
  67. X *               otherwise, it may be assumed to require program_name, dpy,
  68. X *               and screen already defined on entry.
  69. X *
  70. X * Written by Mark Lillibridge.   Last updated 7/1/87
  71. X *
  72. X * Send bugs, etc. to chariot@athena.mit.edu.
  73. X */
  74. X
  75. X
  76. X/* This stuff is defined in the calling program by just_display.h */
  77. Xextern char *program_name;
  78. Xextern Display *dpy;
  79. Xextern int screen;
  80. X
  81. X
  82. X/*
  83. X * Standard fatal error routine - call like printf but maximum of 7 arguments.
  84. X * Does not require dpy or screen defined.
  85. X */
  86. Xvoid Fatal_Error(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
  87. Xchar *msg;
  88. Xchar *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
  89. X{
  90. X    fflush(stdout);
  91. X    fflush(stderr);
  92. X    fprintf(stderr, "%s: error: ", program_name);
  93. X    fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
  94. X    fprintf(stderr, "\n");
  95. X    exit(1);
  96. X}
  97. X
  98. X
  99. X/*
  100. X * Malloc: like malloc but handles out of memory using Fatal_Error.
  101. X */
  102. Xchar *Malloc(size)
  103. X     unsigned size;
  104. X{
  105. X    char *data, *malloc();
  106. X
  107. X    if (!(data = malloc(size)))
  108. X      Fatal_Error("Out of memory!");
  109. X
  110. X    return(data);
  111. X}
  112. X    
  113. X
  114. X/*
  115. X * Realloc: like Malloc except for realloc, handles NULL using Malloc.
  116. X */
  117. Xchar *Realloc(ptr, size)
  118. X        char *ptr;
  119. X        int size;
  120. X{
  121. X    char *new_ptr, *realloc();
  122. X
  123. X    if (!ptr)
  124. X      return(Malloc(size));
  125. X
  126. X    if (!(new_ptr = realloc(ptr, size)))
  127. X      Fatal_Error("Out of memory!");
  128. X
  129. X    return(new_ptr);
  130. X}
  131. X
  132. X
  133. X/*
  134. X * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
  135. X * If found, remove it from command line.  Don't go past a lone -.
  136. X */
  137. Xchar *Get_Display_Name(pargc, argv)
  138. X    int *pargc;  /* MODIFIED */
  139. X    char **argv; /* MODIFIED */
  140. X{
  141. X    int argc = *pargc;
  142. X    char **pargv = argv+1;
  143. X    char *displayname = NULL;
  144. X    int i;
  145. X
  146. X    for (i = 1; i < argc; i++) {
  147. X    char *arg = argv[i];
  148. X
  149. X    if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
  150. X        if (++i >= argc) usage ();
  151. X
  152. X        displayname = argv[i];
  153. X        *pargc -= 2;
  154. X        continue;
  155. X    }
  156. X    if (!strcmp(arg,"-")) {
  157. X        while (i<argc)
  158. X            *pargv++ = argv[i++];
  159. X        break;
  160. X    }
  161. X    *pargv++ = arg;
  162. X    }
  163. X
  164. X    *pargv = NULL;
  165. X    return (displayname);
  166. X}
  167. X
  168. X
  169. X/*
  170. X * Open_Display: Routine to open a display with correct error handling.
  171. X *               Does not require dpy or screen defined on entry.
  172. X */
  173. XDisplay *Open_Display(display_name)
  174. Xchar *display_name;
  175. X{
  176. X    Display *d;
  177. X
  178. X    d = XOpenDisplay(display_name);
  179. X    if (d == NULL) {
  180. X        fprintf (stderr, "%s:  unable to open display '%s'\n",
  181. X             program_name, XDisplayName (display_name));
  182. X        usage ();
  183. X        /* doesn't return */
  184. X    }
  185. X
  186. X    return(d);
  187. X}
  188. X
  189. X
  190. X/*
  191. X * Setup_Display_And_Screen: This routine opens up the correct display (i.e.,
  192. X *                           it calls Get_Display_Name) and then stores a
  193. X *                           pointer to it in dpy.  The default screen
  194. X *                           for this display is then stored in screen.
  195. X *                           Does not require dpy or screen defined.
  196. X */
  197. Xvoid Setup_Display_And_Screen(argc, argv)
  198. Xint *argc;      /* MODIFIED */
  199. Xchar **argv;    /* MODIFIED */
  200. X{
  201. X    dpy = Open_Display (Get_Display_Name(argc, argv));
  202. X    screen = DefaultScreen(dpy);
  203. X}
  204. X
  205. X
  206. X/*
  207. X * Open_Font: This routine opens a font with error handling.
  208. X */
  209. XXFontStruct *Open_Font(name)
  210. Xchar *name;
  211. X{
  212. X    XFontStruct *font;
  213. X
  214. X    if (!(font=XLoadQueryFont(dpy, name)))
  215. X      Fatal_Error("Unable to open font %s!", name);
  216. X
  217. X    return(font);
  218. X}
  219. X
  220. X
  221. X/*
  222. X * Beep: Routine to beep the display.
  223. X */
  224. Xvoid Beep()
  225. X{
  226. X    XBell(dpy, 50);
  227. X}
  228. X
  229. X
  230. X/*
  231. X * ReadBitmapFile: same as XReadBitmapFile except it returns the bitmap
  232. X *                 directly and handles errors using Fatal_Error.
  233. X */
  234. Xstatic void _bitmap_error(status, filename)
  235. X     int status;
  236. X     char *filename;
  237. X{
  238. X  if (status == BitmapOpenFailed)
  239. X    Fatal_Error("Can't open file %s!", filename);
  240. X  else if (status == BitmapFileInvalid)
  241. X    Fatal_Error("file %s: Bad bitmap format.", filename);
  242. X  else
  243. X    Fatal_Error("Out of memory!");
  244. X}
  245. X
  246. XPixmap ReadBitmapFile(d, filename, width, height, x_hot, y_hot)
  247. X     Drawable d;
  248. X     char *filename;
  249. X     int *width, *height, *x_hot, *y_hot;
  250. X{
  251. X  Pixmap bitmap;
  252. X  int status;
  253. X
  254. X  status = XReadBitmapFile(dpy, RootWindow(dpy, screen), filename, width,
  255. X               height, &bitmap, x_hot, y_hot);
  256. X  if (status != BitmapSuccess)
  257. X    _bitmap_error(status, filename);
  258. X
  259. X  return(bitmap);
  260. X}
  261. X
  262. X
  263. X/*
  264. X * WriteBitmapFile: same as XWriteBitmapFile except it handles errors
  265. X *                  using Fatal_Error.
  266. X */
  267. Xvoid WriteBitmapFile(filename, bitmap, width, height, x_hot, y_hot)
  268. X     char *filename;
  269. X     Pixmap bitmap;
  270. X     int width, height, x_hot, y_hot;
  271. X{
  272. X  int status;
  273. X
  274. X  status= XWriteBitmapFile(dpy, filename, bitmap, width, height, x_hot,
  275. X               y_hot);
  276. X  if (status != BitmapSuccess)
  277. X    _bitmap_error(status, filename);
  278. X}
  279. X
  280. X
  281. X/*
  282. X * Select_Window_Args: a rountine to provide a common interface for
  283. X *                     applications that need to allow the user to select one
  284. X *                     window on the screen for special consideration.
  285. X *                     This routine implements the following command line
  286. X *                     arguments:
  287. X *
  288. X *                       -root            Selects the root window.
  289. X *                       -id <id>         Selects window with id <id>. <id> may
  290. X *                                        be either in decimal or hex.
  291. X *                       -name <name>     Selects the window with name <name>.
  292. X *
  293. X *                     Call as Select_Window_Args(&argc, argv) in main before
  294. X *                     parsing any of your program's command line arguments.
  295. X *                     Select_Window_Args will remove its arguments so that
  296. X *                     your program does not have to worry about them.
  297. X *                     The window returned is the window selected or 0 if
  298. X *                     none of the above arguments was present.  If 0 is
  299. X *                     returned, Select_Window should probably be called after
  300. X *                     all command line arguments, and other setup is done.
  301. X *                     For examples of usage, see xwininfo, xwd, or xprop.
  302. X */
  303. XWindow Select_Window_Args(rargc, argv)
  304. X     int *rargc;
  305. X     char **argv;
  306. X#define ARGC (*rargc)
  307. X{
  308. X    int nargc=1;
  309. X    int argc;
  310. X    char **nargv;
  311. X    Window w=0;
  312. X
  313. X    nargv = argv+1; argc = ARGC;
  314. X#define OPTION argv[0]
  315. X#define NXTOPTP ++argv, --argc>0
  316. X#define NXTOPT if (++argv, --argc==0) usage()
  317. X#define COPYOPT nargv++[0]=OPTION; nargc++
  318. X
  319. X    while (NXTOPTP) {
  320. X        if (!strcmp(OPTION, "-")) {
  321. X            COPYOPT;
  322. X            while (NXTOPTP)
  323. X              COPYOPT;
  324. X            break;
  325. X        }
  326. X        if (!strcmp(OPTION, "-root")) {
  327. X            w=RootWindow(dpy, screen);
  328. X            continue;
  329. X        }
  330. X        if (!strcmp(OPTION, "-name")) {
  331. X            NXTOPT;
  332. X            w = Window_With_Name(dpy, RootWindow(dpy, screen),
  333. X                         OPTION);
  334. X            if (!w)
  335. X              Fatal_Error("No window with name %s exists!",OPTION);
  336. X            continue;
  337. X        }
  338. X        if (!strcmp(OPTION, "-id")) {
  339. X            NXTOPT;
  340. X            w=0;
  341. X            sscanf(OPTION, "0x%lx", &w);
  342. X            if (!w)
  343. X              sscanf(OPTION, "%ld", &w);
  344. X            if (!w)
  345. X              Fatal_Error("Invalid window id format: %s.", OPTION);
  346. X            continue;
  347. X        }
  348. X        COPYOPT;
  349. X    }
  350. X    ARGC = nargc;
  351. X    
  352. X    return(w);
  353. X}
  354. X
  355. X/*
  356. X * Other_stuff: A group of routines which do common X11 tasks.
  357. X *
  358. X * Written by Mark Lillibridge.   Last updated 7/1/87
  359. X *
  360. X * Send bugs, etc. to chariot@athena.mit.edu.
  361. X */
  362. X
  363. X
  364. X#define NULL 0
  365. X
  366. Xextern Display *dpy;
  367. Xextern int screen;
  368. X
  369. X/*
  370. X * Resolve_Color: This routine takes a color name and returns the pixel #
  371. X *                that when used in the window w will be of color name.
  372. X *                (WARNING:  The colormap of w MAY be modified! )
  373. X *                If colors are run out of, only the first n colors will be
  374. X *                as correct as the hardware can make them where n depends
  375. X *                on the display.  This routine does not require wind to
  376. X *                be defined.
  377. X */
  378. Xunsigned long Resolve_Color(w, name)
  379. X     Window w;
  380. X     char *name;
  381. X{
  382. X    XColor c;
  383. X    Colormap colormap;
  384. X    XWindowAttributes wind_info;
  385. X
  386. X    /*
  387. X     * The following is a hack to insure machines without a rgb table
  388. X     * handle at least white & black right.
  389. X     */
  390. X    if (!strcmp(name, "white"))
  391. X      name="#ffffffffffff";
  392. X    if (!strcmp(name, "black"))
  393. X      name="#000000000000";
  394. X
  395. X    XGetWindowAttributes(dpy, w, &wind_info);
  396. X    colormap = wind_info.colormap;
  397. X
  398. X    if (!XParseColor(dpy, colormap, name, &c))
  399. X      Fatal_Error("Bad color format '%s'.", name);
  400. X
  401. X    if (!XAllocColor(dpy, colormap, &c))
  402. X      Fatal_Error("XAllocColor failed!");
  403. X
  404. X    return(c.pixel);
  405. X}
  406. X
  407. X
  408. X/*
  409. X * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap.  The colors come
  410. X *                   from the foreground and background colors of the gc.
  411. X *                   Width and height are required solely for efficiency.
  412. X *                   If needed, they can be obtained via. XGetGeometry.
  413. X */
  414. XPixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height)
  415. X     Display *dpy;
  416. X     Drawable d;
  417. X     GC gc;
  418. X     Pixmap bitmap;
  419. X     int width, height;
  420. X{
  421. X  Pixmap pix;
  422. X  int x, depth;
  423. X  Drawable root;
  424. X
  425. X  if (!XGetGeometry(dpy, d, &root, &x, &x, &x, &x, &x, &depth))
  426. X    return(0);
  427. X
  428. X  pix = XCreatePixmap(dpy, d, width, height, depth);
  429. X
  430. X  XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1);
  431. X
  432. X  return(pix);
  433. X}
  434. X
  435. X
  436. X/*
  437. X * outl: a debugging routine.  Flushes stdout then prints a message on stderr
  438. X *       and flushes stderr.  Used to print messages when past certain points
  439. X *       in code so we can tell where we are.  Outl may be invoked like
  440. X *       printf with up to 7 arguments.
  441. X */
  442. Xoutl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
  443. X     char *msg;
  444. X     char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
  445. X{
  446. X    fflush(stdout);
  447. X    fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
  448. X    fprintf(stderr, "\n");
  449. X    fflush(stderr);
  450. X}
  451. X
  452. X
  453. X/*
  454. X * blip: a debugging routine.  Prints Blip! on stderr with flushing. 
  455. X */
  456. Xvoid blip()
  457. X{
  458. X  outl("blip!");
  459. X}
  460. X
  461. X
  462. X/*
  463. X * Routine to let user select a window using the mouse
  464. X */
  465. X
  466. XWindow Select_Window(dpy)
  467. X     Display *dpy;
  468. X{
  469. X  int status;
  470. X  Cursor cursor;
  471. X  XEvent event;
  472. X  Window target_win = None;
  473. X  int buttons = 0;
  474. X
  475. X  /* Make the target cursor */
  476. X  cursor = XCreateFontCursor(dpy, XC_dot);
  477. X
  478. X  /* Grab the pointer using target cursor, letting it room all over */
  479. X  status = XGrabPointer(dpy, RootWindow(dpy, screen), False,
  480. X            ButtonPressMask|ButtonReleaseMask, GrabModeSync,
  481. X            GrabModeAsync, None, cursor, CurrentTime);
  482. X  if (status != GrabSuccess) Fatal_Error("Can't grab the mouse.");
  483. X
  484. X  /* Let the user select a window... */
  485. X  while ((target_win == None) || (buttons != 0)) {
  486. X    /* allow one more event */
  487. X    XAllowEvents(dpy, SyncPointer, CurrentTime);
  488. X    XWindowEvent(dpy, RootWindow(dpy, screen),
  489. X         ButtonPressMask|ButtonReleaseMask, &event);
  490. X    switch (event.type) {
  491. X    case ButtonPress:
  492. X      if (target_win == None) {
  493. X    target_win = event.xbutton.subwindow; /* window selected */
  494. X    if (target_win == None)
  495. X      target_win = RootWindow(dpy, screen);
  496. X      }
  497. X      buttons++;
  498. X      break;
  499. X    case ButtonRelease:
  500. X      if (buttons > 0) /* there may have been some down before we started */
  501. X    buttons--;
  502. X       break;
  503. X    }
  504. X  } 
  505. X  XUngrabPointer(dpy, CurrentTime);      /* Done with pointer */
  506. X
  507. X  return(target_win);
  508. X}
  509. X
  510. X
  511. X/*
  512. X * Window_With_Name: routine to locate a window with a given name on a display.
  513. X *                   If no window with the given name is found, 0 is returned.
  514. X *                   If more than one window has the given name, the first
  515. X *                   one found will be returned.  Only top and its subwindows
  516. X *                   are looked at.  Normally, top should be the RootWindow.
  517. X */
  518. XWindow Window_With_Name(dpy, top, name)
  519. X     Display *dpy;
  520. X     Window top;
  521. X     char *name;
  522. X{
  523. X    Window *children, dummy;
  524. X    int nchildren, i;
  525. X    Window w=0;
  526. X    char *window_name;
  527. X
  528. X    if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
  529. X      return(top);
  530. X
  531. X    if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
  532. X      return(0);
  533. X
  534. X    for (i=0; i<nchildren; i++) {
  535. X        w = Window_With_Name(dpy, children[i], name);
  536. X        if (w)
  537. X          break;
  538. X    }
  539. X    XFree(children);
  540. X    return(w);
  541. X}
  542. EOF dsimple.c
  543.     case "`echo \`wc < 'dsimple.c'\``" in
  544.     "499 1633 12545")
  545.         ;;
  546.     *)
  547.         echo "$prog: \"dsimple.c\" corrupted" >&2
  548.         error=1
  549.         ;;
  550.     esac
  551. fi ; : # End of overwrite check
  552. if test -f 'psfile.c' -o -d 'psfile.c'; then
  553.     echo "$prog: \"psfile.c\" exists, skipping" >&2
  554.     error=1
  555. else
  556.     echo 'x - psfile.c'
  557.     sed -e 's/^X//' << 'EOF psfile.c' > 'psfile.c'
  558. X#include "extern.h"
  559. X
  560. Xvoid openImage(psFile,width,height)
  561. X    FILE *psFile;
  562. X    int width, height;
  563. X{
  564. X    fprintf(psFile, "%%!\n");
  565. X    fprintf(psFile, "/inch {72 mul} def\n");
  566. X    fprintf(psFile, "/picstr %d string def\n", width);
  567. X    fprintf(psFile, "/plotimage\n");
  568. X    fprintf(psFile, " {%d %d %d [%d 0 0 %d 0 %d] \n", width, height,
  569. X        BITS_PER_SAMPLE, width, -height, height);
  570. X    fprintf(psFile,"   {currentfile picstr readhexstring pop} \n");
  571. X    fprintf(psFile,"   image\n } def\n");
  572. X    fprintf(psFile, "gsave\n");
  573. X    fprintf(psFile, "%.2f inch %.2f inch translate\n", translateX, translateY);
  574. X    fprintf(psFile, "%.2f inch %.2f inch scale\n", scaleX, scaleY);
  575. X    fprintf(psFile, "%d rotate\n", rotation);
  576. X    fflush(psFile);
  577. X}
  578. X
  579. Xvoid closeImage(psFile)
  580. X    FILE *psFile;
  581. X{
  582. X    fprintf(psFile, "grestore\n");
  583. X    fprintf(psFile, "showpage\n");
  584. X    fflush(psFile);
  585. X}
  586. Xvoid writeImage(psFile, ximage, width, height)
  587. X     FILE *psFile;
  588. X     XImage *ximage;
  589. X     int width, height;
  590. X{
  591. X    int x, y;
  592. X    XColor *pix;
  593. X
  594. X    pix = (XColor *)malloc(sizeof(XColor));
  595. X    /* Output is hexadecimal */
  596. X    fprintf(psFile, "plotimage\n");
  597. X    for(y=0;y<height;y++){
  598. X        for(x=0;x<width;x++){
  599. X        pix->pixel = XGetPixel(ximage,x,y);
  600. X        pix->red = (pix->pixel >> 16 & 0xFF);
  601. X        pix->green = (pix->pixel >> 8 & 0xFF);
  602. X        pix->blue = (pix->pixel & 0xFF);
  603. X        pix->pixel = luminance(*pix);
  604. X        fprintf(psFile, "%02x", pix->pixel);
  605. X        }
  606. X        fprintf(psFile, "\n");
  607. X    }
  608. X    fprintf(psFile, "\n");
  609. X}
  610. X
  611. Xint luminance(colorSpec)
  612. X XColor colorSpec;
  613. X{
  614. X    int r, g, b, l;
  615. X
  616. X    r = 255 - (colorSpec.red);
  617. X    g = 255 - (colorSpec.green);
  618. X    b = 255 - (colorSpec.blue);
  619. X    l = (0.33*r) + (0.33*g) + (0.34*b);
  620. X    if(inverse) return(l);
  621. X    else return(abs(l - 255));
  622. X}
  623. X
  624. EOF psfile.c
  625.     case "`echo \`wc < 'psfile.c'\``" in
  626.     "67 193 1742")
  627.         ;;
  628.     *)
  629.         echo "$prog: \"psfile.c\" corrupted" >&2
  630.         error=1
  631.         ;;
  632.     esac
  633. fi ; : # End of overwrite check
  634. if test -f 'xwps.c' -o -d 'xwps.c'; then
  635.     echo "$prog: \"xwps.c\" exists, skipping" >&2
  636.     error=1
  637. else
  638.     echo 'x - xwps.c'
  639.     sed -e 's/^X//' << 'EOF xwps.c' > 'xwps.c'
  640. X#include <X11/copyright.h>
  641. X
  642. X/* Copyright 1987 Massachusetts Institute of Technology */
  643. X
  644. X/*
  645. X * xwd.c MIT Project Athena, X Window system window raster image dumper.
  646. X *
  647. X * This program will dump a raster image of the contents of a window into a 
  648. X * file for output on graphics printers or for other uses.
  649. X *
  650. X *  Author:    Tony Della Fera, DEC
  651. X *        17-Jun-85
  652. X * 
  653. X *  Modification history:
  654. X *
  655. X *  11/14/86 Bill Wyatt, Smithsonian Astrophysical Observatory
  656. X *    - Removed Z format option, changing it to an XY option. Monochrome 
  657. X *      windows will always dump in XY format. Color windows will dump
  658. X *      in Z format by default, but can be dumped in XY format with the
  659. X *      -xy option.
  660. X *
  661. X *  11/18/86 Bill Wyatt
  662. X *    - VERSION 6 is same as version 5 for monchrome. For colors, the 
  663. X *      appropriate number of Color structs are dumped after the header,
  664. X *      which has the number of colors (=0 for monochrome) in place of the
  665. X *      V5 padding at the end. Up to 16-bit displays are supported. I
  666. X *      don't yet know how 24- to 32-bit displays will be handled under
  667. X *      the Version 11 protocol.
  668. X *
  669. X *  6/15/87 David Krikorian, MIT Project Athena
  670. X *    - VERSION 7 runs under the X Version 11 servers, while the previous
  671. X *      versions of xwd were are for X Version 10.  This version is based
  672. X *      on xwd version 6, and should eventually have the same color
  673. X *      abilities. (Xwd V7 has yet to be tested on a color machine, so
  674. X *      all color-related code is commented out until color support
  675. X *      becomes practical.)
  676. X */
  677. X
  678. X#ifndef lint
  679. Xstatic char *rcsid_xwd_c = "$Header: xwd.c,v 1.34 88/02/12 13:24:59 jim Exp $";
  680. X#endif
  681. X
  682. X/*%
  683. X *%    This is the format for commenting out color-related code until
  684. X *%  color can be supported.
  685. X */
  686. X
  687. X#define FEEP_VOLUME 0
  688. X#define DECLARE
  689. X#include "extern.h"
  690. X
  691. X/* Include routines to do parsing */
  692. X#include "dsimple.h"
  693. X
  694. Xextern int (*_XErrorFunction)();
  695. Xextern int _XDefaultError();
  696. X
  697. Xmain(argc, argv)
  698. X    int argc;
  699. X    char **argv;
  700. X{
  701. X    register i;
  702. X    FILE *fopen();
  703. X
  704. X    INIT_NAME;
  705. X
  706. X    Setup_Display_And_Screen(&argc, argv);
  707. X
  708. X    /* Get window select on command line, if any */
  709. X    target_win = Select_Window_Args(&argc, argv);
  710. X
  711. X    for (i = 1; i < argc; i++) {
  712. X    if (!strcmp(argv[i], "-borders")) {
  713. X        bdrs = False;
  714. X        continue;
  715. X    }
  716. X    if (!strcmp(argv[i], "-debug")) {
  717. X        debug = True;
  718. X        continue;
  719. X    }
  720. X    if (!strcmp(argv[i], "-help"))
  721. X      usage();
  722. X    if (!strcmp(argv[i], "-out")) {
  723. X        if (++i >= argc) usage();
  724. X        if (!(out_file = fopen(argv[i], "w"))){
  725. X          Error("Can't open output file as specified.");
  726. X          out_file = stdout;
  727. X        }
  728. X        continue;
  729. X    }
  730. X    if (!strcmp(argv[i], "-xy")) {
  731. X        format = XYPixmap;
  732. X        continue;
  733. X    }
  734. X    if(!strcmp(argv[i], "-rot")) {
  735. X        sscanf(argv[++i],"%d",&rotation); 
  736. X        continue;
  737. X    }
  738. X    if(!strcmp(argv[i], "-scale")){
  739. X        sscanf(argv[++i],"%d",&scaleX);
  740. X        sscanf(argv[++i],"%d",&scaleY);
  741. X        continue;
  742. X    }
  743. X    if(!strcmp(argv[i],"-off")){
  744. X        sscanf(argv[++i],"%d",&translateX);
  745. X        sscanf(argv[++i],"%d",&translateY);
  746. X        continue;
  747. X    }
  748. X    if(!strcmp(argv[i],"-inv")){
  749. X        inverse = 1;
  750. X        continue;
  751. X    }
  752. X        
  753. X    usage();
  754. X    }
  755. X    
  756. X    /*
  757. X     * Let the user select the target window.
  758. X     */
  759. X    if (!target_win)
  760. X      target_win = Select_Window(dpy);
  761. X
  762. X    /*
  763. X     * Dump the window 
  764. X     */
  765. X    Window_Dump(target_win,out_file);
  766. X
  767. X    fclose(out_file);
  768. X
  769. X
  770. X
  771. X}
  772. X
  773. X
  774. X/*
  775. X * Window_Dump: dump a window to a file which must already be open for
  776. X *              writting.
  777. X */
  778. X
  779. Xchar *calloc();
  780. X
  781. X#include "X11/XWDFile.h"
  782. X
  783. XWindow_Dump(window, out)
  784. X     Window window;
  785. X     FILE *out;
  786. X{
  787. X    unsigned long swaptest = 1;
  788. X    XColor *colors;
  789. X    unsigned buffer_size;
  790. X    int win_name_size;
  791. X    int header_size;
  792. X    int ncolors, i;
  793. X    char *win_name;
  794. X    XWindowAttributes win_info;
  795. X    XImage *image;
  796. X
  797. X    XWDFileHeader header;
  798. X
  799. X    
  800. X    /*
  801. X     * Inform the user not to alter the screen.
  802. X     */
  803. X    Beep();
  804. X
  805. X    /*
  806. X     * Get the parameters of the window being dumped.
  807. X     */
  808. X    if (debug) outl("xwd: Getting target window information.\n");
  809. X    if(!XGetWindowAttributes(dpy, window, &win_info)) 
  810. X      Fatal_Error("Can't get target window attributes.");
  811. X
  812. X    XFetchName(dpy, window, &win_name);
  813. X    if (!win_name || !win_name[0])
  814. X      win_name = "xwdump";
  815. X
  816. X    /* sizeof(char) is included for the null string terminator. */
  817. X    win_name_size = strlen(win_name) + sizeof(char);
  818. X
  819. X    /*
  820. X     * Snarf the pixmap with XGetImage.
  821. X     */
  822. X
  823. X    if (!bdrs) {
  824. X          if (debug) outl("xwd: Image without borders selected.\n");
  825. X    image = XGetImage ( dpy, window, 0, 0, win_info.width,
  826. X               win_info.height, ~0, format); 
  827. X      }
  828. X    else {
  829. X    if (debug) outl("xwd: Image with borders selected.\n");
  830. X    image = XGetImage ( dpy, window,
  831. X               -win_info.border_width, -win_info.border_width, 
  832. X               win_info.width + (win_info.border_width << 1),
  833. X               win_info.height + (win_info.border_width << 1),
  834. X               ~0, format); 
  835. X      }
  836. X    if (debug) outl("xwd: Getting pixmap.\n");
  837. X
  838. X    /*
  839. X     * Determine the pixmap size.
  840. X     */
  841. X    buffer_size = Image_Size(image);
  842. X
  843. X    if (debug) outl("xwd: Getting Colors.\n");
  844. X
  845. X    ncolors = Get_XColors(&win_info, &colors);
  846. X
  847. X    /*
  848. X     * Inform the user that the image has been retrieved.
  849. X     */
  850. X    XBell(dpy, FEEP_VOLUME);
  851. X    XBell(dpy, FEEP_VOLUME);
  852. X    XFlush(dpy);
  853. X
  854. X    /*
  855. X     * Calculate header size.
  856. X     */
  857. X    if (debug) outl("xwd: Calculating header size.\n");
  858. X    header_size = sizeof(header) + win_name_size;
  859. X
  860. X    /*
  861. X     * Write out header information.
  862. X     */
  863. X    if (debug) outl("xwd: Constructing and dumping file header.\n");
  864. X    header.header_size = (xwdval) header_size;
  865. X    header.file_version = (xwdval) XWD_FILE_VERSION;
  866. X    header.pixmap_format = (xwdval) format;
  867. X    header.pixmap_depth = (xwdval) image->depth;
  868. X    header.pixmap_width = (xwdval) image->width;
  869. X    header.pixmap_height = (xwdval) image->height;
  870. X    header.xoffset = (xwdval) image->xoffset;
  871. X    header.byte_order = (xwdval) image->byte_order;
  872. X    header.bitmap_unit = (xwdval) image->bitmap_unit;
  873. X    header.bitmap_bit_order = (xwdval) image->bitmap_bit_order;
  874. X    header.bitmap_pad = (xwdval) image->bitmap_pad;
  875. X    header.bits_per_pixel = (xwdval) image->bits_per_pixel;
  876. X    header.bytes_per_line = (xwdval) image->bytes_per_line;
  877. X    header.visual_class = (xwdval) win_info.visual->class;
  878. X    header.red_mask = (xwdval) win_info.visual->red_mask;
  879. X    header.green_mask = (xwdval) win_info.visual->green_mask;
  880. X    header.blue_mask = (xwdval) win_info.visual->blue_mask;
  881. X    header.bits_per_rgb = (xwdval) win_info.visual->bits_per_rgb;
  882. X    header.colormap_entries = (xwdval) win_info.visual->map_entries;
  883. X    header.ncolors = ncolors;
  884. X    header.window_width = (xwdval) win_info.width;
  885. X    header.window_height = (xwdval) win_info.height;
  886. X    if (!bdrs) {
  887. X      header.window_x = (xwdval) (win_info.x + win_info.border_width);
  888. X      header.window_y = (xwdval) (win_info.y + win_info.border_width);
  889. X    } else {
  890. X      header.window_x = (xwdval) win_info.x;
  891. X      header.window_y = (xwdval) win_info.y;
  892. X    }
  893. X    header.window_bdrwidth = (xwdval) win_info.border_width;
  894. X
  895. X    if (*(char *) &swaptest) {
  896. X    _swaplong((char *) &header, sizeof(header));
  897. X    for (i = 0; i < ncolors; i++) {
  898. X        _swaplong((char *) &colors[i].pixel, sizeof(long));
  899. X        _swapshort((char *) &colors[i].red, 3 * sizeof(short));
  900. X    }
  901. X    }
  902. X
  903. X    /*
  904. X     * (void) fwrite((char *)&header, sizeof(header), 1, out);
  905. X     * (void) fwrite(win_name, win_name_size, 1, out);
  906. X     */
  907. X
  908. X     openImage(out, header.pixmap_width, header.pixmap_height);
  909. X     writeImage(out,image,header.pixmap_width, header.pixmap_height);
  910. X     closeImage(out);
  911. X
  912. X    /*
  913. X     * Write out the color maps, if any
  914. X     */
  915. X
  916. X    /*
  917. X     * if (debug) outl("xwd: Dumping %d colors.\n", ncolors);
  918. X     * (void) fwrite((char *) colors, sizeof(XColor), ncolors, out);
  919. X     */
  920. X
  921. X    /*
  922. X     * Write out the buffer.
  923. X     */
  924. X    if (debug) outl("xwd: Dumping pixmap.  bufsize=%d\n",buffer_size);
  925. X
  926. X    /*
  927. X     *    This copying of the bit stream (data) to a file is to be replaced
  928. X     *  by an Xlib call which hasn't been written yet.  It is not clear
  929. X     *  what other functions of xwd will be taken over by this (as yet)
  930. X     *  non-existant X function.
  931. X     */
  932. X
  933. X    /* 
  934. X     * (void) fwrite(image->data, (int) buffer_size, 1, out);
  935. X     */
  936. X
  937. X    /*
  938. X     * free the color buffer.
  939. X     */
  940. X
  941. X    if(debug && ncolors > 0) outl("xwd: Freeing colors.\n");
  942. X    if(ncolors > 0) free(colors);
  943. X
  944. X    /*
  945. X     * Free window name string.
  946. X     *
  947. X    if (debug) outl("xwd: Freeing window name string.\n");
  948. X    free((char *)win_name);
  949. X    */
  950. X
  951. X    /*
  952. X     * Free image
  953. X     */
  954. X    XDestroyImage(image);
  955. X}
  956. X
  957. X/*
  958. X * Report the syntax for calling xwd.
  959. X */
  960. Xusage()
  961. X{
  962. X    fprintf (stderr,
  963. X"usage: %s [-display host:dpy] [-debug] [-help] [-borders] [-out <file>]",
  964. X       program_name);
  965. X    fprintf (stderr, " [-xy]\n\t[-rot <rotation>] [-scale <x y>] [-off <x y>] [-inv]\n");
  966. X    exit(1);
  967. X}
  968. X
  969. X
  970. X/*
  971. X * Error - Fatal xwd error.
  972. X */
  973. Xextern int errno;
  974. X
  975. XError(string)
  976. X    char *string;    /* Error description string. */
  977. X{
  978. X    outl("\nxwd: Error => %s\n", string);
  979. X    if (errno != 0) {
  980. X        perror("xwd");
  981. X        outl("\n");
  982. X    }
  983. X
  984. X    exit(1);
  985. X}
  986. X
  987. X
  988. X/*
  989. X * Determine the pixmap size.
  990. X */
  991. X
  992. Xint Image_Size(image)
  993. X     XImage *image;
  994. X{
  995. X    if (format != ZPixmap)
  996. X      return(image->bytes_per_line * image->height * image->depth);
  997. X
  998. X    return(image->bytes_per_line * image->height);
  999. X}
  1000. X
  1001. X
  1002. X/*
  1003. X * Get the XColors of all pixels in image - returns # of colors
  1004. X */
  1005. Xint Get_XColors(win_info, colors)
  1006. X     XWindowAttributes *win_info;
  1007. X     XColor **colors;
  1008. X{
  1009. X    int i, ncolors;
  1010. X
  1011. X    if (!win_info->colormap)
  1012. X    return(0);
  1013. X
  1014. X    if (win_info->visual->class == TrueColor ||
  1015. X    win_info->visual->class == DirectColor)
  1016. X    return(0);    /* XXX punt for now */
  1017. X
  1018. X    ncolors = win_info->visual->map_entries;
  1019. X    if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
  1020. X      Fatal_Error("Out of memory!");
  1021. X
  1022. X    for (i=0; i<ncolors; i++)
  1023. X      (*colors)[i].pixel = i;
  1024. X
  1025. X    XQueryColors(dpy, win_info->colormap, *colors, ncolors);
  1026. X    
  1027. X    return(ncolors);
  1028. X}
  1029. X
  1030. X_swapshort (bp, n)
  1031. X    register char *bp;
  1032. X    register unsigned n;
  1033. X{
  1034. X    register char c;
  1035. X    register char *ep = bp + n;
  1036. X
  1037. X    while (bp < ep) {
  1038. X    c = *bp;
  1039. X    *bp = *(bp + 1);
  1040. X    bp++;
  1041. X    *bp++ = c;
  1042. X    }
  1043. X}
  1044. X
  1045. X_swaplong (bp, n)
  1046. X    register char *bp;
  1047. X    register unsigned n;
  1048. X{
  1049. X    register char c;
  1050. X    register char *ep = bp + n;
  1051. X    register char *sp;
  1052. X
  1053. X    while (bp < ep) {
  1054. X    sp = bp + 3;
  1055. X    c = *sp;
  1056. X    *sp = *bp;
  1057. X    *bp++ = c;
  1058. X    sp = bp + 1;
  1059. X    c = *sp;
  1060. X    *sp = *bp;
  1061. X    *bp++ = c;
  1062. X    bp += 2;
  1063. X    }
  1064. X}
  1065. EOF xwps.c
  1066.     case "`echo \`wc < 'xwps.c'\``" in
  1067.     "425 1295 10482")
  1068.         ;;
  1069.     *)
  1070.         echo "$prog: \"xwps.c\" corrupted" >&2
  1071.         error=1
  1072.         ;;
  1073.     esac
  1074. fi ; : # End of overwrite check
  1075. if test -f 'dsimple.h' -o -d 'dsimple.h'; then
  1076.     echo "$prog: \"dsimple.h\" exists, skipping" >&2
  1077.     error=1
  1078. else
  1079.     echo 'x - dsimple.h'
  1080.     sed -e 's/^X//' << 'EOF dsimple.h' > 'dsimple.h'
  1081. X/* $Header: dsimple.h,v 1.1 87/09/11 08:17:50 toddb Exp $ */
  1082. X/*
  1083. X * Just_display.h: This file contains the definitions needed to use the
  1084. X *                 functions in just_display.c.  It also declares the global
  1085. X *                 variables dpy, screen, and program_name which are needed to
  1086. X *                 use just_display.c.
  1087. X *
  1088. X * Written by Mark Lillibridge.   Last updated 7/1/87
  1089. X *
  1090. X * Send bugs, etc. to chariot@athena.mit.edu.
  1091. X */
  1092. X
  1093. X    /* Global variables used by routines in just_display.c */
  1094. X
  1095. Xchar *program_name = "unknown_program";       /* Name of this program */
  1096. XDisplay *dpy;                                 /* The current display */
  1097. Xint screen;                                   /* The current screen */
  1098. X
  1099. X#define INIT_NAME program_name=argv[0]        /* use this in main to setup
  1100. X                                                 program_name */
  1101. X
  1102. X    /* Declaritions for functions in just_display.c */
  1103. X
  1104. Xvoid Fatal_Error();
  1105. Xchar *Malloc();
  1106. Xchar *Realloc();
  1107. Xchar *Get_Display_Name();
  1108. XDisplay *Open_Display();
  1109. Xvoid Setup_Display_And_Screen();
  1110. XXFontStruct *Open_Font();
  1111. Xvoid Beep();
  1112. XPixmap ReadBitmapFile();
  1113. Xvoid WriteBitmapFile();
  1114. XWindow Select_Window_Args();
  1115. X
  1116. X#define X_USAGE "[host:display]"              /* X arguments handled by
  1117. X                         Get_Display_Name */
  1118. X#define SELECT_USAGE "[{-root|-id <id>|-font <font>|-name <name>}]"
  1119. X
  1120. X/*
  1121. X * Other_stuff.h: Definitions of routines in other_stuff.
  1122. X *
  1123. X * Written by Mark Lillibridge.   Last updated 7/1/87
  1124. X *
  1125. X * Send bugs, etc. to chariot@athena.mit.edu.
  1126. X */
  1127. X
  1128. Xunsigned long Resolve_Color();
  1129. XPixmap Bitmap_To_Pixmap();
  1130. XWindow Select_Window();
  1131. Xvoid out();
  1132. Xvoid blip();
  1133. XWindow Window_With_Name();
  1134. EOF dsimple.h
  1135.     case "`echo \`wc < 'dsimple.h'\``" in
  1136.     "53 189 1648")
  1137.         ;;
  1138.     *)
  1139.         echo "$prog: \"dsimple.h\" corrupted" >&2
  1140.         error=1
  1141.         ;;
  1142.     esac
  1143. fi ; : # End of overwrite check
  1144. if test -f 'extern.h' -o -d 'extern.h'; then
  1145.     echo "$prog: \"extern.h\" exists, skipping" >&2
  1146.     error=1
  1147. else
  1148.     echo 'x - extern.h'
  1149.     sed -e 's/^X//' << 'EOF extern.h' > 'extern.h'
  1150. X/*    List of external variable and headers to be included in xwps    */
  1151. X
  1152. X#include <X11/Xos.h>
  1153. X#include <X11/Xlib.h>
  1154. X#include <X11/Xutil.h>
  1155. X#include <stdio.h>
  1156. X#include <signal.h>
  1157. X
  1158. X#define SAVE    0
  1159. X#define PRINT    1
  1160. X#define FILENAME    "xwpsfile"
  1161. X#define BITS_PER_SAMPLE 8
  1162. X
  1163. X#ifdef DECLARE
  1164. X    Bool debug        = False;
  1165. X    Bool inverse    = False;    /* inverse Flag */
  1166. X    Bool bdrs        = True;        /* borders Flag */
  1167. X    Bool output        = PRINT;    /* Save to File or Print */
  1168. X    int format        = ZPixmap;    /* XYBitmap, XYPixmap, ZPixmap */
  1169. X    int rotation    = 0;        /* In degrees counterclockwise */
  1170. X    float scaleX    = 6.0;        /* In inches */
  1171. X    float scaleY    = 6.0;        /* In inches */
  1172. X    float translateX    = 1.0;        /* In inches */
  1173. X    float translateY    = 1.0;        /* In inches */
  1174. X
  1175. X    Window target_win;            /* User selected target window */
  1176. X    FILE *out_file    = stdout;    /* File to save to */
  1177. X#else
  1178. X    extern Bool debug, inverse, bdrs, output;
  1179. X    extern int format, rotation;
  1180. X    extern float scaleX, scaleY, translateX, translateY;
  1181. X    extern Window target_win;
  1182. X    extern FILE *out_file;
  1183. X#endif
  1184. X
  1185. X
  1186. EOF extern.h
  1187.     case "`echo \`wc < 'extern.h'\``" in
  1188.     "36 160 1051")
  1189.         ;;
  1190.     *)
  1191.         echo "$prog: \"extern.h\" corrupted" >&2
  1192.         error=1
  1193.         ;;
  1194.     esac
  1195. fi ; : # End of overwrite check
  1196. if test -f 'Makefile' -o -d 'Makefile'; then
  1197.     echo "$prog: \"Makefile\" exists, skipping" >&2
  1198.     error=1
  1199. else
  1200.     echo 'x - Makefile'
  1201.     sed -e 's/^X//' << 'EOF Makefile' > 'Makefile'
  1202. X#
  1203. X#     Makefile for XWD -> XWPS: Xwindow Dump to a Postscript  format
  1204. X#
  1205. X
  1206. XXLIBS =  -lX 
  1207. XCFLAGS = -g
  1208. Xsrc = xwps.c dsimple.c psfile.c 
  1209. Xobj = xwps.o dsimple.o psfile.o 
  1210. Xheaders = dsimple.h extern.h
  1211. XDEST = ./xwps
  1212. X
  1213. Xxwps: $(obj)
  1214. X    $(CC) $(obj) $(XLIBS) -o $(DEST)
  1215. X
  1216. X$(obj): $(headers)
  1217. X
  1218. Xall: xwps clean
  1219. X    
  1220. Xclean:
  1221. X    rm -f $(obj)
  1222. EOF Makefile
  1223.     case "`echo \`wc < 'Makefile'\``" in
  1224.     "20 53 314")
  1225.         ;;
  1226.     *)
  1227.         echo "$prog: \"Makefile\" corrupted" >&2
  1228.         error=1
  1229.         ;;
  1230.     esac
  1231. fi ; : # End of overwrite check
  1232. if test -f 'README' -o -d 'README'; then
  1233.     echo "$prog: \"README\" exists, skipping" >&2
  1234.     error=1
  1235. else
  1236.     echo 'x - README'
  1237.     sed -e 's/^X//' << 'EOF README' > 'README'
  1238. XWell here it is. This works for my release of X11 which is R2 I think.
  1239. XYou will notice quite a few extra external variables hanging around, this is because
  1240. XI had to rip out the widget part. Also there is some X code in xwps.c that I
  1241. Xdidn't want to mess with because I didn't know if it was doing something.
  1242. EOF README
  1243.     case "`echo \`wc < 'README'\``" in
  1244.     "4 62 307")
  1245.         ;;
  1246.     *)
  1247.         echo "$prog: \"README\" corrupted" >&2
  1248.         error=1
  1249.         ;;
  1250.     esac
  1251. fi ; : # End of overwrite check
  1252. : # End of shell archive
  1253. exit $error
  1254.  
  1255. Benjamin Chen
  1256. Office:   550-A4 Cory Hall, 2-4332
  1257. UUCP:     !ucbvax!esvax!bchen               
  1258. HEPNET:   LBL::"bchen@esvax.Berkeley.EDU"
  1259.