home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / imagemagic / part17 < prev    next >
Text File  |  1991-05-23  |  75KB  |  2,212 lines

  1. Path: uunet!uunet!elroy.jpl.nasa.gov!usc!apple!sun-barr!newstop!exodus!dupont.com!cristy
  2. From: cristy@dupont.com
  3. Newsgroups: comp.sources.x
  4. Subject: v13i033: ImageMagick - Graphics display programs, Part17/21
  5. Message-ID: <13947@exodus.Eng.Sun.COM>
  6. Date: 24 May 91 03:20:24 GMT
  7. References: <csx-13i017:imagemagic@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 2200
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: cristy@dupont.com
  13. Posting-number: Volume 13, Issue 33
  14. Archive-name: imagemagic/part17
  15.  
  16. #!/bin/sh
  17. # this is img.17 (part 17 of ImageMagick)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file ImageMagick/display.c continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 17; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping ImageMagick/display.c'
  35. else
  36. echo 'x - continuing file ImageMagick/display.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
  38. %    3    press and drag to define a region of the image to magnify
  39. %
  40. %  Keys
  41. %    1-9  press to change the level of magnification
  42. %    <    press to half the image size
  43. %    >    press to double the image size
  44. %    /    press to rotate the image 90 degrees clockwise
  45. %    \    press to rotate the image 90 degrees counter-clockwise
  46. %    r    press to reflect the image scanlines
  47. %    o    press to restore the image to its original size
  48. %    w    press to restore the image window to its original size
  49. %    m    press to map or unmap the magnify window
  50. %    i    press to display information about the image
  51. %    n    press to display the next image
  52. %    q    press to discard all images and exit program
  53. %
  54. %
  55. */
  56. X
  57. /*
  58. X  Include declarations.
  59. */
  60. #include "display.h"
  61. #include "image.h"
  62. #include "X.h"
  63. X
  64. /*
  65. X  Define declarations.
  66. */
  67. #define ConstrainMagnifyFactor(image_window,magnify_window,magnify)  \
  68. {  \
  69. X  while ((magnify*image_window->ximage->width) < magnify_window->width)  \
  70. X    magnify<<=1;  \
  71. X  while ((magnify*image_window->ximage->height) < magnify_window->height)  \
  72. X    magnify<<=1;  \
  73. X  if (magnify > magnify_window->width)  \
  74. X    magnify=magnify_window->width;  \
  75. X  if (magnify > magnify_window->height)  \
  76. X    magnify=magnify_window->height;  \
  77. }
  78. #define ConfigureWindowState  0x0001
  79. #define ControlState  0x0002
  80. #define DefaultState  0x0004
  81. #define ExitState  0x0008
  82. #define ImageMappedState  0x0010
  83. #define HighlightState  0x0020
  84. #define InfoMappedState  0x0040
  85. #define MagnifyState  0x0080
  86. #define MagnifyMappedState  0x0100
  87. X
  88. /*
  89. X  Forward declarations.
  90. */
  91. static Cursor
  92. X  XMakeCursor();
  93. X
  94. static unsigned int
  95. X  XReflectImageWindow(),
  96. X  XResizeImageWindow(),
  97. X  XRotateImageWindow();
  98. X
  99. static void
  100. X  XDisplayImageWindow(),
  101. X  XMagnifyImageWindow(),
  102. X  XMakeMagnifyImage(),
  103. X  XMenuWindow(),
  104. X  XPanImageWindow();
  105. X
  106. /*
  107. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  108. %                                                                             %
  109. %                                                                             %
  110. %                                                                             %
  111. %   E r r o r                                                                 %
  112. %                                                                             %
  113. %                                                                             %
  114. %                                                                             %
  115. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  116. %
  117. %  Function Error displays an error message and then terminates the program.
  118. %
  119. %  The format of the Error routine is:
  120. %
  121. %      Error(message,qualifier)
  122. %
  123. %  A description of each parameter follows:
  124. %
  125. %    o message: Specifies the message to display before terminating the
  126. %      program.
  127. %
  128. %    o qualifier: Specifies any qualifier to the message.
  129. %
  130. %
  131. */
  132. void Error(message,qualifier)
  133. char
  134. X  *message,
  135. X  *qualifier;
  136. {
  137. X  (void) fprintf(stderr,"%s: %s",application_name,message);
  138. X  if (qualifier != (char *) NULL)
  139. X    (void) fprintf(stderr," (%s)",qualifier);
  140. X  (void) fprintf(stderr,".\n");
  141. X  exit(1);
  142. }
  143. X
  144. /*
  145. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  146. %                                                                             %
  147. %                                                                             %
  148. %                                                                             %
  149. %   U s a g e                                                                 %
  150. %                                                                             %
  151. %                                                                             %
  152. %                                                                             %
  153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  154. %
  155. %  Function Usage displays the program command syntax.
  156. %
  157. %  The format of the Usage routine is:
  158. %
  159. %      Usage(message,terminate)
  160. %
  161. %  A description of each parameter follows:
  162. %
  163. %    o message: Specifies a specific message to display to the user.
  164. %
  165. %    o terminate: A value other than zero is returned if the program is to 
  166. %      terminate immediately.
  167. %
  168. */
  169. static void Usage(message,terminate)
  170. char
  171. X  *message;
  172. X
  173. unsigned int
  174. X  terminate;
  175. {
  176. X  char
  177. X    **p;
  178. X
  179. X  static char
  180. X    *buttons[]=
  181. X    {
  182. X      "Control-1",
  183. X      "     press and drag to pan the image",
  184. X      "1    press and drag to select a command from a pop-up menu",
  185. X      "2    press and drag to define a region of the image to clip",
  186. X      "3    press and drag to define a region of the image to magnify",
  187. X      (char *) NULL
  188. X    },
  189. X    *keys[]=
  190. X    {
  191. X      "1-9  press to change the level of magnification",
  192. X      "<    press to half the image size",
  193. X      ">    press to double the image size",
  194. X      "/    press to rotate the image 90 degrees clockwise",
  195. X      "\\    press to rotate the image 90 degrees counter-clockwise",
  196. X      "r    press to reflect the image scanlines",
  197. X      "o    press to restore the image to its original size",
  198. X      "w    press to restore the image window to its original size",
  199. X      "m    press to map or unmap the magnify window",
  200. X      "i    press to display information about the image",
  201. X      "n    press to display the next image",
  202. X      "q    press to discard all images and exit program",
  203. X      (char *) NULL
  204. X    },
  205. X    *options[]=
  206. X    {
  207. X      "-backdrop           display image centered on a backdrop",
  208. X      "-clip geometry      preferred size and location of the clipped image",
  209. X      "-colors value       preferred number of colors in the image",
  210. X      "-compress type      compress image: RunlengthEncoded or QEncoded",
  211. X      "-delay seconds      display the next image after pausing",
  212. X      "-display server     display image to this X server",
  213. X      "-dither             apply Floyd/Steinberg error diffusion to image",
  214. X      "-enhance            apply a digital filter to enhance a noisy image",
  215. X      "-gamma value        level of gamma correction",
  216. X      "-geometry geometry  preferred size and location of the image window",
  217. X      "-gray               transform image to gray scale colors",
  218. X      "-inverse            apply color inversion to image",
  219. X      "-magnify value      level of image magnification",
  220. X      "-map type           display image using this Standard Colormap",
  221. X      "-monochrome         transform image to black and white",
  222. X      "-noise              reduce noise with a noise peak elimination filter",
  223. X      "-normalize          tranform image to span the full range of colors",
  224. X      "-print file         write image as Postscript to a file",
  225. X      "-reflect            reflect the image scanlines",
  226. X      "-root               display image on the root window",
  227. X      "-rotate degrees     apply Paeth rotation to the image",
  228. X      "-scale geometry     preferred size factors of the image",
  229. X      "-scene number       image scene number",
  230. X      "-treedepth value    depth of the color classification tree",
  231. X      "-verbose            print detailed information about the image",
  232. X      "-visual type        display image using this visual type",
  233. X      "-write file         write image to a file",
  234. X      (char *) NULL
  235. X    };
  236. X  if (message != (char *) NULL)
  237. X    (void) fprintf(stderr,"Can't continue, %s\n\n",message);
  238. X  (void) fprintf(stderr,
  239. X    "Usage: %s [-options ...] file [ [-options ...] file ...]\n",
  240. X    application_name);
  241. X  (void) fprintf(stderr,"\nWhere options include: \n");
  242. X  for (p=options; *p != (char *) NULL; p++)
  243. X    (void) fprintf(stderr,"  %s\n",*p);
  244. X  (void) fprintf(stderr,
  245. X    "\nIn addition to those listed above, you can specify these standard X\n");
  246. X  (void) fprintf(stderr,
  247. X    "resources as command line options:  -background, -bordercolor,\n");
  248. X  (void) fprintf(stderr,
  249. X    "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name, or\n");
  250. X  (void) fprintf(stderr,"-title.\n");
  251. X  (void) fprintf(stderr,
  252. X    "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  253. X  (void) fprintf(stderr,
  254. X    "example, specify +compress to store the image as uncompressed.\n");
  255. X  (void) fprintf(stderr,
  256. X    "\nSpecify 'file' as '-' for standard input or output.\n");
  257. X  (void) fprintf(stderr,"\nButtons: \n");
  258. X  for (p=buttons; *p != (char *) NULL; p++)
  259. X    (void) fprintf(stderr,"  %s\n",*p);
  260. X  (void) fprintf(stderr,"\nKeys: \n");
  261. X  for (p=keys; *p != (char *) NULL; p++)
  262. X    (void) fprintf(stderr,"  %s\n",*p);
  263. X  if (terminate)
  264. X    exit(1);
  265. }
  266. X
  267. /*
  268. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  269. %                                                                             %
  270. %                                                                             %
  271. %                                                                             %
  272. %   U s e r C o m m a n d                                                     %
  273. %                                                                             %
  274. %                                                                             %
  275. %                                                                             %
  276. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  277. %
  278. %  Function UserCommand makes a transform to the image or image window as
  279. %  specified by a user menu button or keyboard command.
  280. %
  281. %  The format of the UserCommand routine is:
  282. %
  283. %    UserCommand(display,resource_info,info_window,image_window,magnify_window,
  284. %      image,command,timeout,state);
  285. %
  286. %  A description of each parameter follows:
  287. %
  288. %    o display: Specifies a connection to an X server; returned from
  289. %      XOpenDisplay.
  290. %
  291. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  292. %
  293. %    o info_window: Specifies a pointer to a XWindowInfo structure.
  294. %
  295. %    o image_window: Specifies a pointer to a XWindowInfo structure.
  296. %
  297. %    o magnify_window: Specifies a pointer to a XWindowInfo structure.
  298. %
  299. %    o image: Specifies a pointer to a Image structure;  UserCommand
  300. %      may transform the image and return a new image pointer.
  301. %
  302. %    o timeout: Specifies an unsigned long;  UserCommand may modify this
  303. %      value.
  304. %
  305. %    o state: Specifies an unsigned int;  UserCommand may return a
  306. %      modified state.
  307. %
  308. %
  309. */
  310. static void UserCommand(display,resource_info,info_window,image_window,
  311. X  magnify_window,command,image,timeout,state)
  312. Display
  313. X  *display;
  314. X
  315. XXResourceInfo
  316. X  *resource_info;
  317. X
  318. XXWindowInfo
  319. X  *info_window,
  320. X  *image_window,
  321. X  *magnify_window;
  322. X
  323. char
  324. X  *command;
  325. X
  326. Image
  327. X  **image;
  328. X
  329. unsigned long
  330. X  *timeout;
  331. X
  332. unsigned int
  333. X  *state;
  334. {
  335. X  XWindowInfo
  336. X    window;
  337. X
  338. X  XWindowChanges
  339. X    window_changes;
  340. X
  341. X  if (*state & InfoMappedState)
  342. X    XWithdrawWindow(display,info_window->id,info_window->screen);
  343. X  /*
  344. X    Process user command.
  345. X  */
  346. X  switch (*command)
  347. X  {
  348. X    case 'i':
  349. X    {
  350. X      char
  351. X        text[256];
  352. X
  353. X      /*
  354. X        Display information about the image in the info window.
  355. X      */
  356. X      (void) sprintf(text,"[%d] %s %dx%d %s \0",(*image)->scene,
  357. X        (*image)->filename,image_window->ximage->width,
  358. X        image_window->ximage->height,
  359. X        XVisualClassName(info_window->visual_info));
  360. X      if ((*image)->colors > 0)
  361. X        (void) sprintf(text,"%s%dc \0",text,(*image)->colors);
  362. X      info_window->width=XTextWidth(info_window->font_info,text,strlen(text));
  363. X      info_window->height=
  364. X        info_window->font_info->ascent+info_window->font_info->descent+4;
  365. X      XResizeWindow(display,info_window->id,info_window->width,
  366. X        info_window->height);
  367. X      XMapWindow(display,info_window->id);
  368. X      XClearWindow(display,info_window->id);
  369. X      XDrawString(display,info_window->id,info_window->graphic_context,2,
  370. X        info_window->font_info->ascent+2,text,strlen(text));
  371. X      break;
  372. X    }
  373. X    case '<':
  374. X    case '>':
  375. X    {
  376. X      /*
  377. X        Half or double the image size.
  378. X      */
  379. X      window=(*image_window);
  380. X      if (*command == '>')
  381. X        {
  382. X          window.width=image_window->ximage->width << 1;
  383. X          window.height=image_window->ximage->height << 1;
  384. X        }
  385. X      else
  386. X        {
  387. X          window.width=image_window->ximage->width >> 1;
  388. X          window.height=image_window->ximage->height >> 1;
  389. X          if ((window.width == 0) || (window.height == 0))
  390. X            break;
  391. X        }
  392. X      (void) XResizeImageWindow(display,resource_info,info_window,&window,
  393. X        *image);
  394. X      image_window->ximage=window.ximage;
  395. X      window_changes.width=image_window->ximage->width;
  396. X      if (window_changes.width > XDisplayWidth(display,image_window->screen))
  397. X        window_changes.width=XDisplayWidth(display,image_window->screen);
  398. X      window_changes.height=image_window->ximage->height;
  399. X      if (window_changes.height > XDisplayHeight(display,image_window->screen))
  400. X        window_changes.height=XDisplayHeight(display,image_window->screen);
  401. X      if ((image_window->width == window_changes.width) &&
  402. X          (image_window->height == window_changes.height))
  403. X        XDisplayImageWindow(display,image_window,0,0,image_window->width,
  404. X          image_window->height);
  405. X      else
  406. X        {
  407. X          /*
  408. X            Resize image window.
  409. X          */
  410. X          XReconfigureWMWindow(display,image_window->id,image_window->screen,
  411. X            CWWidth | CWHeight,&window_changes);
  412. X          *state|=ConfigureWindowState;
  413. X        }
  414. X      break;
  415. X    }
  416. X    case '/':
  417. X    case '\\':
  418. X    {
  419. X      unsigned int
  420. X        status;
  421. X
  422. X      /*
  423. X        Rotate image 90 degrees to the right or left.
  424. X      */
  425. X      status=XRotateImageWindow(display,info_window,image_window,
  426. X        (unsigned int) (*command == '/' ? 90 : 270),image);
  427. X      if (!status)
  428. X        break;
  429. X      window=(*image_window);
  430. X      window.width=image_window->ximage->height;
  431. X      window.height=image_window->ximage->width;
  432. X      (void) XResizeImageWindow(display,resource_info,info_window,&window,
  433. X        *image);
  434. X      image_window->ximage=window.ximage;
  435. X      window_changes.width=image_window->ximage->width;
  436. X      if (window_changes.width > XDisplayWidth(display,image_window->screen))
  437. X        window_changes.width=XDisplayWidth(display,image_window->screen);
  438. X      window_changes.height=image_window->ximage->height;
  439. X      if (window_changes.height > XDisplayHeight(display,image_window->screen))
  440. X        window_changes.height=XDisplayHeight(display,image_window->screen);
  441. X      if ((image_window->width == window_changes.width) &&
  442. X          (image_window->height == window_changes.height))
  443. X        XDisplayImageWindow(display,image_window,0,0,image_window->width,
  444. X          image_window->height);
  445. X      else
  446. X        {
  447. X          /*
  448. X            Resize image window.
  449. X          */
  450. X          XReconfigureWMWindow(display,image_window->id,image_window->screen,
  451. X            CWWidth | CWHeight,&window_changes);
  452. X          *state|=ConfigureWindowState;
  453. X        }
  454. X      break;
  455. X    }
  456. X    case 'r':
  457. X    {
  458. X      /*
  459. X        Reflect image scanlines.
  460. X      */
  461. X      (void) XReflectImageWindow(display,info_window,image_window,image);
  462. X      (void) XResizeImageWindow(display,resource_info,info_window,image_window,
  463. X        *image);
  464. X      XDisplayImageWindow(display,image_window,0,0,image_window->width,
  465. X        image_window->height);
  466. X      break;
  467. X    }
  468. X    case 'o':
  469. X    case 'w':
  470. X    {
  471. X      /*
  472. X        Restore image or image window to its original size.
  473. X      */
  474. X      if (image_window->clip_geometry != (char *) NULL)
  475. X        {
  476. X          unsigned int
  477. X            clip_height,
  478. X            clip_width;
  479. X
  480. X          /*
  481. X            Retain the image clipping offsets;  discard geometry.
  482. X          */
  483. X          (void) XParseGeometry(image_window->clip_geometry,&image_window->x,
  484. X            &image_window->y,&clip_width,&clip_height);
  485. X          image_window->x=(-image_window->x);
  486. X          image_window->y=(-image_window->y);
  487. X          (void) free((char *) image_window->clip_geometry);
  488. X          image_window->clip_geometry=(char *) NULL;
  489. X        }
  490. X      window=(*image_window);
  491. X      window.width=(*image)->columns;
  492. X      window.height=(*image)->rows;
  493. X      (void) XResizeImageWindow(display,resource_info,info_window,&window,
  494. X        *image);
  495. X      image_window->ximage=window.ximage;
  496. X      window_changes.width=image_window->ximage->width;
  497. X      if (window_changes.width > XDisplayWidth(display,image_window->screen))
  498. X        window_changes.width=XDisplayWidth(display,image_window->screen);
  499. X      window_changes.height=image_window->ximage->height;
  500. X      if (window_changes.height > XDisplayHeight(display,image_window->screen))
  501. X        window_changes.height=XDisplayHeight(display,image_window->screen);
  502. X      if ((*command == 'o') ||
  503. X          ((image_window->width == window_changes.width) &&
  504. X           (image_window->height == window_changes.height)))
  505. X        XDisplayImageWindow(display,image_window,0,0,image_window->width,
  506. X          image_window->height);
  507. X      else
  508. X        {
  509. X          /*
  510. X            Resize image window.
  511. X          */
  512. X          XReconfigureWMWindow(display,image_window->id,image_window->screen,
  513. X            CWWidth | CWHeight,&window_changes);
  514. X          *state|=ConfigureWindowState;
  515. X        }
  516. X      break;
  517. X    }
  518. X    case 'm':
  519. X    {
  520. X      /*
  521. X        Unmap or unmap magnify image.
  522. X      */
  523. X      if (*state & MagnifyMappedState)
  524. X        XWithdrawWindow(display,magnify_window->id,magnify_window->screen);
  525. X      else
  526. X        {
  527. X          ConstrainMagnifyFactor(image_window,magnify_window,
  528. X            resource_info->magnify);
  529. X          XMakeMagnifyImage(magnify_window,image_window->ximage,
  530. X            resource_info->magnify);
  531. X          XMapRaised(display,magnify_window->id);
  532. X        }
  533. X      break;
  534. X    }
  535. X    case 'n':
  536. X    {
  537. X      /*
  538. X        Display next image.
  539. X      */
  540. X      *timeout=0;
  541. X      break;
  542. X    }
  543. X    case 'q':
  544. X    {
  545. X      /*
  546. X        Exit program
  547. X      */
  548. X      *state|=ExitState;  /* exit program */
  549. X      break;
  550. X    }
  551. X    case ' ':
  552. X    case '\0':
  553. X      break;
  554. X    default:
  555. X    {
  556. X      XBell(display,0);
  557. X      break;
  558. X    }
  559. X  }
  560. }
  561. X
  562. /*
  563. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  564. %                                                                             %
  565. %                                                                             %
  566. %                                                                             %
  567. %   X C l i p I m a g e W i n d o w                                           %
  568. %                                                                             %
  569. %                                                                             %
  570. %                                                                             %
  571. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  572. %
  573. %  Function XClipImageWindow displays a rectangle whose sizes changes as
  574. %  the pointer moves.  When the mouse button is released, the geometry of
  575. %  the image region defined within the rectangle is returned.
  576. %
  577. %  The format of the XClipImageWindow routine is:
  578. %
  579. %    XClipImageWindow(display,info_window,image_window,image,x_offset,y_offset)
  580. %
  581. %  A description of each parameter follows:
  582. %
  583. %    o display: Specifies a connection to an X server;  returned from
  584. %      XOpenDisplay.
  585. %
  586. %    o info_window: Specifies a pointer to a XWindowInfo structure.
  587. %
  588. %    o image_window: Specifies a pointer to a XWindowInfo structure.
  589. %
  590. %    o image: Specifies a pointer to a Image structure; returned from
  591. %      ReadImage.
  592. %
  593. %    o x_offset: Specifies the initial offset in the x-direction of the
  594. %      rectangle.
  595. %
  596. %    o y_offset: Specifies the initial offset in the y-direction of the
  597. %      rectangle.
  598. %
  599. %
  600. */
  601. static void XClipImageWindow(display,info_window,image_window,image,x_offset,
  602. X  y_offset)
  603. Display
  604. X  *display;
  605. X
  606. XXWindowInfo
  607. X  *info_window,
  608. X  *image_window;
  609. X
  610. Image
  611. X  *image;
  612. X
  613. int
  614. X  x_offset,
  615. X  y_offset;
  616. {
  617. #define ClipRectangle(x,y,width,height)  \
  618. {  \
  619. X  if ((width >= MinRectangle) && (height >= MinRectangle))  \
  620. X    {  \
  621. X      XSetFunction(display,image_window->graphic_context,GXinvert);  \
  622. X      XDrawRectangle(display,image_window->id,image_window->graphic_context,  \
  623. X        x,y,width-1,height-1);  \
  624. X      XDrawRectangle(display,image_window->id,image_window->graphic_context,  \
  625. X        x+1,y+1,width-3,height-3);  \
  626. X      XSetFunction(display,image_window->graphic_context,GXcopy);  \
  627. X    }  \
  628. }
  629. #define MinRectangle  3
  630. X
  631. X  char
  632. X    text[256];
  633. X
  634. X  register int
  635. X    x,
  636. X    y;
  637. X
  638. X  register unsigned int
  639. X    height,
  640. X    width;
  641. X
  642. X  unsigned int
  643. X    state;
  644. X
  645. X  XEvent
  646. X    event;
  647. X
  648. X  /*
  649. X    Set the width of info window.
  650. X  */
  651. X  state=DefaultState;
  652. X  (void) sprintf(text," %dx%d%+d%+d \0",image_window->width,
  653. X    image_window->height,image_window->width,image_window->height);
  654. X  info_window->width=XTextWidth(info_window->font_info,text,strlen(text));
  655. X  info_window->height=
  656. X    info_window->font_info->ascent+info_window->font_info->descent+4;
  657. X  XResizeWindow(display,info_window->id,info_window->width,
  658. X    info_window->height);
  659. X  /*
  660. X    Size rectangle as pointer moves until the mouse button is released.
  661. X  */
  662. X  x=x_offset;
  663. X  y=y_offset;
  664. X  width=0;
  665. X  height=0;
  666. X  do
  667. X  {
  668. X    if ((width >= MinRectangle) && (height >= MinRectangle))
  669. X      {
  670. X        /*
  671. X          Display info and draw clipping rectangle.
  672. X        */
  673. X        if (!(state & InfoMappedState))
  674. X          {
  675. X            XMapWindow(display,info_window->id);
  676. X            state|=InfoMappedState;
  677. X          }
  678. X        (void) sprintf(text," %dx%d%+d%+d\0",width,height,x,y);
  679. X        XClearWindow(display,info_window->id);
  680. X        XDrawString(display,info_window->id,info_window->graphic_context,2,
  681. X          info_window->font_info->ascent+2,text,strlen(text));
  682. X        ClipRectangle(x,y,width,height);
  683. X      }
  684. X    else
  685. X      if (state & InfoMappedState)
  686. X        {
  687. X          /*
  688. X            Clipping rectangle is too small;  withdraw info window.
  689. X          */
  690. X          XWithdrawWindow(display,info_window->id,info_window->screen);
  691. X          state&=(~InfoMappedState);
  692. X        }
  693. X    /*
  694. X      Wait for next event.
  695. X    */
  696. X    XMaskEvent(display,ButtonPressMask | Button2MotionMask | ButtonReleaseMask,
  697. X      &event);
  698. X    ClipRectangle(x,y,width,height);
  699. X    switch (event.type)
  700. X    {
  701. X      case ButtonPress:
  702. X        break;
  703. X      case ButtonRelease:
  704. X      {
  705. X        /*
  706. X          User has committed to clipping rectangle.
  707. X        */
  708. X        if (event.xbutton.button != Button2)
  709. X          break;
  710. X        state|=ExitState;
  711. X        break;
  712. X      }
  713. X      case MotionNotify:
  714. X      {
  715. X        /*
  716. X          Discard pending button motion events.
  717. X        */
  718. X        while (XCheckMaskEvent(display,Button2MotionMask,&event));
  719. X        x=event.xmotion.x;
  720. X        y=event.xmotion.y;
  721. X        /*
  722. X          Check boundary conditions.
  723. X        */
  724. X        if (x < 0)
  725. X          x=0;
  726. X        else
  727. X          if (x > image_window->width)
  728. X            x=image_window->width-1;
  729. X        if (x < x_offset)
  730. X          width=(unsigned int) (x_offset-x);
  731. X        else
  732. X          {
  733. X            width=(unsigned int) (x-x_offset);
  734. X            x=x_offset;
  735. X          }
  736. X        if (y < 0)
  737. X          y=0;
  738. X        else
  739. X          if (y > image_window->height)
  740. X            y=image_window->height-1;
  741. X        if (y < y_offset)
  742. X          height=(unsigned int) (y_offset-y);
  743. X        else
  744. X          {
  745. X            height=(unsigned int) (y-y_offset);
  746. X            y=y_offset;
  747. X          }
  748. X      }
  749. X      default:
  750. X        break;
  751. X    }
  752. X  } while (!(state & ExitState));
  753. X  if (state & InfoMappedState)
  754. X    XWithdrawWindow(display,info_window->id,info_window->screen);
  755. X  if ((width >= MinRectangle) && (height >= MinRectangle))
  756. X    {
  757. X      int
  758. X        clip_x,
  759. X        clip_y;
  760. X
  761. X      unsigned int
  762. X        clip_height,
  763. X        clip_width;
  764. X
  765. X      unsigned long
  766. X        scale_factor;
  767. X
  768. X      XWindowChanges
  769. X        window_changes;
  770. X
  771. X      /*
  772. X        Check boundary conditions.
  773. X      */
  774. X      if (((x+(int) width) < image_window->x) ||
  775. X          ((y+(int) height) < image_window->y) ||
  776. X          (x > (image_window->x+image_window->ximage->width)) ||
  777. X          (y > (image_window->y+image_window->ximage->height)))
  778. X        return;
  779. X      if (x < image_window->x)
  780. X        {
  781. X          width-=(unsigned int) (image_window->x-x);
  782. X          x=image_window->x;
  783. X        }
  784. X      if (y < image_window->y)
  785. X        {
  786. X          height-=(unsigned int) (image_window->y-y);
  787. X          y=image_window->y;
  788. X        }
  789. X      if ((x+(int) width) > (image_window->x+image_window->ximage->width))
  790. X        width=(unsigned int) (image_window->x+image_window->ximage->width);
  791. X      if ((y+(int) height) > (image_window->y+image_window->ximage->height))
  792. X        height=(unsigned int) (image_window->y+image_window->ximage->height);
  793. X      x-=image_window->x;
  794. X      y-=image_window->y;
  795. X      /*
  796. X        Clipping geometry is relative to any previous clip geometry.
  797. X      */
  798. X      clip_x=0;
  799. X      clip_y=0;
  800. X      clip_width=image->columns;
  801. X      clip_height=image->rows;
  802. X      if (image_window->clip_geometry != (char *) NULL)
  803. X        (void) XParseGeometry(image_window->clip_geometry,&clip_x,&clip_y,
  804. X          &clip_width,&clip_height);
  805. X      else
  806. X        {
  807. X          /*
  808. X            Allocate clip geometry string.
  809. X          */
  810. X          image_window->clip_geometry=(char *) malloc(256);
  811. X          if (image_window->clip_geometry == (char *) NULL)
  812. X            Error("unable to clip X image",image_window->name);
  813. X        }
  814. X      /*
  815. X        Define the clip geometry string from the clipping rectangle.
  816. X      */
  817. X      scale_factor=(clip_width << 14)/image_window->ximage->width;
  818. X      if (x > 0)
  819. X        clip_x+=(x*scale_factor+8191) >> 14;
  820. X      clip_width=(width*scale_factor+8191) >> 14;
  821. X      if (clip_width == 0)
  822. X        clip_width=1;
  823. X      scale_factor=(clip_height << 14)/image_window->ximage->height;
  824. X      if (y > 0)
  825. X        clip_y+=(y*scale_factor+8191) >> 14;
  826. X      clip_height=(height*scale_factor+8191) >> 14;
  827. X      if (clip_height == 0)
  828. X        clip_height=1;
  829. X      (void) sprintf(image_window->clip_geometry,"%dx%d%+d%+d\0",clip_width,
  830. X        clip_height,clip_x,clip_y);
  831. X      /*
  832. X        Reconfigure image window as defined by clipping rectangle.
  833. X      */
  834. X      window_changes.width=width;
  835. X      window_changes.height=height;
  836. X      XReconfigureWMWindow(display,image_window->id,image_window->screen,
  837. X        CWWidth | CWHeight,&window_changes);
  838. X    }
  839. }
  840. X
  841. /*
  842. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  843. %                                                                             %
  844. %                                                                             %
  845. %                                                                             %
  846. %   X D i s p l a y I m a g e                                                 %
  847. %                                                                             %
  848. %                                                                             %
  849. %                                                                             %
  850. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  851. %
  852. %  Function XDisplayImage displays an image via X11.
  853. %
  854. %  The format of the XDisplayImage routine is:
  855. %
  856. %      displayed_image=XDisplayImage(display,resource_info,argv,argc,image,
  857. %        clip_geometry,image_geometry,terminate)
  858. %
  859. %  A description of each parameter follows:
  860. %
  861. %    o display: Specifies a connection to an X server;  returned from
  862. %      XOpenDisplay.
  863. %
  864. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  865. %
  866. %    o argv: Specifies the application's argument list.
  867. %
  868. %    o argc: Specifies the number of arguments.
  869. %
  870. %    o image: Specifies a pointer to a Image structure; returned from
  871. %      ReadImage.
  872. %
  873. %    o clip_geometry: Returns a pointer to a clip geometry string.
  874. %      This geometry defines a subregion of the image.
  875. %
  876. %    o image_geometry: Returns a pointer to a image geometry string.
  877. %      The specified width and height of this geometry string are absolute.
  878. %
  879. %    o terminate: A value other than zero is returned if the user requests
  880. %      the program to terminate immediately.
  881. %
  882. %
  883. */
  884. static Image *XDisplayImage(display,resource_info,argv,argc,image,
  885. X  clip_geometry,image_geometry,terminate)
  886. Display
  887. X  *display;
  888. X
  889. XXResourceInfo
  890. X  *resource_info;
  891. X
  892. char
  893. X  **argv;
  894. X
  895. int
  896. X  argc;
  897. X
  898. Image
  899. X  *image;
  900. X
  901. char
  902. X  **clip_geometry,
  903. X  **image_geometry;
  904. X
  905. unsigned int
  906. X  *terminate;
  907. {
  908. #define MagnifySize  256  /* must be a power of 2 */
  909. X
  910. X  Atom
  911. X    delete_property,
  912. X    protocols_property;
  913. X
  914. X  Colormap
  915. X    colormap;
  916. X
  917. X  char
  918. X    text[256];
  919. X
  920. X  Cursor
  921. X    arrow_cursor,
  922. X    watch_cursor;
  923. X
  924. X  GC
  925. X    graphic_context;
  926. X
  927. X  unsigned int
  928. X    state;
  929. X
  930. X  unsigned long
  931. X    timeout;
  932. X
  933. X  Window
  934. X    root_window;
  935. X
  936. X  XClassHint
  937. X    *class_hint;
  938. X
  939. X  XColor
  940. X    color;
  941. X
  942. X  XEvent
  943. X    event;
  944. X
  945. X  XFontStruct
  946. X    *font_info;
  947. X
  948. X  XGCValues
  949. X    graphic_context_value;
  950. X
  951. X  XPixelInfo
  952. X    pixel_info;
  953. X
  954. X  XStandardColormap
  955. X    *map_info;
  956. X
  957. X  XVisualInfo
  958. X    *visual_info;
  959. X
  960. X  XWindowInfo
  961. X    backdrop_window,
  962. X    icon_window,
  963. X    image_window,
  964. X    info_window,
  965. X    magnify_window,
  966. X    menu_window,
  967. X    superclass_window;
  968. X
  969. X  XWMHints
  970. X    *manager_hints;
  971. X
  972. X  /*
  973. X    Discard outstanding X events.
  974. X  */
  975. X  while (XEventsQueued(display,QueuedAfterFlush) > 0)
  976. X    XNextEvent(display,&event);
  977. X  /*
  978. X    Get the best visual this server supports.
  979. X  */
  980. X  visual_info=XBestVisualInfo(display,resource_info->visual_type,
  981. X    resource_info->map_type,&map_info);
  982. X  if (visual_info == (XVisualInfo *) NULL)
  983. X    Error("unable to get visual",resource_info->visual_type);
  984. X  /*
  985. X    Initialize colormap.
  986. X  */
  987. X  pixel_info.pixels=(unsigned long *) NULL;
  988. X  if (resource_info->map_type == (char *) NULL)
  989. X    {
  990. X      /*
  991. X        Create Standard Colormap.
  992. X      */
  993. X      map_info=XMakeStandardColormap(display,visual_info,resource_info,
  994. X        &pixel_info,image);
  995. X      colormap=map_info->colormap;
  996. X    }
  997. X  else
  998. X    {
  999. X      if (image->class == PseudoClass)
  1000. X        {
  1001. X          register int
  1002. X            i;
  1003. X
  1004. X          /*
  1005. X            Initialize pixel array for images of type PseudoClass.
  1006. X          */
  1007. X          pixel_info.pixels=(unsigned long *)
  1008. X            malloc((unsigned int) image->colors*sizeof(unsigned long));
  1009. X          if (pixel_info.pixels == (unsigned long *) NULL)
  1010. X            Error("unable to create colormap","memory allocation failed");
  1011. X          for (i=0; i < image->colors; i++)
  1012. X            pixel_info.pixels[i]=XStandardPixel(map_info,image->colormap[i],8);
  1013. X        }
  1014. X      /*
  1015. X        Define background/border/foreground pixels.
  1016. X      */
  1017. X      colormap=map_info->colormap;
  1018. X      XParseColor(display,colormap,resource_info->background_color,&color);
  1019. X      pixel_info.background_pixel=XStandardPixel(map_info,color,16);
  1020. X      XParseColor(display,colormap,resource_info->border_color,&color);
  1021. X      pixel_info.border_pixel=XStandardPixel(map_info,color,16);
  1022. X      XParseColor(display,colormap,resource_info->foreground_color,&color);
  1023. X      pixel_info.foreground_pixel=XStandardPixel(map_info,color,16);
  1024. X    }
  1025. X  /*
  1026. X    Initialize font info.
  1027. X  */
  1028. X  (void) sprintf(text," %+d%+d #%02x%02x%02x \0",image->columns,image->rows,
  1029. X    MaxRgb,MaxRgb,MaxRgb);
  1030. X  font_info=XBestFont(display,resource_info,text,image->columns >> 1);
  1031. X  if (font_info == (XFontStruct *) NULL)
  1032. X    Error("unable to load font",resource_info->font_name);
  1033. X  /*
  1034. X    Initialize cursor.
  1035. X  */
  1036. X  arrow_cursor=XCreateFontCursor(display,XC_arrow);
  1037. X  watch_cursor=XCreateFontCursor(display,XC_watch);
  1038. X  if ((arrow_cursor == (Cursor) NULL) || (watch_cursor == (Cursor) NULL))
  1039. X    Error("unable to create cursor",(char *) NULL);
  1040. X  /*
  1041. X    Initialize atoms.
  1042. X  */
  1043. X  protocols_property=XInternAtom(display,"WM_PROTOCOLS",False);
  1044. X  delete_property=XInternAtom(display,"WM_DELETE_WINDOW",False);
  1045. X  if ((protocols_property == (Atom) NULL) || (delete_property == (Atom) NULL))
  1046. X    Error("unable to create property",(char *) NULL);
  1047. X  /*
  1048. X    Initialize class and manager hints.
  1049. X  */
  1050. X  class_hint=XAllocClassHint();
  1051. X  manager_hints=XAllocWMHints();
  1052. X  if ((class_hint == (XClassHint *) NULL) ||
  1053. X      (manager_hints == (XWMHints *) NULL))
  1054. X    Error("unable to allocate X hints",(char *) NULL);
  1055. X  if (resource_info->name == (char *) NULL)
  1056. X    class_hint->res_name=application_name;
  1057. X  else
  1058. X    class_hint->res_name=resource_info->name;
  1059. X  class_hint->res_class=(char *) "ImageMagick";
  1060. X  manager_hints->flags=InputHint | StateHint;
  1061. X  manager_hints->input=False;
  1062. X  manager_hints->initial_state=NormalState;
  1063. X  /*
  1064. X    Window superclass.
  1065. X  */
  1066. X  superclass_window.screen=visual_info->screen;
  1067. X  superclass_window.depth=visual_info->depth;
  1068. X  superclass_window.visual_info=visual_info;
  1069. X  superclass_window.map_info=map_info;
  1070. X  superclass_window.pixel_info=(&pixel_info);
  1071. X  superclass_window.font_info=font_info;
  1072. X  superclass_window.cursor=arrow_cursor;
  1073. X  superclass_window.busy_cursor=watch_cursor;
  1074. X  superclass_window.name="ImageMagick SuperClass";
  1075. X  superclass_window.geometry=(char *) NULL;
  1076. X  superclass_window.icon_geometry=resource_info->icon_geometry;
  1077. X  superclass_window.clip_geometry=(char *) NULL;
  1078. X  superclass_window.flags=PSize;
  1079. X  superclass_window.x=0;
  1080. X  superclass_window.y=0;
  1081. X  superclass_window.width=1;
  1082. X  superclass_window.height=1;
  1083. X  superclass_window.min_width=0;
  1084. X  superclass_window.min_height=0;
  1085. X  superclass_window.width_inc=1;
  1086. X  superclass_window.height_inc=1;
  1087. X  superclass_window.border_width=2;
  1088. X  superclass_window.immutable=True;
  1089. X  superclass_window.attributes.background_pixel=pixel_info.background_pixel;
  1090. X  superclass_window.attributes.background_pixmap=(Pixmap) NULL;
  1091. X  superclass_window.attributes.backing_store=WhenMapped;
  1092. X  superclass_window.attributes.bit_gravity=ForgetGravity;
  1093. X  superclass_window.attributes.border_pixel=pixel_info.border_pixel;
  1094. X  superclass_window.attributes.colormap=colormap;
  1095. X  superclass_window.attributes.cursor=arrow_cursor;
  1096. X  superclass_window.attributes.do_not_propagate_mask=NoEventMask;
  1097. X  superclass_window.attributes.event_mask=NoEventMask;
  1098. X  superclass_window.attributes.override_redirect=False;
  1099. X  superclass_window.attributes.save_under=False;
  1100. X  superclass_window.attributes.win_gravity=NorthWestGravity;
  1101. X  superclass_window.graphic_context=(GC) NULL;
  1102. X  superclass_window.ximage=(XImage *) NULL;
  1103. X  /*
  1104. X    Initialize graphic context.
  1105. X  */
  1106. X  root_window=XRootWindow(display,visual_info->screen);
  1107. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1108. X    delete_property,&superclass_window);
  1109. X  graphic_context_value.background=pixel_info.background_pixel;
  1110. X  graphic_context_value.foreground=pixel_info.foreground_pixel;
  1111. X  graphic_context_value.font=font_info->fid;
  1112. X  graphic_context_value.function=GXcopy;
  1113. X  graphic_context_value.plane_mask=AllPlanes;
  1114. X  graphic_context=XCreateGC(display,superclass_window.id,GCBackground |
  1115. X    GCFont | GCForeground | GCFunction | GCPlaneMask,&graphic_context_value);
  1116. X  if (graphic_context == (GC) NULL)
  1117. X    Error("unable to create graphic context",(char *) NULL);
  1118. X  superclass_window.graphic_context=graphic_context;
  1119. X  /*
  1120. X    Initialize icon window.
  1121. X  */
  1122. X  icon_window=superclass_window;
  1123. X  icon_window.name="ImageMagick Icon";
  1124. X  XBestIconSize(display,&icon_window,image);
  1125. X  icon_window.attributes.event_mask=ExposureMask | StructureNotifyMask;
  1126. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1127. X  manager_hints->input=False;
  1128. X  manager_hints->initial_state=IconicState;
  1129. X  manager_hints->window_group=superclass_window.id;
  1130. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1131. X    delete_property,&icon_window);
  1132. X  /*
  1133. X    Initialize image window.
  1134. X  */
  1135. X  image_window=superclass_window;
  1136. X  image_window.name=(char *) malloc(256);
  1137. X  if (image_window.name == NULL)
  1138. X    Error("unable to create image window","memory allocation failed");
  1139. X  if (resource_info->title == (char *) NULL)
  1140. X    (void) sprintf(image_window.name,"ImageMagick: %s\0",image->filename);
  1141. X  else
  1142. X    (void) strcpy(image_window.name,resource_info->title);
  1143. X  image_window.geometry=resource_info->image_geometry;
  1144. X  image_window.width=image->columns;
  1145. X  if (image_window.width > XDisplayWidth(display,visual_info->screen))
  1146. X    image_window.width=XDisplayWidth(display,visual_info->screen);
  1147. X  image_window.height=image->rows;
  1148. X  if (image_window.height > XDisplayHeight(display,visual_info->screen))
  1149. X    image_window.height=XDisplayHeight(display,visual_info->screen);
  1150. X  image_window.border_width=resource_info->border_width;
  1151. X  backdrop_window=superclass_window;
  1152. X  if (resource_info->backdrop)
  1153. X    {
  1154. X      /*
  1155. X        Initialize backdrop window.
  1156. X      */
  1157. X      backdrop_window.name="ImageMagick Background";
  1158. X      backdrop_window.flags=USSize | USPosition;
  1159. X      backdrop_window.width=XDisplayWidth(display,visual_info->screen);
  1160. X      backdrop_window.height=XDisplayHeight(display,visual_info->screen);
  1161. X      backdrop_window.border_width=0;
  1162. X      backdrop_window.attributes.do_not_propagate_mask=
  1163. X        ButtonPressMask | ButtonReleaseMask;
  1164. X      manager_hints->flags=IconWindowHint | InputHint | StateHint |
  1165. X        WindowGroupHint;
  1166. X      manager_hints->icon_window=icon_window.id;
  1167. X      manager_hints->input=True;
  1168. X      manager_hints->initial_state=
  1169. X        resource_info->iconic ? IconicState : NormalState;
  1170. X      manager_hints->window_group=superclass_window.id;
  1171. X      XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1172. X        delete_property,&backdrop_window);
  1173. X      XSetTransientForHint(display,backdrop_window.id,backdrop_window.id);
  1174. X      XMapWindow(display,backdrop_window.id);
  1175. X      /*
  1176. X        Position image in the center the backdrop.
  1177. X      */
  1178. X      image_window.flags|=USPosition;
  1179. X      image_window.x=XDisplayWidth(display,visual_info->screen)/2-
  1180. X        (image_window.width+image_window.border_width)/2;
  1181. X      image_window.y=XDisplayHeight(display,visual_info->screen)/2-
  1182. X        (image_window.height+image_window.border_width)/2;
  1183. X    }
  1184. X  image_window.immutable=False;
  1185. X  image_window.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  1186. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
  1187. X    KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
  1188. X    StructureNotifyMask;
  1189. X  manager_hints->flags=
  1190. X    IconWindowHint | InputHint | StateHint | WindowGroupHint;
  1191. X  manager_hints->icon_window=icon_window.id;
  1192. X  manager_hints->input=True;
  1193. X  manager_hints->initial_state=
  1194. X    resource_info->iconic ? IconicState : NormalState;
  1195. X  manager_hints->window_group=superclass_window.id;
  1196. X  XMakeWindow(display,(resource_info->backdrop ? backdrop_window.id :
  1197. X    root_window),argv,argc,class_hint,manager_hints,delete_property,
  1198. X    &image_window);
  1199. X  XMapWindow(display,image_window.id);
  1200. X  /*
  1201. X    Initialize image X image structure.
  1202. X  */
  1203. X  image_window.x=0;
  1204. X  image_window.y=0;
  1205. X  image_window.ximage=XMakeImage(display,resource_info,&image_window,image,
  1206. X    image->columns,image->rows);
  1207. X  if (image_window.ximage == (XImage *) NULL)
  1208. X    Error("unable to create X image",(char *) NULL);
  1209. X  /*
  1210. X    Initialize magnify window and cursor.
  1211. X  */
  1212. X  magnify_window=superclass_window;
  1213. X  magnify_window.cursor=XMakeCursor(display,image_window.id,colormap,
  1214. X    resource_info->background_color,resource_info->foreground_color);
  1215. X  if (magnify_window.cursor == (Cursor) NULL)
  1216. X    Error("unable to create cursor",(char *) NULL);
  1217. X  magnify_window.name="ImageMagick Magnifier";
  1218. X  magnify_window.width=MagnifySize;
  1219. X  magnify_window.height=MagnifySize;
  1220. X  magnify_window.min_width=MagnifySize;
  1221. X  magnify_window.min_height=MagnifySize;
  1222. X  magnify_window.width_inc=MagnifySize;
  1223. X  magnify_window.height_inc=MagnifySize;
  1224. X  magnify_window.immutable=False;
  1225. X  magnify_window.attributes.cursor=magnify_window.cursor;
  1226. X  magnify_window.attributes.event_mask=
  1227. X    ExposureMask | KeyPressMask | StructureNotifyMask;
  1228. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1229. X  manager_hints->input=False;
  1230. X  manager_hints->initial_state=NormalState;
  1231. X  manager_hints->window_group=superclass_window.id;
  1232. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1233. X    delete_property,&magnify_window);
  1234. X  /*
  1235. X    Initialize magnify window X image structure.
  1236. X  */
  1237. X  magnify_window.x=image->columns >> 1;
  1238. X  magnify_window.y=image->rows >> 1;
  1239. X  magnify_window.ximage=XMakeImage(display,resource_info,&magnify_window,
  1240. X    (Image *) NULL,magnify_window.width,magnify_window.height);
  1241. X  if (magnify_window.ximage == (XImage *) NULL)
  1242. X    Error("unable to create magnify image",(char *) NULL);
  1243. X  /*
  1244. X    Initialize menu window.
  1245. X  */
  1246. X  menu_window=superclass_window;
  1247. X  menu_window.name="ImageMagick Menu";
  1248. X  menu_window.flags=PSize | PPosition;
  1249. X  menu_window.attributes.override_redirect=True;
  1250. X  menu_window.attributes.save_under=True;
  1251. X  menu_window.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  1252. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
  1253. X    OwnerGrabButtonMask;
  1254. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1255. X  manager_hints->input=False;
  1256. X  manager_hints->initial_state=NormalState;
  1257. X  manager_hints->window_group=superclass_window.id;
  1258. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1259. X    delete_property,&menu_window);
  1260. X  XSetTransientForHint(display,menu_window.id,image_window.id);
  1261. X  /*
  1262. X    Initialize info window.
  1263. X  */
  1264. X  info_window=superclass_window;
  1265. X  info_window.name="ImageMagick Info";
  1266. X  info_window.flags=PSize | PPosition;
  1267. X  info_window.x=2;
  1268. X  info_window.y=2;
  1269. X  info_window.attributes.event_mask=StructureNotifyMask;
  1270. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1271. X  manager_hints->input=False;
  1272. X  manager_hints->initial_state=NormalState;
  1273. X  manager_hints->window_group=superclass_window.id;
  1274. X  XMakeWindow(display,image_window.id,argv,argc,class_hint,manager_hints,
  1275. X    delete_property,&info_window);
  1276. X  /*
  1277. X    Respond to events.
  1278. X  */
  1279. X  state=DefaultState;
  1280. X  timeout=(~0);
  1281. X  do
  1282. X  {
  1283. X    /*
  1284. X      Handle a window event.
  1285. X    */
  1286. X    if (resource_info->delay > 0)
  1287. X      if (XEventsQueued(display,QueuedAfterFlush) == 0)
  1288. X        {
  1289. X          /*
  1290. X            Block if delay > 0.
  1291. X          */
  1292. X          (void) sleep(1);
  1293. X          continue;
  1294. X        }
  1295. X    XNextEvent(display,&event);
  1296. X    switch (event.type)
  1297. X    {
  1298. X      case ButtonPress:
  1299. X      {
  1300. X        if (event.xbutton.window == image_window.id)
  1301. X          switch (event.xbutton.button)
  1302. X          {
  1303. X            case Button1:
  1304. X            {
  1305. X              static char
  1306. X                command[256];
  1307. X
  1308. X              if (state & ControlState)
  1309. X                {
  1310. X                  /*
  1311. X                    User pressed the image pan button.
  1312. X                  */
  1313. X                  XPanImageWindow(display,&info_window,&image_window,
  1314. X                    event.xbutton.x,event.xbutton.y);
  1315. X                  break;
  1316. X                }
  1317. X              /*
  1318. X                Select a command from the pop-up menu.
  1319. X              */
  1320. X              XMenuWindow(display,&menu_window,event.xbutton.x_root,
  1321. X                event.xbutton.y_root,command);
  1322. X              UserCommand(display,resource_info,&info_window,&image_window,
  1323. X                &magnify_window,command,&image,&timeout,&state);
  1324. X              break;
  1325. X            }
  1326. X            case Button2:
  1327. X            {
  1328. X              /*
  1329. X                User pressed the image clip button.
  1330. X              */
  1331. X              XClipImageWindow(display,&info_window,&image_window,image,
  1332. X                event.xbutton.x,event.xbutton.y);
  1333. X              break;
  1334. X            }
  1335. X            case Button3:
  1336. X            {
  1337. X              /*
  1338. X                User pressed the image magnify button.
  1339. X              */
  1340. X              magnify_window.x=event.xbutton.x-image_window.x;
  1341. X              magnify_window.y=event.xbutton.y-image_window.y;
  1342. X              if (state & MagnifyMappedState)
  1343. X                XRaiseWindow(display,magnify_window.id);
  1344. X              else
  1345. X                {
  1346. X                  XMapRaised(display,magnify_window.id);
  1347. X                  state|=MagnifyMappedState;
  1348. X                  XWindowEvent(display,magnify_window.id,ExposureMask,&event);
  1349. X                }
  1350. X              XMagnifyImageWindow(display,resource_info,&info_window,
  1351. X                &image_window,&magnify_window);
  1352. X              break;
  1353. X            }
  1354. X            default:
  1355. X              break;
  1356. X          }
  1357. X        break;
  1358. X      }
  1359. X      case ClientMessage:
  1360. X      {
  1361. X        /*
  1362. X          If client window delete message, exit.
  1363. X        */
  1364. X        if (event.xclient.message_type == protocols_property)
  1365. X          if (*event.xclient.data.l == delete_property)
  1366. X            if (event.xclient.window == image_window.id)
  1367. X              state|=ExitState;
  1368. X            else
  1369. X              XWithdrawWindow(display,event.xclient.window,
  1370. X                visual_info->screen);
  1371. X        break;
  1372. X      }
  1373. X      case ConfigureNotify:
  1374. X      {
  1375. X        if (event.xconfigure.window == image_window.id)
  1376. X          {
  1377. X            static unsigned long
  1378. X              scale_factor;
  1379. X
  1380. X            /*
  1381. X              Image window has a new configuration.
  1382. X            */
  1383. X            image_window.x=0;
  1384. X            image_window.y=0;
  1385. X            if ((event.xconfigure.width == image_window.width) &&
  1386. X                (event.xconfigure.height == image_window.height))
  1387. X              break;
  1388. X            /*
  1389. X              Make magnify offset proportional to the window size.
  1390. X            */
  1391. X            scale_factor=(event.xconfigure.width << 14)/image_window.width;
  1392. X            magnify_window.x=(magnify_window.x*scale_factor+8191) >> 14;
  1393. X            scale_factor=(event.xconfigure.height << 14)/image_window.height;
  1394. X            magnify_window.y=(magnify_window.y*scale_factor+8191) >> 14;
  1395. X            image_window.width=event.xconfigure.width;
  1396. X            image_window.height=event.xconfigure.height;
  1397. X            if (!(state & ImageMappedState))
  1398. X              break;
  1399. X            /*
  1400. X              Make font proportional to the window size.
  1401. X            */
  1402. X            (void) sprintf(text," %+d%+d #%02x%02x%02x \0",image_window.width,
  1403. X              image_window.height,MaxRgb,MaxRgb,MaxRgb);
  1404. X            XFreeFont(display,font_info);
  1405. X            font_info=
  1406. X              XBestFont(display,resource_info,text,image_window.width >> 1);
  1407. X            if (font_info == (XFontStruct *) NULL)
  1408. X              Error("unable to load font",resource_info->font_name);
  1409. X            XSetFont(display,superclass_window.graphic_context,font_info->fid);
  1410. X            superclass_window.font_info=font_info;
  1411. X            icon_window.font_info=font_info;
  1412. X            backdrop_window.font_info=font_info;
  1413. X            image_window.font_info=font_info;
  1414. X            magnify_window.font_info=font_info;
  1415. X            menu_window.font_info=font_info;
  1416. X            info_window.font_info=font_info;
  1417. X            /*
  1418. X              If ConfigureState, image is already resized.
  1419. X            */
  1420. X            if (state & ConfigureWindowState)
  1421. X              state&=(~ConfigureWindowState);
  1422. X            else
  1423. X              (void) XResizeImageWindow(display,resource_info,&info_window,
  1424. X                &image_window,image);
  1425. X            while
  1426. X              (XCheckWindowEvent(display,image_window.id,ExposureMask,&event));
  1427. X            XDisplayImageWindow(display,&image_window,0,0,image_window.width,
  1428. X              image_window.height);
  1429. X            break;
  1430. X          }
  1431. X        if (event.xconfigure.window == magnify_window.id)
  1432. X          {
  1433. X            /*
  1434. X              Magnify window has a new configuration.
  1435. X            */
  1436. X            magnify_window.width=event.xconfigure.width;
  1437. X            magnify_window.height=event.xconfigure.height;
  1438. X            if (((magnify_window.width % magnify_window.width_inc) != 0) ||
  1439. X                ((magnify_window.height % magnify_window.height_inc) != 0))
  1440. X              break;
  1441. X            XDestroyImage(magnify_window.ximage);
  1442. X            magnify_window.ximage=XMakeImage(display,resource_info,
  1443. X              &magnify_window,(Image *) NULL,magnify_window.width,
  1444. X              magnify_window.height);
  1445. X            if (magnify_window.ximage == (XImage *) NULL)
  1446. X              Error("unable to create magnify image",(char *) NULL);
  1447. X            ConstrainMagnifyFactor((&image_window),(&magnify_window),
  1448. X              resource_info->magnify);
  1449. X            XMakeMagnifyImage(&magnify_window,image_window.ximage,
  1450. X              resource_info->magnify);
  1451. X            XPutImage(display,magnify_window.id,magnify_window.graphic_context,
  1452. X              magnify_window.ximage,0,0,0,0,magnify_window.width,
  1453. X              magnify_window.height);
  1454. X            break;
  1455. X          }
  1456. X        if (event.xconfigure.window == icon_window.id)
  1457. X          {
  1458. X            /*
  1459. X              Icon window has a new configuration.
  1460. X            */
  1461. X            icon_window.width=event.xconfigure.width;
  1462. X            icon_window.height=event.xconfigure.height;
  1463. X            break;
  1464. X          }
  1465. X      }
  1466. X      case EnterNotify:
  1467. X      {
  1468. X        /*
  1469. X          Selectively install colormap.
  1470. X        */
  1471. X        if (colormap != XDefaultColormap(display,visual_info->screen))
  1472. X          if (event.xcrossing.mode != NotifyUngrab)
  1473. X            XInductColormap(display,colormap);
  1474. X        break;
  1475. X      }
  1476. X      case Expose:
  1477. X      {
  1478. X        /*
  1479. X          Repaint windows that are now exposed.
  1480. X        */
  1481. X        if (event.xexpose.window == image_window.id)
  1482. X          {
  1483. X            XDisplayImageWindow(display,&image_window,event.xexpose.x,
  1484. X              event.xexpose.y,(unsigned int) event.xexpose.width,
  1485. X              (unsigned int) event.xexpose.height);
  1486. X            /*
  1487. X              Reset timeout after expose.
  1488. X            */
  1489. X            if (resource_info->delay == 0)
  1490. X              timeout=(~0);
  1491. X            else
  1492. X              timeout=time((long *) 0)+resource_info->delay;
  1493. X            break;
  1494. X          }
  1495. X        if (event.xexpose.window == magnify_window.id)
  1496. X          {
  1497. X            XPutImage(display,magnify_window.id,magnify_window.graphic_context,
  1498. X              magnify_window.ximage,event.xexpose.x,event.xexpose.y,
  1499. X              event.xexpose.x,event.xexpose.y,
  1500. X              (unsigned int) event.xexpose.width,
  1501. X              (unsigned int) event.xexpose.height);
  1502. X            break;
  1503. X          }
  1504. X        if (event.xexpose.window == icon_window.id)
  1505. X          {
  1506. X            XPutImage(display,icon_window.id,icon_window.graphic_context,
  1507. X              icon_window.ximage,event.xexpose.x,event.xexpose.y,
  1508. X              event.xexpose.x,event.xexpose.y,
  1509. X              (unsigned int) event.xexpose.width,
  1510. X              (unsigned int) event.xexpose.height);
  1511. X            break;
  1512. X          }
  1513. X        break;
  1514. X      }
  1515. X      case KeyPress:
  1516. X      {
  1517. X        static char
  1518. X          command[256];
  1519. X
  1520. X        static KeySym
  1521. X          key_symbol;
  1522. X
  1523. X        /*
  1524. X          Respond to a user key press.
  1525. X        */
  1526. X        if (state & ConfigureWindowState)
  1527. X          {
  1528. X            XBell(display,0);
  1529. X            break;
  1530. X          }
  1531. X        *command=(char) NULL;
  1532. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1533. X          &key_symbol,(XComposeStatus *) NULL);
  1534. X        if (key_symbol == XK_Control_L)
  1535. X          state|=ControlState;
  1536. X        else
  1537. X          if (key_symbol == XK_Help)
  1538. X            Usage((char *) NULL,False);
  1539. X          else
  1540. X            if (!IsCursorKey(key_symbol) && !isdigit(*command))
  1541. X              UserCommand(display,resource_info,&info_window,&image_window,
  1542. X                &magnify_window,command,&image,&timeout,&state);
  1543. X            else
  1544. X              {
  1545. X                /*
  1546. X                  User specified a magnify factor or position.
  1547. X                */
  1548. X                if (!(state & MagnifyMappedState))
  1549. X                  break;
  1550. X                if (key_symbol == XK_Home)
  1551. X                  {
  1552. X                    magnify_window.x=0;
  1553. X                    magnify_window.y=0;
  1554. X                  }
  1555. X                if (key_symbol == XK_Left)
  1556. X                  magnify_window.x--;
  1557. X                if (key_symbol == XK_Up)
  1558. X                  magnify_window.y--;
  1559. X                if (key_symbol == XK_Right)
  1560. X                  magnify_window.x++;
  1561. X                if (key_symbol == XK_Down)
  1562. X                  magnify_window.y++;
  1563. X                if (isdigit(*command))
  1564. X                  resource_info->magnify=1 << atoi(command);
  1565. X                /*
  1566. X                  Magnify image.
  1567. X                */
  1568. X                ConstrainMagnifyFactor((&image_window),(&magnify_window),
  1569. X                  resource_info->magnify);
  1570. X                XMakeMagnifyImage(&magnify_window,image_window.ximage,
  1571. X                  resource_info->magnify);
  1572. X                XPutImage(display,magnify_window.id,
  1573. X                  magnify_window.graphic_context,magnify_window.ximage,0,0,0,0,
  1574. X                  magnify_window.width,magnify_window.height);
  1575. X              }
  1576. X        break;
  1577. X      }
  1578. X      case KeyRelease:
  1579. X      {
  1580. X        static char
  1581. X          command[256];
  1582. X
  1583. X        static KeySym
  1584. X          key_symbol;
  1585. X
  1586. X        /*
  1587. X          Respond to a user key release.
  1588. X        */
  1589. X        *command=(char) NULL;
  1590. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1591. X          &key_symbol,(XComposeStatus *) NULL);
  1592. X        if (key_symbol == XK_Control_L)
  1593. X          state&=(~ControlState);
  1594. X        break;
  1595. X      }
  1596. X      case LeaveNotify:
  1597. X      {
  1598. X        /*
  1599. X          Selectively uninstall colormap.
  1600. X        */
  1601. X        if (colormap != XDefaultColormap(display,visual_info->screen))
  1602. X          if (event.xcrossing.mode != NotifyUngrab)
  1603. X            XUninductColormap(display,colormap);
  1604. X        break;
  1605. X      }
  1606. X      case MapNotify:
  1607. X      {
  1608. X        if (event.xmap.window == image_window.id)
  1609. X          {
  1610. X            state|=ImageMappedState;
  1611. X            break;
  1612. X          }
  1613. X        if (event.xmap.window == magnify_window.id)
  1614. X          {
  1615. X            state|=MagnifyMappedState;
  1616. X            break;
  1617. X          }
  1618. X        if (event.xmap.window == info_window.id)
  1619. X          {
  1620. X            state|=InfoMappedState;
  1621. X            break;
  1622. X          }
  1623. X        if (event.xmap.window == icon_window.id)
  1624. X          {
  1625. X            /*
  1626. X              Create icon image.
  1627. X            */
  1628. X            icon_window.ximage=XMakeImage(display,resource_info,&icon_window,
  1629. X              image,icon_window.width,icon_window.height);
  1630. X            if (icon_window.ximage == (XImage *) NULL)
  1631. X              Error("unable to create icon image",(char *) NULL);
  1632. X            break;
  1633. X          }
  1634. X        break;
  1635. X      }
  1636. X      case MappingNotify:
  1637. X      {
  1638. X        XRefreshKeyboardMapping(&event.xmapping);
  1639. X        break;
  1640. X      }
  1641. X      case UnmapNotify:
  1642. X      {
  1643. X        if (event.xunmap.window == image_window.id)
  1644. X          {
  1645. X            state&=(~ImageMappedState);
  1646. X            /*
  1647. X              Unmap magnify window.
  1648. X            */
  1649. X            if (state & MagnifyMappedState)
  1650. X              XWithdrawWindow(display,magnify_window.id,magnify_window.screen);
  1651. X            break;
  1652. X          }
  1653. X        if (event.xunmap.window == magnify_window.id)
  1654. X          {
  1655. X            /*
  1656. X              Destroy magnify image.
  1657. X            */
  1658. X            state&=(~MagnifyMappedState);
  1659. X            break;
  1660. X          }
  1661. X        if (event.xunmap.window == info_window.id)
  1662. X          {
  1663. X            state&=(~InfoMappedState);
  1664. X            break;
  1665. X          }
  1666. X        if (event.xunmap.window == icon_window.id)
  1667. X          {
  1668. X            /*
  1669. X              Destroy icon image.
  1670. X            */
  1671. X            XDestroyImage(icon_window.ximage);
  1672. X            icon_window.ximage=(XImage *) NULL;
  1673. X            break;
  1674. X          }
  1675. X        break;
  1676. X      }
  1677. X      default:
  1678. X        break;
  1679. X    }
  1680. X  }
  1681. X  while ((timeout > time((long *) 0)) && !(state & ExitState));
  1682. X  /*
  1683. X    Initialize function return values.
  1684. X  */
  1685. X  *terminate=state & ExitState;
  1686. X  *clip_geometry=image_window.clip_geometry;
  1687. X  if ((image->columns == image_window.ximage->width) &&
  1688. X      (image->rows == image_window.ximage->height))
  1689. X    *image_geometry=(char *) NULL;
  1690. X  else
  1691. X    {
  1692. X      *image_geometry=(char *) malloc(256);
  1693. X      if (*image_geometry == (char *) NULL)
  1694. X        Error("unable to transform X image",(char *) NULL);
  1695. X      (void) sprintf(*image_geometry,"%dx%d\0",image_window.ximage->width,
  1696. X        image_window.ximage->height);
  1697. X    }
  1698. X  /*
  1699. X    Free up memory.
  1700. X  */
  1701. X  XDestroyWindow(display,info_window.id);
  1702. X  XDestroyWindow(display,menu_window.id);
  1703. X  XDestroyWindow(display,magnify_window.id);
  1704. X  XDestroyImage(magnify_window.ximage);
  1705. X  XDestroyWindow(display,image_window.id);
  1706. X  XDestroyImage(image_window.ximage);
  1707. X  (void) free((char *) image_window.name);
  1708. X  if (resource_info->backdrop)
  1709. X    XDestroyWindow(display,backdrop_window.id);
  1710. X  XDestroyWindow(display,icon_window.id);
  1711. X  if (icon_window.ximage != (XImage *) NULL)
  1712. X    XDestroyImage(icon_window.ximage);
  1713. X  XDestroyWindow(display,superclass_window.id);
  1714. X  XFreeGC(display,graphic_context);
  1715. X  XFree((char *) class_hint);
  1716. X  XFree((char *) manager_hints);
  1717. X  XFreeCursor(display,arrow_cursor);
  1718. X  XFreeCursor(display,watch_cursor);
  1719. X  XFreeCursor(display,magnify_window.cursor);
  1720. X  XFreeFont(display,font_info);
  1721. X  /*
  1722. X    Discard pending events before freeing colormap.
  1723. X  */
  1724. X  while (XEventsQueued(display,QueuedAfterFlush) > 0)
  1725. X    XNextEvent(display,&event);
  1726. X  if (resource_info->map_type == (char *) NULL)
  1727. X    if (colormap != XDefaultColormap(display,visual_info->screen))
  1728. X      XFreeColormap(display,colormap);
  1729. X    else
  1730. X      if ((visual_info->class == GrayScale) ||
  1731. X          (visual_info->class == PseudoColor))
  1732. X        XFreeColors(display,colormap,pixel_info.pixels,(int) image->colors,0);
  1733. X  if (pixel_info.pixels != (unsigned long *) NULL)
  1734. X    (void) free((char *) pixel_info.pixels);
  1735. X  XFree((char *) map_info);
  1736. X  XFree((char *) visual_info);
  1737. X  return(image);
  1738. }
  1739. X
  1740. /*
  1741. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1742. %                                                                             %
  1743. %                                                                             %
  1744. %                                                                             %
  1745. %   X D i s p l a y I m a g e W i n d o w                                     %
  1746. %                                                                             %
  1747. %                                                                             %
  1748. %                                                                             %
  1749. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1750. %
  1751. %  Function XDisplayImageWindow displays an image in a X window.
  1752. %
  1753. %  The format of the XDisplayImageWindow routine is:
  1754. %
  1755. %      XDisplayImageWindow(display,image_window,x,y,width,height)
  1756. %
  1757. %  A description of each parameter follows:
  1758. %
  1759. %    o display: Specifies a connection to an X server;  returned from
  1760. %      XOpenDisplay.
  1761. %
  1762. %    o image_window: Specifies a pointer to a XWindowInfo structure.
  1763. %
  1764. %    o x: Specifies the x coordinate relative to the image window.
  1765. %
  1766. %    o y: Specifies the y coordinate relative to the image window.
  1767. %
  1768. %    o width: Specifies the width in pixels of the rectangular area to
  1769. %      display.
  1770. %
  1771. %    o height: Specifies the height in pixels of the rectangular area to
  1772. %      display.
  1773. %
  1774. %
  1775. */
  1776. static void XDisplayImageWindow(display,image_window,x,y,width,height)
  1777. Display
  1778. X  *display;
  1779. X
  1780. XXWindowInfo
  1781. X  *image_window;
  1782. X
  1783. register int
  1784. X  x,
  1785. X  y;
  1786. X
  1787. register unsigned int
  1788. X  height,
  1789. X  width;
  1790. {
  1791. X  /*
  1792. X    Check boundary conditions.
  1793. X  */
  1794. X  if ((x+(int) width) > (int) image_window->width)
  1795. X    width=(unsigned int) ((int) image_window->width-x);
  1796. X  if ((y+(int) height) > (int) image_window->height)
  1797. X    height=(unsigned int) ((int) image_window->height-y);
  1798. X  if (x < image_window->x)
  1799. X    {
  1800. X      XClearArea(display,image_window->id,x,y,
  1801. X        (unsigned int) (image_window->x-x),(unsigned int) (y+(int) height),
  1802. X        False);
  1803. X      width-=(unsigned int) (image_window->x-x);
  1804. X      x=image_window->x;
  1805. X    }
  1806. X  if (y < image_window->y)
  1807. X    {
  1808. X      XClearArea(display,image_window->id,x,y,width,
  1809. X        (unsigned int) (image_window->y-y),False);
  1810. X      height-=(unsigned int) (image_window->y-y);
  1811. X      y=image_window->y;
  1812. X    }
  1813. X  if ((x+(int) width) > (image_window->x+image_window->ximage->width))
  1814. X    {
  1815. X      width=(unsigned int) (image_window->x+image_window->ximage->width);
  1816. X      XClearArea(display,image_window->id,width,y,image_window->width-width,
  1817. X        image_window->height,False);
  1818. X    }
  1819. X  if ((y+(int) height) > (image_window->y+image_window->ximage->height))
  1820. X    {
  1821. X      height=(unsigned int) (image_window->y+image_window->ximage->height);
  1822. X      XClearArea(display,image_window->id,x,height,width,image_window->height-
  1823. X        height,False);
  1824. X    }
  1825. X  /*
  1826. X    Display image.
  1827. X  */
  1828. X  XPutImage(display,image_window->id,image_window->graphic_context,
  1829. X    image_window->ximage,x-image_window->x,y-image_window->y,x,y,width,height);
  1830. }
  1831. X
  1832. /*
  1833. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1834. %                                                                             %
  1835. %                                                                             %
  1836. %                                                                             %
  1837. %   X D i s p l a y R o o t I m a g e                                         %
  1838. %                                                                             %
  1839. %                                                                             %
  1840. %                                                                             %
  1841. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1842. %
  1843. %  Function XDisplayRootImage displays an image in the root window.
  1844. %
  1845. %  The format of the XDisplayRootImage routine is:
  1846. %
  1847. %      XDisplayRootImage(display,resource_info,image)
  1848. %
  1849. %  A description of each parameter follows:
  1850. %
  1851. %    o display: Specifies a connection to an X server;  returned from
  1852. %      XOpenDisplay.
  1853. %
  1854. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1855. %
  1856. %    o image: Specifies a pointer to a Image structure; returned from
  1857. %      ReadImage.
  1858. %
  1859. %
  1860. */
  1861. static void XDisplayRootImage(display,resource_info,image)
  1862. Display
  1863. X  *display;
  1864. X
  1865. XXResourceInfo
  1866. X  *resource_info;
  1867. X
  1868. Image
  1869. X  *image;
  1870. {
  1871. X  Atom
  1872. X    property,
  1873. X    type;
  1874. X
  1875. X  Colormap
  1876. X    colormap;
  1877. X
  1878. X  int
  1879. X    format,
  1880. X    i;
  1881. X
  1882. X  Pixmap
  1883. X    pixmap;
  1884. X
  1885. X  unsigned char
  1886. X    *data;
  1887. X
  1888. X  unsigned int
  1889. X    height,
  1890. X    number_children,
  1891. X    width;
  1892. X
  1893. X  unsigned long
  1894. X    after,
  1895. X    length;
  1896. X
  1897. X  Window
  1898. X    *children,
  1899. X    parent,
  1900. X    root,
  1901. X    root_window;
  1902. X
  1903. X  XColor
  1904. X    color;
  1905. X
  1906. X  XGCValues
  1907. X    graphic_context_value;
  1908. X
  1909. X  XPixelInfo
  1910. X    pixel_info;
  1911. X
  1912. X  XStandardColormap
  1913. X    *map_info;
  1914. X
  1915. X  XWindowInfo
  1916. X    image_window;
  1917. X
  1918. X  XVisualInfo
  1919. X    *visual_info;
  1920. X
  1921. X  /*
  1922. X    Initialize visual info.
  1923. X  */
  1924. X  if ((resource_info->visual_type != (char *) NULL) ||
  1925. X      (resource_info->map_type != (char *) NULL))
  1926. X    visual_info=XBestVisualInfo(display,resource_info->visual_type,
  1927. X      resource_info->map_type,&map_info);
  1928. X  else
  1929. X    {
  1930. X      int
  1931. X        number_visuals;
  1932. X
  1933. X      XVisualInfo
  1934. X        visual_template;
  1935. X
  1936. X      /*
  1937. X        Get the default visual.
  1938. X      */
  1939. X      visual_template.visualid=
  1940. X        XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
  1941. X      visual_info=XGetVisualInfo(display,VisualIDMask,&visual_template,
  1942. X        &number_visuals);
  1943. X    }
  1944. X  if (visual_info == (XVisualInfo *) NULL)
  1945. X    Error("unable to get visual",resource_info->visual_type);
  1946. X  if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  1947. X    Error("visual must be server default",resource_info->visual_type);
  1948. X  /*
  1949. X    Determine if root window is virtual.
  1950. X  */
  1951. X  root_window=XRootWindow(display,visual_info->screen);
  1952. X  property=XInternAtom(display,"__SWM_VROOT",False);
  1953. X  XQueryTree(display,root_window,&root,&parent,&children,&number_children);
  1954. X  for (i=0; i < number_children; i++)
  1955. X  {
  1956. X    (void) XGetWindowProperty(display,children[i],property,0L,1L,False,
  1957. X      XA_WINDOW,&type,&format,&length,&after,&data);
  1958. X    if ((format == 32) && (length == 1) && (after == 0))
  1959. X      {
  1960. X        /*
  1961. X          Root window is a virtual root.
  1962. X        */
  1963. X        root_window=(*((Window *) data));
  1964. X        break;
  1965. X      }
  1966. X  }
  1967. X  if (children != (Window *) NULL)
  1968. X    XFree((char *) children);
  1969. X  /*
  1970. X    If there are previous resources on the root window, destroy them.
  1971. X  */
  1972. X  property=XInternAtom(display,"_XSETROOT_ID",False);
  1973. X  if (property == (Atom) NULL)
  1974. X    Error("unable to create X property","_XSETROOT_ID");
  1975. X  (void) XGetWindowProperty(display,root_window,property,0L,1L,True,
  1976. X    AnyPropertyType,&type,&format,&length,&after,&data);
  1977. X  if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
  1978. X    {
  1979. X      /*
  1980. X        Free previous resources on the root window.
  1981. X      */
  1982. X      XKillClient(display,*((Pixmap *) data));
  1983. X      XFree((char *) data);
  1984. X    }
  1985. X  /*
  1986. X    Initialize colormap.
  1987. X  */
  1988. X  pixel_info.pixels=(unsigned long *) NULL;
  1989. X  if (resource_info->map_type == (char *) NULL)
  1990. X    {
  1991. X      /*
  1992. X        Create Standard Colormap.
  1993. X      */
  1994. X      map_info=XMakeStandardColormap(display,visual_info,resource_info,
  1995. X        &pixel_info,image);
  1996. X      colormap=map_info->colormap;
  1997. X    }
  1998. X  else
  1999. X    {
  2000. X      if (image->class == PseudoClass)
  2001. X        {
  2002. X          register int
  2003. X            i;
  2004. X
  2005. X          /*
  2006. X            Initialize pixel array for images of type PseudoClass.
  2007. X          */
  2008. X          pixel_info.pixels=(unsigned long *)
  2009. X            malloc((unsigned int) image->colors*sizeof(unsigned long));
  2010. X          if (pixel_info.pixels == (unsigned long *) NULL)
  2011. X            Error("unable to create colormap","memory allocation failed");
  2012. X          for (i=0; i < image->colors; i++)
  2013. X            pixel_info.pixels[i]=XStandardPixel(map_info,image->colormap[i],8);
  2014. X        }
  2015. X      /*
  2016. X        Define background/border/foreground pixels.
  2017. X      */
  2018. X      colormap=map_info->colormap;
  2019. X      XParseColor(display,colormap,resource_info->background_color,&color);
  2020. X      pixel_info.background_pixel=XStandardPixel(map_info,color,16);
  2021. X      XParseColor(display,colormap,resource_info->border_color,&color);
  2022. X      pixel_info.border_pixel=XStandardPixel(map_info,color,16);
  2023. X      XParseColor(display,colormap,resource_info->foreground_color,&color);
  2024. X      pixel_info.foreground_pixel=XStandardPixel(map_info,color,16);
  2025. X    }
  2026. X  /*
  2027. X    The colormap must be the default colormap.
  2028. X  */
  2029. X  if (colormap != XDefaultColormap(display,visual_info->screen))
  2030. X    Error("unable to display X image on the root window","too many colors");
  2031. X  /*
  2032. X    Initialize image window attributes.
  2033. X  */
  2034. X  image_window.id=root_window;
  2035. X  image_window.visual_info=visual_info;
  2036. X  image_window.screen=visual_info->screen;
  2037. X  image_window.depth=visual_info->depth;
  2038. X  image_window.clip_geometry=(char *) NULL;
  2039. X  image_window.map_info=map_info;
  2040. X  image_window.pixel_info=(&pixel_info);
  2041. X  image_window.x=0;
  2042. X  image_window.y=0;
  2043. X  image_window.width=image->columns;
  2044. X  if (image_window.width > XDisplayWidth(display,visual_info->screen))
  2045. X    image_window.width=XDisplayWidth(display,visual_info->screen);
  2046. X  image_window.height=image->rows;
  2047. X  if (image_window.height > XDisplayHeight(display,visual_info->screen))
  2048. X    image_window.height=XDisplayHeight(display,visual_info->screen);
  2049. X  image_window.border_width=resource_info->border_width;
  2050. X  /*
  2051. X    Graphic context superclass.
  2052. X  */
  2053. X  graphic_context_value.background=pixel_info.background_pixel;
  2054. X  graphic_context_value.foreground=pixel_info.foreground_pixel;
  2055. X  graphic_context_value.fill_style=FillSolid;
  2056. X  graphic_context_value.function=GXcopy;
  2057. X  graphic_context_value.plane_mask=AllPlanes;
  2058. X  image_window.graphic_context=XCreateGC(display,image_window.id,
  2059. X    GCBackground | GCFillStyle | GCForeground | GCFunction | GCPlaneMask,
  2060. X    &graphic_context_value);
  2061. X  if (image_window.graphic_context == (GC) NULL)
  2062. X    Error("unable to create graphic context",(char *) NULL);
  2063. X  /*
  2064. X    Create the X image.
  2065. X  */
  2066. X  image_window.ximage=XMakeImage(display,resource_info,&image_window,image,
  2067. X    image->columns,image->rows);
  2068. X  if (image_window.ximage == (XImage *) NULL)
  2069. X    Error("unable to create X image",(char *) NULL);
  2070. X  /*
  2071. X    Adjust image dimensions as specified by backdrop or geometry options.
  2072. X  */
  2073. X  width=image_window.width;
  2074. X  height=image_window.height;
  2075. X  if (resource_info->backdrop)
  2076. X    {
  2077. X      /*
  2078. X        Center image on root window.
  2079. X      */
  2080. X      image_window.x=
  2081. X        XDisplayWidth(display,visual_info->screen)/2-image->columns/2;
  2082. X      image_window.y=
  2083. X        XDisplayHeight(display,visual_info->screen)/2-image->rows/2;
  2084. X      width=XDisplayWidth(display,visual_info->screen);
  2085. X      height=XDisplayHeight(display,visual_info->screen);
  2086. X    }
  2087. X  if (resource_info->image_geometry != (char *) NULL)
  2088. X    {
  2089. X      char
  2090. X        default_geometry[256];
  2091. X
  2092. X      int
  2093. X        flags,
  2094. X        gravity;
  2095. X
  2096. X      XSizeHints
  2097. X        *size_hints;
  2098. X
  2099. X      /*
  2100. X        User specified geometry.
  2101. X      */
  2102. X      size_hints=XAllocSizeHints();
  2103. X      if (size_hints == (XSizeHints *) NULL)
  2104. X        Error("unable to display on root","memory allocation failed");
  2105. X      size_hints->flags=(long int) NULL;
  2106. X      (void) sprintf(default_geometry,"%dx%d\0",width,height);
  2107. X      flags=XWMGeometry(display,visual_info->screen,
  2108. X        resource_info->image_geometry,default_geometry,
  2109. X        image_window.border_width,size_hints,&image_window.x,&image_window.y,
  2110. X        (int *) &width,(int *) &height,&gravity);
  2111. X      if (flags & (XValue | YValue))
  2112. X        {
  2113. X          width=XDisplayWidth(display,visual_info->screen);
  2114. X          height=XDisplayHeight(display,visual_info->screen);
  2115. X        }
  2116. X      XFree((char *) size_hints);
  2117. X    }
  2118. X  /*
  2119. X    Create the root pixmap.
  2120. X  */
  2121. X  pixmap=
  2122. X    XCreatePixmap(display,image_window.id,width,height,image_window.depth);
  2123. X  if (pixmap == (Pixmap) NULL)
  2124. X    Error("unable to create X pixmap",(char *) NULL);
  2125. X  /*
  2126. X    Display pixmap on the root window.
  2127. X  */
  2128. X  if ((width > image_window.width) || (height > image_window.height))
  2129. X    {
  2130. X      /*
  2131. X        Surround the image by pixels of the background color.
  2132. X      */
  2133. X      XSetForeground(display,image_window.graphic_context,
  2134. X        pixel_info.background_pixel);
  2135. X      XFillRectangle(display,pixmap,image_window.graphic_context,0,0,width,
  2136. X        height);
  2137. X      XSetForeground(display,image_window.graphic_context,
  2138. X        pixel_info.foreground_pixel);
  2139. X    }
  2140. X  XPutImage(display,pixmap,image_window.graphic_context,image_window.ximage,
  2141. X    0,0,image_window.x,image_window.y,image_window.width,image_window.height);
  2142. X  XSetWindowBackgroundPixmap(display,image_window.id,pixmap);
  2143. X  XClearWindow(display,image_window.id);
  2144. X  /*
  2145. X    Free resources.
  2146. X  */
  2147. X  if (pixel_info.pixels != (unsigned long *) NULL)
  2148. X    (void) free((char *) pixel_info.pixels);
  2149. X  XFreePixmap(display,pixmap);
  2150. X  XDestroyImage(image_window.ximage);
  2151. X  XFreeGC(display,image_window.graphic_context);
  2152. X  XFree((char *) visual_info);
  2153. X  XFree((char *) map_info);
  2154. X  /*
  2155. X    Put property on root window and set close-down mode to RetainPermanent.
  2156. X  */
  2157. X  pixmap=XCreatePixmap(display,image_window.id,1,1,1);
  2158. X  if (pixmap == (Pixmap) NULL)
  2159. X    Error("unable to create X pixmap",(char *) NULL);
  2160. X  XChangeProperty(display,image_window.id,property,XA_PIXMAP,32,PropModeReplace,
  2161. X    (unsigned char *) &pixmap,1);
  2162. X  XSetCloseDownMode(display,RetainPermanent);
  2163. }
  2164. X
  2165. /*
  2166. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2167. %                                                                             %
  2168. %                                                                             %
  2169. %                                                                             %
  2170. %   X M a g n i f y I m a g e W i n d o w                                     %
  2171. %                                                                             %
  2172. %                                                                             %
  2173. %                                                                             %
  2174. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2175. %
  2176. %  Function XMagnifyImageWindow magnifies portions of the image as indicated
  2177. %  by the pointer.  The magnified portion is displayed in a separate window.
  2178. %
  2179. %  The format of the XMagnifyImageWindow routine is:
  2180. %
  2181. %    XMagnifyImageWindow(display,resource_info,info_window,image_window,
  2182. %      magnify_window)
  2183. %
  2184. %  A description of each parameter follows:
  2185. %
  2186. %    o display: Specifies a connection to an X server;  returned from
  2187. %      XOpenDisplay.
  2188. %
  2189. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  2190. %
  2191. %    o info_window: Specifies a pointer to a XWindowInfo structure.
  2192. %
  2193. %    o image_window: Specifies a pointer to a XWindowInfo structure.
  2194. %
  2195. %    o magnify_window: Specifies a pointer to a XWindowInfo structure.
  2196. %
  2197. %
  2198. */
  2199. static void XMagnifyImageWindow(display,resource_info,info_window,image_window,
  2200. SHAR_EOF
  2201. true || echo 'restore of ImageMagick/display.c failed'
  2202. fi
  2203. echo 'End of ImageMagick part 17'
  2204. echo 'File ImageMagick/display.c is continued in part 18'
  2205. echo 18 > _shar_seq_.tmp
  2206. exit 0
  2207. --
  2208. Dan Heller
  2209. O'Reilly && Associates       Z-Code Software    Comp-sources-x:
  2210. Senior Writer                President          comp-sources-x@uunet.uu.net
  2211. argv@ora.com                 argv@zipcode.com
  2212.