home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / imagemagick / part13 < prev    next >
Text File  |  1992-12-14  |  59KB  |  1,873 lines

  1. Newsgroups: comp.sources.misc
  2. From: cristy@eplrx7.es.duPont.com (John Cristy)
  3. Subject:  v34i041:  imagemagick - X11 image processing and display v2.2, Part13/26
  4. Message-ID: <1992Dec15.035211.21619@sparky.imd.sterling.com>
  5. X-Md4-Signature: a86318d02685a3ab0d7e26a5d116ddfb
  6. Date: Tue, 15 Dec 1992 03:52:11 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cristy@eplrx7.es.duPont.com (John Cristy)
  10. Posting-number: Volume 34, Issue 41
  11. Archive-name: imagemagick/part13
  12. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  13.  
  14. #!/bin/sh
  15. # this is Part.13 (part 13 of a multipart archive)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file ImageMagick/display.c continued
  18. #
  19. if test ! -r _shar_seq_.tmp; then
  20.     echo 'Please unpack part 1 first!'
  21.     exit 1
  22. fi
  23. (read Scheck
  24.  if test "$Scheck" != 13; then
  25.     echo Please unpack part "$Scheck" next!
  26.     exit 1
  27.  else
  28.     exit 0
  29.  fi
  30. ) < _shar_seq_.tmp || exit 1
  31. if test ! -f _shar_wnt_.tmp; then
  32.     echo 'x - still skipping ImageMagick/display.c'
  33. else
  34. echo 'x - continuing file ImageMagick/display.c'
  35. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
  36. X    {
  37. X      XWindowChanges
  38. X        window_changes;
  39. X
  40. X      if (resource_info->debug)
  41. X        (void) fprintf(stderr,"Update Configuration\n");
  42. X      /*
  43. X        Update panning icon configuration.
  44. X      */
  45. X      XBestIconSize(display,&window->pan,displayed_image);
  46. X      window_changes.width=window->pan.width;
  47. X      window_changes.height=window->pan.height;
  48. X      XReconfigureWMWindow(display,window->pan.id,window->pan.screen,CWWidth |
  49. X        CWHeight,&window_changes);
  50. X      if (*state & PanIconMappedState)
  51. X        XWithdrawWindow(display,window->pan.id,window->pan.screen);
  52. X      if ((window->image.width < window->image.ximage->width) ||
  53. X          (window->image.height < window->image.ximage->height))
  54. X        XMapRaised(display,window->pan.id);
  55. X      /*
  56. X        Update magnifier configuration.
  57. X      */
  58. X      window->magnify.x=window->image.width >> 1;
  59. X      window->magnify.y=window->image.height >> 1;
  60. X      if (*state & MagnifyMappedState)
  61. X        XMakeMagnifyImage(display,resource_info,window);
  62. X      /*
  63. X        Update icon configuration.
  64. X      */
  65. X      XBestIconSize(display,&window->icon,displayed_image);
  66. X      window_changes.width=window->icon.width;
  67. X      window_changes.height=window->icon.height;
  68. X      XReconfigureWMWindow(display,window->icon.id,window->icon.screen,CWWidth |
  69. X        CWHeight,&window_changes);
  70. X      /*
  71. X        Update font configuration.
  72. X      */
  73. X      (void) sprintf(text," [%u] %s %ux%u %s \0",displayed_image->scene,
  74. X        displayed_image->filename,displayed_image->columns,
  75. X        displayed_image->rows,XVisualClassName(visual_info));
  76. X      if (displayed_image->colors > 0)
  77. X        (void) sprintf(text,"%s%uc \0",text,displayed_image->colors);
  78. X      XFreeFont(display,font_info);
  79. X      font_info=XBestFont(display,resource_info,text,window->image.width);
  80. X      if (font_info == (XFontStruct *) NULL)
  81. X        Error("unable to load font",resource_info->font);
  82. X      for (i=0; i < number_windows; i++)
  83. X      {
  84. X        magick_windows[i]->font_info=font_info;
  85. X        XSetFont(display,magick_windows[i]->graphic_context,font_info->fid);
  86. X        XSetFont(display,magick_windows[i]->highlight_context,font_info->fid);
  87. X      }
  88. X      XRefreshWindow(display,&window->image,(XEvent *) NULL);
  89. X      *state&=(~UpdateConfigurationState);
  90. X    }
  91. X  }
  92. X  while ((timeout > time((time_t *) 0)) && !(*state & ExitState));
  93. X  if ((*state & LastImageState) || (*state & NextImageState))
  94. X    *state&=(~ExitState);
  95. X  if (*state & PanIconMappedState)
  96. X    XWithdrawWindow(display,window->pan.id,window->pan.screen);
  97. X  if (*state & MagnifyMappedState)
  98. X    XWithdrawWindow(display,window->magnify.id,window->magnify.screen);
  99. X  /*
  100. X    Alert user we are busy.
  101. X  */
  102. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  103. X  XFlush(display);
  104. X  if ((resource_info->print_filename != (char *) NULL) ||
  105. X      (resource_info->write_filename != (char *) NULL))
  106. X    {
  107. X      /*
  108. X        Update image with user transforms.
  109. X      */
  110. X      if ((window->image.clip_geometry != (char *) NULL) ||
  111. X          (displayed_image->columns != window->image.ximage->width) ||
  112. X          (displayed_image->rows != window->image.ximage->height))
  113. X        {
  114. X          char
  115. X            image_geometry[2048];
  116. X
  117. X          /*
  118. X            Clip and/or scale displayed_image.
  119. X          */
  120. X          (void) sprintf(image_geometry,"%dx%d\0",window->image.ximage->width,
  121. X            window->image.ximage->height);
  122. X          TransformImage(&displayed_image,window->image.clip_geometry,
  123. X            image_geometry,(char *) NULL);
  124. X        }
  125. X      if (resource_info->colorspace == GRAYColorspace)
  126. X        QuantizeImage(displayed_image,256,8,resource_info->dither,
  127. X          GRAYColorspace,True);
  128. X      if (resource_info->monochrome)
  129. X        QuantizeImage(displayed_image,2,8,resource_info->dither,GRAYColorspace,
  130. X          True);
  131. X      if (resource_info->number_colors > 0)
  132. X        if ((displayed_image->class == DirectClass) ||
  133. X            (displayed_image->colors > resource_info->number_colors))
  134. X          QuantizeImage(displayed_image,resource_info->number_colors,
  135. X            resource_info->tree_depth,resource_info->dither,
  136. X            resource_info->colorspace,True);
  137. X    }
  138. X  /*
  139. X    Free X resources.
  140. X  */
  141. X  XFreeCursor(display,window->magnify.cursor);
  142. X  (void) free((char *) window->magnify.name);
  143. X  (void) free((char *) window->image.name);
  144. X  (void) free((char *) window->image.icon_name);
  145. X  if (resource_info->backdrop)
  146. X    XFreeCursor(display,window->backdrop.cursor);
  147. X  XFreeGC(display,window->superclass.graphic_context);
  148. X  XFreeGC(display,window->superclass.highlight_context);
  149. X  XFreeFont(display,font_info);
  150. X  if (*state & ExitState)
  151. X    {
  152. X      /*
  153. X        Destroy X windows.
  154. X      */
  155. X      for (i=0; i < number_windows; i++)
  156. X      {
  157. X        if (magick_windows[i]->id != (Window) NULL)
  158. X          XDestroyWindow(display,magick_windows[i]->id);
  159. X        if (magick_windows[i]->ximage != (XImage *) NULL)
  160. X          XDestroyImage(magick_windows[i]->ximage);
  161. X        if (magick_windows[i]->pixmap != (Pixmap) NULL)
  162. X          XFreePixmap(display,magick_windows[i]->pixmap);
  163. X      }
  164. X      /*
  165. X        Free Standard Colormap.
  166. X      */
  167. X      if (resource_info->map_type == (char *) NULL)
  168. X        XFreeStandardColormap(display,visual_info,&pixel_info,map_info);
  169. X      XFreeCursor(display,arrow_cursor);
  170. X      XFreeCursor(display,watch_cursor);
  171. X      (void) free((void *) window);
  172. X      XFree((void *) manager_hints);
  173. X      XFree((void *) class_hint);
  174. X      XFree((void *) visual_info);
  175. X      XFree((void *) map_info);
  176. X      visual_info=(XVisualInfo *) NULL;
  177. X    }
  178. X  XFlush(display);
  179. X  *image=displayed_image;
  180. X  return(tile_image);
  181. }
  182. X
  183. /*
  184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  185. %                                                                             %
  186. %                                                                             %
  187. %                                                                             %
  188. %   X D r a w P a n R e c t a n g l e                                         %
  189. %                                                                             %
  190. %                                                                             %
  191. %                                                                             %
  192. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  193. %
  194. %  Function XDrawPanRectangle draws a rectangle in the pan window.  The pan
  195. %  window displays a scaled image and the rectangle shows which portion of
  196. %  the image is displayed in the image window.
  197. %
  198. %  The format of the XDrawPanRectangle routine is:
  199. %
  200. %    XDrawPanRectangle(display,window)
  201. %
  202. %  A description of each parameter follows:
  203. %
  204. %    o display: Specifies a connection to an X server;  returned from
  205. %      XOpenDisplay.
  206. %
  207. %    o window: Specifies a pointer to a XWindows structure.
  208. %
  209. %
  210. */
  211. static void XDrawPanRectangle(display,window)
  212. Display
  213. X  *display;
  214. X
  215. XXWindows
  216. X  *window;
  217. {
  218. X  unsigned long
  219. X    scale_factor;
  220. X
  221. X  int
  222. X    x,
  223. X    y;
  224. X
  225. X  unsigned int
  226. X    height,
  227. X    width;
  228. X
  229. X  /*
  230. X    Determine dimensions of the panning rectangle.
  231. X  */
  232. X  scale_factor=(unsigned long)
  233. X    (UpShift(window->pan.width)/window->image.ximage->width);
  234. X  x=DownShift(window->image.x*scale_factor);
  235. X  width=DownShift(window->image.width*scale_factor);
  236. X  scale_factor=(unsigned long)
  237. X    (UpShift(window->pan.height)/window->image.ximage->height);
  238. X  y=DownShift(window->image.y*scale_factor);
  239. X  height=DownShift(window->image.height*scale_factor);
  240. X  /*
  241. X    Display the panning rectangle.
  242. X  */
  243. X  XClearWindow(display,window->pan.id);
  244. X  XSetForeground(display,window->pan.graphic_context,
  245. X    window->image.pixel_info->background_color.pixel);
  246. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x+1,y+1,
  247. X    width-2,height-2);
  248. X  XSetForeground(display,window->pan.graphic_context,
  249. X    window->image.pixel_info->foreground_color.pixel);
  250. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x,y,
  251. X    width,height);
  252. }
  253. X
  254. /*
  255. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  256. %                                                                             %
  257. %                                                                             %
  258. %                                                                             %
  259. %   X M a g n i f y I m a g e W i n d o w                                     %
  260. %                                                                             %
  261. %                                                                             %
  262. %                                                                             %
  263. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  264. %
  265. %  Function XMagnifyImageWindow magnifies portions of the image as indicated
  266. %  by the pointer.  The magnified portion is displayed in a separate window.
  267. %
  268. %  The format of the XMagnifyImageWindow routine is:
  269. %
  270. %    XMagnifyImageWindow(display,resource_info,window,event)
  271. %
  272. %  A description of each parameter follows:
  273. %
  274. %    o display: Specifies a connection to an X server;  returned from
  275. %      XOpenDisplay.
  276. %
  277. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  278. %
  279. %    o window: Specifies a pointer to a XWindows structure.
  280. %
  281. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  282. %      the entire image is refreshed.
  283. %
  284. %
  285. */
  286. static void XMagnifyImageWindow(display,resource_info,window,event)
  287. Display
  288. X  *display;
  289. X
  290. XXResourceInfo
  291. X  *resource_info;
  292. X
  293. XXWindows
  294. X  *window;
  295. X
  296. XXEvent
  297. X  *event;
  298. {
  299. X  char
  300. X    text[2048];
  301. X
  302. X  register int
  303. X    x,
  304. X    y;
  305. X
  306. X  unsigned long int
  307. X    state;
  308. X
  309. X  /*
  310. X    Map info window.
  311. X  */
  312. X  state=DefaultState;
  313. X  (void) sprintf(text," %+u%+u \0",window->image.width,window->image.height);
  314. X  XSetWindowExtents(window->info,text,2);
  315. X  XMapWindow(display,window->info.id);
  316. X  state|=InfoMappedState;
  317. X  /*
  318. X    Update magnified image until the mouse button is released.
  319. X  */
  320. X  XDefineCursor(display,window->image.id,window->magnify.cursor);
  321. X  x=event->xbutton.x;
  322. X  y=event->xbutton.y;
  323. X  window->magnify.x=x+1;
  324. X  window->magnify.y=y+1;
  325. X  do
  326. X  {
  327. X    /*
  328. X      Check boundary conditions.
  329. X    */
  330. X    if (x < 0)
  331. X      x=0;
  332. X    else
  333. X      if (x >= window->image.width)
  334. X        x=window->image.width-1;
  335. X    if (y < 0)
  336. X      y=0;
  337. X    else
  338. X     if (y >= window->image.height)
  339. X       y=window->image.height-1;
  340. X    if ((window->magnify.x != (window->image.x+x)) ||
  341. X        (window->magnify.y != (window->image.y+y)))
  342. X      {
  343. X        window->magnify.x=window->image.x+x;
  344. X        window->magnify.y=window->image.y+y;
  345. X        /*
  346. X          Map and unmap info window as text cursor crosses its boundaries.
  347. X        */
  348. X        if (state & InfoMappedState)
  349. X          {
  350. X            if ((x < (window->info.x+window->info.width)) &&
  351. X                (y < (window->info.y+window->info.height)))
  352. X              {
  353. X                XWithdrawWindow(display,window->info.id,window->info.screen);
  354. X                state&=(~InfoMappedState);
  355. X              }
  356. X          }
  357. X        else
  358. X          if ((x > (window->info.x+window->info.width)) ||
  359. X              (y > (window->info.y+window->info.height)))
  360. X            {
  361. X              XMapWindow(display,window->info.id);
  362. X              state|=InfoMappedState;
  363. X            }
  364. X        if (state & InfoMappedState)
  365. X          {
  366. X            /*
  367. X              Display pointer position.
  368. X            */
  369. X            (void) sprintf(text," %+d%+d \0",window->magnify.x,
  370. X              window->magnify.y);
  371. X            XClearWindow(display,window->info.id);
  372. X            XDrawImageString(display,window->info.id,
  373. X              window->info.graphic_context,2,window->info.font_info->ascent+2,
  374. X              text,strlen(text));
  375. X          }
  376. X        /*
  377. X          Display magnified image.
  378. X        */
  379. X        XMakeMagnifyImage(display,resource_info,window);
  380. X      }
  381. X    /*
  382. X      Wait for next event.
  383. X    */
  384. X    XWindowEvent(display,window->image.id,ButtonPressMask | Button3MotionMask |
  385. X      ButtonReleaseMask | ExposureMask,event);
  386. X    switch (event->type)
  387. X    {
  388. X      case ButtonPress:
  389. X        break;
  390. X      case ButtonRelease:
  391. X      {
  392. X        /*
  393. X          User has finished magnifying image.
  394. X        */
  395. X        if (event->xbutton.button != Button3)
  396. X          break;
  397. X        x=event->xbutton.x;
  398. X        y=event->xbutton.y;
  399. X        state|=ExitState;
  400. X        break;
  401. X      }
  402. X      case Expose:
  403. X      {
  404. X        /*
  405. X          Refresh image window.
  406. X        */
  407. X        XRefreshWindow(display,&window->image,event);
  408. X        break;
  409. X      }
  410. X      case MotionNotify:
  411. X      {
  412. X        /*
  413. X          Discard pending button motion events.
  414. X        */
  415. X        while (XCheckMaskEvent(display,Button3MotionMask,event));
  416. X        x=event->xmotion.x;
  417. X        y=event->xmotion.y;
  418. X        break;
  419. X      }
  420. X      default:
  421. X        break;
  422. X    }
  423. X  } while (!(state & ExitState));
  424. X  /*
  425. X    Check boundary conditions.
  426. X  */
  427. X  if (x < 0)
  428. X    x=0;
  429. X  else
  430. X    if (x >= window->image.width)
  431. X      x=window->image.width-1;
  432. X  window->magnify.x=window->image.x+x;
  433. X  if (y < 0)
  434. X    y=0;
  435. X  else
  436. X   if (y >= window->image.height)
  437. X     y=window->image.height-1;
  438. X  window->magnify.y=window->image.y+y;
  439. X  /*
  440. X    Display magnified image.
  441. X  */
  442. X  XMakeMagnifyImage(display,resource_info,window);
  443. X  /*
  444. X    Restore cursor.
  445. X  */
  446. X  XDefineCursor(display,window->image.id,window->image.cursor);
  447. X  if (state & InfoMappedState)
  448. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  449. }
  450. X
  451. /*
  452. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  453. %                                                                             %
  454. %                                                                             %
  455. %                                                                             %
  456. %   X M a k e C u r s o r                                                     %
  457. %                                                                             %
  458. %                                                                             %
  459. %                                                                             %
  460. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  461. %
  462. %  Function XMakeCursor creates a crosshairs X11 cursor.
  463. %
  464. %  The format of the XMakeCursor routine is:
  465. %
  466. %      XMakeCursor(display,window,colormap,background_color,foreground_color)
  467. %
  468. %  A description of each parameter follows:
  469. %
  470. %    o display: Specifies a connection to an X server;  returned from
  471. %      XOpenDisplay.
  472. %
  473. %    o window: Specifies the ID of the window for which the cursor is
  474. %      assigned.
  475. %
  476. %    o colormap: Specifies the ID of the colormap from which the background
  477. %      and foreground color will be retrieved.
  478. %
  479. %    o background_color: Specifies the color to use for the cursor background.
  480. %
  481. %    o foreground_color: Specifies the color to use for the cursor foreground.
  482. %
  483. %
  484. */
  485. static Cursor XMakeCursor(display,window,colormap,background_color,
  486. X  foreground_color)
  487. Display
  488. X  *display;
  489. X
  490. Window
  491. X  window;
  492. X
  493. Colormap
  494. X  colormap;
  495. X
  496. char
  497. X  *background_color,
  498. X  *foreground_color;
  499. {
  500. #define scope_height 17
  501. #define scope_mask_width 17
  502. #define scope_mask_height 17
  503. #define scope_x_hot 8
  504. #define scope_y_hot 8
  505. #define scope_width 17
  506. X
  507. X  static unsigned char scope_bit[] =
  508. X    {
  509. X      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  510. X      0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  511. X      0x7e, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  512. X      0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  513. X      0x00, 0x00, 0x00
  514. X    };
  515. X
  516. X  static unsigned char scope_mask_bit[] =
  517. X    {
  518. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  519. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x7f, 0xfc, 0x01,
  520. X      0x7f, 0xfc, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  521. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  522. X      0x80, 0x03, 0x00
  523. X    };
  524. X
  525. X  Cursor
  526. X    cursor;
  527. X
  528. X  Pixmap
  529. X    mask,
  530. X    source;
  531. X
  532. X  XColor
  533. X    background,
  534. X    foreground;
  535. X
  536. X  source=XCreateBitmapFromData(display,window,(char *) scope_bit,scope_width,
  537. X    scope_height);
  538. X  mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bit,
  539. X    scope_width,scope_height);
  540. X  if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
  541. X    Error("unable to create pixmap",(char *) NULL);
  542. X  XParseColor(display,colormap,background_color,&background);
  543. X  XParseColor(display,colormap,foreground_color,&foreground);
  544. X  cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
  545. X    scope_x_hot,scope_y_hot);
  546. X  XFreePixmap(display,source);
  547. X  XFreePixmap(display,mask);
  548. X  return(cursor);
  549. }
  550. X
  551. /*
  552. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  553. %                                                                             %
  554. %                                                                             %
  555. %                                                                             %
  556. %   X M a k e M a g n i f y I m a g e                                         %
  557. %                                                                             %
  558. %                                                                             %
  559. %                                                                             %
  560. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  561. %
  562. %  Function XMakeMagnifyImage magnifies a region of an X image and returns it.
  563. %
  564. %  The format of the XMakeMagnifyImage routine is:
  565. %
  566. %      XMakeMagnifyImage(display,resource_info,window)
  567. %
  568. %  A description of each parameter follows:
  569. %
  570. %    o window: Specifies a pointer to a XWindows structure.
  571. %
  572. %
  573. */
  574. static void XMakeMagnifyImage(display,resource_info,window)
  575. Display
  576. X  *display;
  577. X
  578. XXResourceInfo
  579. X  *resource_info;
  580. X
  581. XXWindows
  582. X  *window;
  583. {
  584. X  register int
  585. X    x,
  586. X    y;
  587. X
  588. X  register unsigned char
  589. X    *p,
  590. X    *q;
  591. X
  592. X  register unsigned int
  593. X    j,
  594. X    k,
  595. X    l;
  596. X
  597. X  static char
  598. X    text[2048];
  599. X
  600. X  static unsigned int
  601. X    previous_magnify=0;
  602. X
  603. X  static XWindowInfo
  604. X    magnify_window;
  605. X
  606. X  unsigned int
  607. X    height,
  608. X    i,
  609. X    magnify,
  610. X    scanline_pad,
  611. X    width;
  612. X
  613. X  XColor
  614. X    color;
  615. X
  616. X  XImage
  617. X    *ximage;
  618. X
  619. X  /*
  620. X    Check boundry conditions.
  621. X  */
  622. X  magnify=1;
  623. X  for (i=1; i < resource_info->magnify; i++)
  624. X    magnify<<=1;
  625. X  while ((magnify*window->image.ximage->width) < window->magnify.width)
  626. X    magnify<<=1;
  627. X  while ((magnify*window->image.ximage->height) < window->magnify.height)
  628. X    magnify<<=1;
  629. X  while (magnify > window->magnify.width)
  630. X    magnify>>=1;
  631. X  while (magnify > window->magnify.height)
  632. X    magnify>>=1;
  633. X  if (magnify != previous_magnify)
  634. X    {
  635. X      unsigned int
  636. X        status;
  637. X
  638. X      XTextProperty
  639. X        window_name;
  640. X
  641. X      /*
  642. X        New magnify factor:  update magnify window name.
  643. X      */
  644. X      i=0;
  645. X      while ((1 << i) <= magnify)
  646. X        i++;
  647. X      (void) sprintf(window->magnify.name,"Magnify %uX",i);
  648. X      status=XStringListToTextProperty(&window->magnify.name,1,&window_name);
  649. X      if (status != 0)
  650. X        XSetWMName(display,window->magnify.id,&window_name);
  651. X    }
  652. X  previous_magnify=magnify;
  653. X  ximage=window->image.ximage;
  654. X  width=window->magnify.ximage->width;
  655. X  height=window->magnify.ximage->height;
  656. X  x=window->magnify.x-(width/magnify/2);
  657. X  if (x < 0)
  658. X    x=0;
  659. X  else
  660. X    if (x > (ximage->width-(width/magnify)))
  661. X      x=ximage->width-width/magnify;
  662. X  y=window->magnify.y-(height/magnify/2);
  663. X  if (y < 0)
  664. X    y=0;
  665. X  else
  666. X    if (y > (ximage->height-(height/magnify)))
  667. X      y=ximage->height-height/magnify;
  668. X  q=(unsigned char *) window->magnify.ximage->data;
  669. X  scanline_pad=window->magnify.ximage->bytes_per_line-
  670. X    ((width*window->magnify.ximage->bits_per_pixel) >> 3);
  671. X  if (ximage->bits_per_pixel < 8)
  672. X    {
  673. X      register unsigned char
  674. X        byte,
  675. X        p_bit,
  676. X        q_bit;
  677. X
  678. X      register unsigned int
  679. X        plane;
  680. X
  681. X      switch (ximage->bitmap_bit_order)
  682. X      {
  683. X        case LSBFirst:
  684. X        {
  685. X          /*
  686. X            Magnify little-endian bitmap.
  687. X          */
  688. X          for (i=0; i < height; i+=magnify)
  689. X          {
  690. X            /*
  691. X              Propogate pixel magnify rows.
  692. X            */
  693. X            for (j=0; j < magnify; j++)
  694. X            {
  695. X              p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  696. X                ((x*ximage->bits_per_pixel) >> 3);
  697. X              p_bit=(x*ximage->bits_per_pixel) & 0x07;
  698. X              q_bit=0;
  699. X              byte=0;
  700. X              for (k=0; k < width; k+=magnify)
  701. X              {
  702. X                /*
  703. X                  Propogate pixel magnify columns.
  704. X                */
  705. X                for (l=0; l < magnify; l++)
  706. X                {
  707. X                  /*
  708. X                    Propogate each bit plane.
  709. X                  */
  710. X                  for (plane=0; plane < ximage->bits_per_pixel; plane++)
  711. X                  {
  712. X                    byte>>=1;
  713. X                    if (*p & (0x01 << (p_bit+plane)))
  714. X                      byte|=0x80;
  715. X                    q_bit++;
  716. X                    if (q_bit == 8)
  717. X                      {
  718. X                        *q++=byte;
  719. X                        q_bit=0;
  720. X                        byte=0;
  721. X                      }
  722. X                  }
  723. X                }
  724. X                p_bit+=ximage->bits_per_pixel;
  725. X                if (p_bit == 8)
  726. X                  {
  727. X                    p++;
  728. X                    p_bit=0;
  729. X                  }
  730. X                if (q_bit > 0)
  731. X                  *q=byte >> (8-q_bit);
  732. X                q+=scanline_pad;
  733. X              }
  734. X            }
  735. X            y++;
  736. X          }
  737. X          break;
  738. X        }
  739. X        case MSBFirst:
  740. X        default:
  741. X        {
  742. X          /*
  743. X            Magnify big-endian bitmap.
  744. X          */
  745. X          for (i=0; i < height; i+=magnify)
  746. X          {
  747. X            /*
  748. X              Propogate pixel magnify rows.
  749. X            */
  750. X            for (j=0; j < magnify; j++)
  751. X            {
  752. X              p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  753. X                ((x*ximage->bits_per_pixel) >> 3);
  754. X              p_bit=(x*ximage->bits_per_pixel) & 0x07;
  755. X              q_bit=0;
  756. X              byte=0;
  757. X              for (k=0; k < width; k+=magnify)
  758. X              {
  759. X                /*
  760. X                  Propogate pixel magnify columns.
  761. X                */
  762. X                for (l=0; l < magnify; l++)
  763. X                {
  764. X                  /*
  765. X                    Propogate each bit plane.
  766. X                  */
  767. X                  for (plane=0; plane < ximage->bits_per_pixel; plane++)
  768. X                  {
  769. X                    byte<<=1;
  770. X                    if (*p & (0x80 >> (p_bit+plane)))
  771. X                      byte|=0x01;
  772. X                    q_bit++;
  773. X                    if (q_bit == 8)
  774. X                      {
  775. X                        *q++=byte;
  776. X                        q_bit=0;
  777. X                        byte=0;
  778. X                      }
  779. X                  }
  780. X                }
  781. X                p_bit+=ximage->bits_per_pixel;
  782. X                if (p_bit == 8)
  783. X                  {
  784. X                    p++;
  785. X                    p_bit=0;
  786. X                  }
  787. X                if (q_bit > 0)
  788. X                  *q=byte << (8-q_bit);
  789. X                q+=scanline_pad;
  790. X              }
  791. X            }
  792. X            y++;
  793. X          }
  794. X          break;
  795. X        }
  796. X      }
  797. X    }
  798. X  else
  799. X    switch (ximage->bits_per_pixel)
  800. X    {
  801. X      case 8:
  802. X      {
  803. X        /*
  804. X          Magnify 8 bit X image.
  805. X        */
  806. X        for (i=0; i < height; i+=magnify)
  807. X        {
  808. X          /*
  809. X            Propogate pixel magnify rows.
  810. X          */
  811. X          for (j=0; j < magnify; j++)
  812. X          {
  813. X            p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  814. X              ((x*ximage->bits_per_pixel) >> 3);
  815. X            for (k=0; k < width; k+=magnify)
  816. X            {
  817. X              /*
  818. X                Propogate pixel magnify columns.
  819. X              */
  820. X              for (l=0; l < magnify; l++)
  821. X                *q++=(*p);
  822. X              p++;
  823. X            }
  824. X            q+=scanline_pad;
  825. X          }
  826. X          y++;
  827. X        }
  828. X        break;
  829. X      }
  830. X      default:
  831. X      {
  832. X        register unsigned int
  833. X          bytes_per_pixel,
  834. X          m;
  835. X
  836. X        /*
  837. X          Magnify multi-byte X image.
  838. X        */
  839. X        bytes_per_pixel=ximage->bits_per_pixel >> 3;
  840. X        for (i=0; i < height; i+=magnify)
  841. X        {
  842. X          /*
  843. X            Propogate pixel magnify rows.
  844. X          */
  845. X          for (j=0; j < magnify; j++)
  846. X          {
  847. X            p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  848. X              ((x*ximage->bits_per_pixel) >> 3);
  849. X            for (k=0; k < width; k+=magnify)
  850. X            {
  851. X              /*
  852. X                Propogate pixel magnify columns.
  853. X              */
  854. X              for (l=0; l < magnify; l++)
  855. X                for (m=0; m < bytes_per_pixel; m++)
  856. X                  *q++=(*(p+m));
  857. X              p+=bytes_per_pixel;
  858. X            }
  859. X            q+=scanline_pad;
  860. X          }
  861. X          y++;
  862. X        }
  863. X        break;
  864. X      }
  865. X    }
  866. X  /*
  867. X    Copy X image to magnify pixmap.
  868. X  */
  869. X  x=window->magnify.x-(width/magnify/2);
  870. X  if (x < 0)
  871. X    x=width/2-window->magnify.x*magnify;
  872. X  else
  873. X    if (x > (ximage->width-(width/magnify)))
  874. X      x=(ximage->width-window->magnify.x)*magnify-width/2;
  875. X    else
  876. X      x=0;
  877. X  y=window->magnify.y-(height/magnify/2);
  878. X  if (y < 0)
  879. X    y=height/2-window->magnify.y*magnify;
  880. X  else
  881. X    if (y > (ximage->height-(height/magnify)))
  882. X      y=(ximage->height-window->magnify.y)*magnify-height/2;
  883. X    else
  884. X      y=0;
  885. X  if ((x != 0) || (y != 0))
  886. X    XFillRectangle(display,window->magnify.pixmap,
  887. X      window->magnify.highlight_context,0,0,width,height);
  888. X  XPutImage(display,window->magnify.pixmap,window->magnify.graphic_context,
  889. X    window->magnify.ximage,0,0,x,y,width-x,height-y);
  890. X  if ((magnify > 1) && ((magnify <= (width/2)) && (magnify <= (height/2))))
  891. X    {
  892. X      /*
  893. X        Highlight center pixel.
  894. X      */
  895. X      x=window->magnify.width/2;
  896. X      y=window->magnify.height/2;
  897. X      XSetForeground(display,window->magnify.graphic_context,
  898. X        window->magnify.pixel_info->background_color.pixel);
  899. X      XDrawRectangle(display,window->magnify.pixmap,
  900. X        window->magnify.graphic_context,x+1,y+1,magnify-2,magnify-2);
  901. X      XSetForeground(display,window->magnify.graphic_context,
  902. X        window->magnify.pixel_info->foreground_color.pixel);
  903. X      XDrawRectangle(display,window->magnify.pixmap,
  904. X        window->magnify.graphic_context,x,y,magnify,magnify);
  905. X    }
  906. X  /*
  907. X    Show center pixel color.
  908. X  */
  909. X  color.pixel=
  910. X    XGetPixel(window->image.ximage,window->magnify.x,window->magnify.y);
  911. X  XQueryColor(display,window->image.map_info->colormap,&color);
  912. X  (void) sprintf(text,"(%3u,%3u,%3u)\0",color.red >> 8,color.green >> 8,
  913. X    color.blue >> 8);
  914. X  XDrawImageString(display,window->magnify.pixmap,
  915. X    window->magnify.graphic_context,2,window->magnify.font_info->ascent+2,text,
  916. X    strlen(text));
  917. X  /*
  918. X    Refresh magnify window.
  919. X  */
  920. X  magnify_window=window->magnify;
  921. X  magnify_window.x=0;
  922. X  magnify_window.y=0;
  923. X  XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
  924. }
  925. X
  926. /*
  927. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  928. %                                                                             %
  929. %                                                                             %
  930. %                                                                             %
  931. %   X P a n I m a g e W i n d o w                                             %
  932. %                                                                             %
  933. %                                                                             %
  934. %                                                                             %
  935. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  936. %
  937. %  Function XPanImageWindow pans the image until the mouse button is released.
  938. %
  939. %  The format of the XPanImageWindow routine is:
  940. %
  941. %    XPanImageWindow(display,window,event)
  942. %
  943. %  A description of each parameter follows:
  944. %
  945. %    o display: Specifies a connection to an X server;  returned from
  946. %      XOpenDisplay.
  947. %
  948. %    o window: Specifies a pointer to a XWindows structure.
  949. %
  950. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  951. %      the entire image is refreshed.
  952. %
  953. */
  954. static void XPanImageWindow(display,window,event)
  955. Display
  956. X  *display;
  957. X
  958. XXWindows
  959. X  *window;
  960. X
  961. XXEvent
  962. X  *event;
  963. {
  964. X  char
  965. X    text[2048];
  966. X
  967. X  Cursor
  968. X    cursor;
  969. X
  970. X  unsigned long int
  971. X    state;
  972. X
  973. X  unsigned long
  974. X    x_factor,
  975. X    y_factor;
  976. X
  977. X  XRectangle
  978. X    pan_info;
  979. X
  980. X  /*
  981. X    Map info window.
  982. X  */
  983. X  state=DefaultState;
  984. X  (void) sprintf(text," %dx%d%+d%+d  \0",window->image.ximage->width,
  985. X    window->image.ximage->height,window->image.ximage->width,
  986. X    window->image.ximage->height);
  987. X  XSetWindowExtents(window->info,text,2);
  988. X  XMapWindow(display,window->info.id);
  989. X  state|=InfoMappedState;
  990. X  /*
  991. X    Define cursor.
  992. X  */
  993. X  if ((window->image.ximage->width > window->image.width) &&
  994. X      (window->image.ximage->height > window->image.height))
  995. X    cursor=XCreateFontCursor(display,XC_fleur);
  996. X  else
  997. X    if (window->image.ximage->width > window->image.width)
  998. X      cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
  999. X    else
  1000. X      if (window->image.ximage->height > window->image.height)
  1001. X        cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
  1002. X      else
  1003. X        cursor=XCreateFontCursor(display,XC_arrow);
  1004. X  if (cursor == (Cursor) NULL)
  1005. X    Error("unable to create cursor",(char *) NULL);
  1006. X  XRecolorCursor(display,cursor,&window->image.pixel_info->background_color,
  1007. X    &window->image.pixel_info->foreground_color);
  1008. X  XDefineCursor(display,window->pan.id,cursor);
  1009. X  /*
  1010. X    Pan image as pointer moves until the mouse button is released.
  1011. X  */
  1012. X  x_factor=(unsigned long)
  1013. X    UpShift(window->image.ximage->width)/window->pan.width;
  1014. X  y_factor=(unsigned long)
  1015. X    UpShift(window->image.ximage->height)/window->pan.height;
  1016. X  pan_info.x=event->xbutton.x;
  1017. X  pan_info.y=event->xbutton.y;
  1018. X  pan_info.width=(unsigned short int) (UpShift(window->image.width)/x_factor);
  1019. X  pan_info.height=(unsigned short int) (UpShift(window->image.height)/y_factor);
  1020. X  window->image.x=pan_info.x+1;
  1021. X  window->image.y=pan_info.y+1;
  1022. X  do
  1023. X  {
  1024. X    /*
  1025. X      Check boundary conditions.
  1026. X    */
  1027. X    pan_info.x=DownShift((pan_info.x-pan_info.width/2)*x_factor);
  1028. X    if (pan_info.x < 0)
  1029. X      pan_info.x=0;
  1030. X    else
  1031. X      if ((pan_info.x+window->image.width) > window->image.ximage->width)
  1032. X        pan_info.x=window->image.ximage->width-window->image.width;
  1033. X    pan_info.y=DownShift((pan_info.y-pan_info.height/2)*y_factor);
  1034. X    if (pan_info.y < 0)
  1035. X      pan_info.y=0;
  1036. X    else
  1037. X      if ((pan_info.y+window->image.height) > window->image.ximage->height)
  1038. X        pan_info.y=window->image.ximage->height-window->image.height;
  1039. X    if ((window->image.x != pan_info.x) || (window->image.y != pan_info.y))
  1040. X      {
  1041. X        /*
  1042. X          Display image pan offset.
  1043. X        */
  1044. X        window->image.x=pan_info.x;
  1045. X        window->image.y=pan_info.y;
  1046. X        (void) sprintf(text," %dx%d%+d%+d \0",window->image.ximage->width,
  1047. X          window->image.ximage->height,window->image.x,window->image.y);
  1048. X        XClearWindow(display,window->info.id);
  1049. X        XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1050. X          window->info.font_info->ascent+2,text,strlen(text));
  1051. X        /*
  1052. X          Refresh image window.
  1053. X        */
  1054. X        XDrawPanRectangle(display,window);
  1055. X        XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1056. X      }
  1057. X    /*
  1058. X      Wait for next event.
  1059. X    */
  1060. X    XWindowEvent(display,window->pan.id,ButtonPressMask | ButtonMotionMask |
  1061. X      ButtonReleaseMask,event);
  1062. X    switch (event->type)
  1063. X    {
  1064. X      case ButtonRelease:
  1065. X      {
  1066. X        /*
  1067. X          User has finished panning the image.
  1068. X        */
  1069. X        pan_info.x=event->xbutton.x;
  1070. X        pan_info.y=event->xbutton.y;
  1071. X        state|=ExitState;
  1072. X        break;
  1073. X      }
  1074. X      case MotionNotify:
  1075. X      {
  1076. X        /*
  1077. X          Discard pending button motion events.
  1078. X        */
  1079. X        while (XCheckMaskEvent(display,ButtonMotionMask,event));
  1080. X        pan_info.x=event->xmotion.x;
  1081. X        pan_info.y=event->xmotion.y;
  1082. X      }
  1083. X      default:
  1084. X        break;
  1085. X    }
  1086. X  } while (!(state & ExitState));
  1087. X  /*
  1088. X    Check boundary conditions.
  1089. X  */
  1090. X  pan_info.x=DownShift((pan_info.x-pan_info.width/2)*x_factor);
  1091. X  if (pan_info.x < 0)
  1092. X    pan_info.x=0;
  1093. X  else
  1094. X    if ((pan_info.x+window->image.width) > window->image.ximage->width)
  1095. X      pan_info.x=window->image.ximage->width-window->image.width;
  1096. X  pan_info.y=DownShift((pan_info.y-pan_info.height/2)*y_factor);
  1097. X  if (pan_info.y < 0)
  1098. X    pan_info.y=0;
  1099. X  else
  1100. X    if ((pan_info.y+window->image.height) > window->image.ximage->height)
  1101. X      pan_info.y=window->image.ximage->height-window->image.height;
  1102. X  if ((window->image.x != pan_info.x) || (window->image.y != pan_info.y))
  1103. X    {
  1104. X      /*
  1105. X        Refresh image window.
  1106. X      */
  1107. X      window->image.x=pan_info.x;
  1108. X      window->image.y=pan_info.y;
  1109. X      XDrawPanRectangle(display,window);
  1110. X      XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1111. X    }
  1112. X  /*
  1113. X    Restore cursor.
  1114. X  */
  1115. X  XDefineCursor(display,window->pan.id,window->pan.cursor);
  1116. X  XFreeCursor(display,cursor);
  1117. X  XWithdrawWindow(display,window->info.id,window->info.screen);
  1118. }
  1119. X
  1120. /*
  1121. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1122. %                                                                             %
  1123. %                                                                             %
  1124. %                                                                             %
  1125. %   X R e f l e c t I m a g e W i n d o w                                     %
  1126. %                                                                             %
  1127. %                                                                             %
  1128. %                                                                             %
  1129. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1130. %
  1131. %  Function XReflectImageWindow reflects the scanlines of an image.
  1132. %
  1133. %  The format of the XReflectImageWindow routine is:
  1134. %
  1135. %    status=XReflectImageWindow(display,window,image)
  1136. %
  1137. %  A description of each parameter follows:
  1138. %
  1139. %    o status: Function XReflectImageWindow return True if the window scanlines
  1140. %      reverse.  False is returned is there is a memory shortage or if the
  1141. %      window scanlines fails to reverse.
  1142. %
  1143. %    o display: Specifies a connection to an X server; returned from
  1144. %      XOpenDisplay.
  1145. %
  1146. %    o window: Specifies a pointer to a XWindows structure.
  1147. %
  1148. %    o image: Specifies a pointer to a Image structure;  returned from
  1149. %      ReadImage.
  1150. %
  1151. %
  1152. */
  1153. static unsigned int XReflectImageWindow(display,window,image)
  1154. Display
  1155. X  *display;
  1156. X
  1157. XXWindows
  1158. X  *window;
  1159. X
  1160. Image
  1161. X  **image;
  1162. {
  1163. X  char
  1164. X    text[2048];
  1165. X
  1166. X  Image
  1167. X    *reflected_image;
  1168. X
  1169. X  unsigned long int
  1170. X    state;
  1171. X
  1172. X  state=DefaultState;
  1173. X  if (((*image)->columns*(*image)->rows) > MinInfoSize)
  1174. X    {
  1175. X      /*
  1176. X        Map image window.
  1177. X      */
  1178. X      (void) strcpy(text," Reflecting image... ");
  1179. X      XSetWindowExtents(window->info,text,2);
  1180. X      XMapWindow(display,window->info.id);
  1181. X      XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1182. X        window->info.font_info->ascent+2,text,strlen(text));
  1183. X      state|=InfoMappedState;
  1184. X    }
  1185. X  /*
  1186. X    Reflect image scanlines.
  1187. X  */
  1188. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1189. X  XFlush(display);
  1190. X  reflected_image=ReflectImage(*image);
  1191. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1192. X  if (state & InfoMappedState)
  1193. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1194. X  if (reflected_image == (Image *) NULL)
  1195. X    return(False);
  1196. X  DestroyImage(*image);
  1197. X  *image=reflected_image;
  1198. X  if (window->image.clip_geometry != (char *) NULL)
  1199. X    {
  1200. X      int
  1201. X        x,
  1202. X        y;
  1203. X
  1204. X      unsigned int
  1205. X        height,
  1206. X        width;
  1207. X
  1208. X      /*
  1209. X        Reverse clip geometry.
  1210. X      */
  1211. X      (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1212. X      (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",width,height,
  1213. X        (int) (*image)->columns-(int) width-x,y);
  1214. X    }
  1215. X  return(True);
  1216. }
  1217. X
  1218. /*
  1219. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1220. %                                                                             %
  1221. %                                                                             %
  1222. %                                                                             %
  1223. %   X R o t a t e I m a g e W i n d o w                                       %
  1224. %                                                                             %
  1225. %                                                                             %
  1226. %                                                                             %
  1227. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1228. %
  1229. %  Function XRotateImageWindow rotates the X image left or right 90 degrees.
  1230. %
  1231. %  The format of the XRotateImageWindow routine is:
  1232. %
  1233. %    status=XRotateImageWindow(display,window,degrees,image)
  1234. %
  1235. %  A description of each parameter follows:
  1236. %
  1237. %    o status: Function XRotateImageWindow return True if the window is
  1238. %      rotated.  False is returned is there is a memory shortage or if the
  1239. %      window fails to rotate.
  1240. %
  1241. %    o display: Specifies a connection to an X server; returned from
  1242. %      XOpenDisplay.
  1243. %
  1244. %    o window: Specifies a pointer to a XWindows structure.
  1245. %
  1246. %    o degrees: Specifies the number of degrees to rotate the image.
  1247. %
  1248. %    o image: Specifies a pointer to a Image structure;  returned from
  1249. %      ReadImage.
  1250. %
  1251. %
  1252. */
  1253. static unsigned int XRotateImageWindow(display,window,degrees,image)
  1254. Display
  1255. X  *display;
  1256. X
  1257. XXWindows
  1258. X  *window;
  1259. X
  1260. unsigned int
  1261. X  degrees;
  1262. X
  1263. Image
  1264. X  **image;
  1265. {
  1266. X  char
  1267. X    text[2048];
  1268. X
  1269. X  int
  1270. X    x,
  1271. X    y;
  1272. X
  1273. X  Image
  1274. X    *rotated_image;
  1275. X
  1276. X  unsigned long int
  1277. X    state;
  1278. X
  1279. X  state=DefaultState;
  1280. X  if (((*image)->columns*(*image)->rows) > MinInfoSize)
  1281. X    {
  1282. X      /*
  1283. X        Map info window.
  1284. X      */
  1285. X      (void) strcpy(text," Rotating image... ");
  1286. X      XSetWindowExtents(window->info,text,2);
  1287. X      XMapWindow(display,window->info.id);
  1288. X      XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1289. X        window->info.font_info->ascent+2,text,strlen(text));
  1290. X      state|=InfoMappedState;
  1291. X    }
  1292. X  /*
  1293. X    Rotate image.
  1294. X  */
  1295. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1296. X  XFlush(display);
  1297. X  rotated_image=RotateImage(*image,(double) degrees,True);
  1298. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1299. X  if (state & InfoMappedState)
  1300. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1301. X  if (rotated_image == (Image *) NULL)
  1302. X    return(False);
  1303. X  DestroyImage(*image);
  1304. X  *image=rotated_image;
  1305. X  if (window->image.clip_geometry != (char *) NULL)
  1306. X    {
  1307. X      unsigned int
  1308. X        height,
  1309. X        width;
  1310. X
  1311. X      /*
  1312. X        Rotate clip geometry.
  1313. X      */
  1314. X      (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1315. X      if (degrees < 180.0)
  1316. X        (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",height,
  1317. X          width,(int) (*image)->columns-(int) height-y,x);
  1318. X      else
  1319. X        (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",height,
  1320. X          width,y,(int) (*image)->rows-(int) width-x);
  1321. X    }
  1322. X  return(True);
  1323. }
  1324. X
  1325. /*
  1326. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1327. %                                                                             %
  1328. %                                                                             %
  1329. %                                                                             %
  1330. %   X T i l e I m a g e W i n d o w                                           %
  1331. %                                                                             %
  1332. %                                                                             %
  1333. %                                                                             %
  1334. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1335. %
  1336. %  Function XTileImageWindow determines which individual tile of a composite
  1337. %  image was choosen with a button press and then displays it.
  1338. %
  1339. %  The format of the XTileImageWindow routine is:
  1340. %
  1341. %    tile_image=XTileImageWindow(display,resource_info,window,image,event)
  1342. %
  1343. %  A description of each parameter follows:
  1344. %
  1345. %    o tile_image:  XTileImageWindow reads the tiled image and returns
  1346. %      it.  A null image is returned if an error occurs.
  1347. %
  1348. %    o display: Specifies a connection to an X server;  returned from
  1349. %      XOpenDisplay.
  1350. %
  1351. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1352. %
  1353. %    o window: Specifies a pointer to a XWindows structure.
  1354. %
  1355. %    o image: Specifies a pointer to a Image structure; returned from
  1356. %      ReadImage.
  1357. %
  1358. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  1359. %      the entire image is refreshed.
  1360. %
  1361. %
  1362. */
  1363. static Image *XTileImageWindow(display,resource_info,window,image,event)
  1364. Display
  1365. X  *display;
  1366. X
  1367. XXResourceInfo
  1368. X  *resource_info;
  1369. X
  1370. XXWindows
  1371. X  *window;
  1372. X
  1373. Image
  1374. X  *image;
  1375. X
  1376. XXEvent
  1377. X  *event;
  1378. {
  1379. X  AlienInfo
  1380. X    alien_info;
  1381. X
  1382. X  char
  1383. X    *p,
  1384. X    *q;
  1385. X
  1386. X  Image
  1387. X    *tile_image;
  1388. X
  1389. X  int
  1390. X    tile,
  1391. X    x,
  1392. X    y;
  1393. X
  1394. X  unsigned int
  1395. X    height,
  1396. X    width;
  1397. X
  1398. X  unsigned long int
  1399. X    scale_factor;
  1400. X
  1401. X  /*
  1402. X    Tile image is relative to composite image configuration.
  1403. X  */
  1404. X  x=0;
  1405. X  y=0;
  1406. X  width=image->columns;
  1407. X  height=image->rows;
  1408. X  if (window->image.clip_geometry != (char *) NULL)
  1409. X    (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1410. X  scale_factor=UpShift(width)/window->image.ximage->width;
  1411. X  event->xbutton.x+=window->image.x;
  1412. X  event->xbutton.x=DownShift(event->xbutton.x*scale_factor)+x;
  1413. X  scale_factor=UpShift(height)/window->image.ximage->height;
  1414. X  event->xbutton.y+=window->image.y;
  1415. X  event->xbutton.y=DownShift(event->xbutton.y*scale_factor)+y;
  1416. X  /*
  1417. X    Determine size and location of individual tiles of the composite.
  1418. X  */
  1419. X  x=0;
  1420. X  y=0;
  1421. X  width=image->columns;
  1422. X  height=image->rows;
  1423. X  (void) XParseGeometry(image->montage,&x,&y,&width,&height);
  1424. X  tile=((event->xbutton.y-y)/height)*((image->columns-x)/width)+
  1425. X    (event->xbutton.x-x)/width;
  1426. X  if (tile < 0)
  1427. X    {
  1428. X      /*
  1429. X        Button press is outside any tile.
  1430. X      */
  1431. X      XBell(display,0);
  1432. X      return((Image *) NULL);
  1433. X    }
  1434. X  /*
  1435. X    Determine file name from the tile directory.
  1436. X  */
  1437. X  p=image->directory;
  1438. X  while ((tile != 0) && (*p != '\0'))
  1439. X  {
  1440. X    if (*p == '\n')
  1441. X      tile--;
  1442. X    p++;
  1443. X  }
  1444. X  if (*p == '\0')
  1445. X    {
  1446. X      /*
  1447. X        Button press is outside any tile.
  1448. X      */
  1449. X      XBell(display,0);
  1450. X      return((Image *) NULL);
  1451. X    }
  1452. X  /*
  1453. X    Read tile image.
  1454. X  */
  1455. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1456. X  XFlush(display);
  1457. X  GetAlienInfo(&alien_info);
  1458. X  q=p;
  1459. X  while ((*q != '\n') && (*q != '\0'))
  1460. X    q++;
  1461. X  (void) strncpy(alien_info.filename,p,q-p);
  1462. X  alien_info.filename[q-p]='\0';
  1463. X  alien_info.server_name=resource_info->server_name;
  1464. X  alien_info.font=resource_info->font;
  1465. X  tile_image=ReadAlienImage(&alien_info);
  1466. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1467. X  if (tile_image == (Image *) NULL)
  1468. X    {
  1469. X      XPopupAlert(display,&window->popup,"unable to read image",
  1470. X        alien_info.filename);
  1471. X      return((Image *) NULL);
  1472. X    }
  1473. X  return(tile_image);
  1474. }
  1475. X
  1476. /*
  1477. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1478. %                                                                             %
  1479. %                                                                             %
  1480. %                                                                             %
  1481. %    M a i n                                                                  %
  1482. %                                                                             %
  1483. %                                                                             %
  1484. %                                                                             %
  1485. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1486. %
  1487. %
  1488. */
  1489. int main(argc,argv)
  1490. int
  1491. X  argc;
  1492. X
  1493. char
  1494. X  **argv;
  1495. {
  1496. X  AlienInfo
  1497. X    alien_info;
  1498. X
  1499. X  char
  1500. X    *clip_geometry,
  1501. X    *option,
  1502. X    *resource_value,
  1503. X    *scale_geometry,
  1504. X    *server_name,
  1505. X    *window_id;
  1506. X
  1507. X  Display
  1508. X    *display;
  1509. X
  1510. X  double
  1511. X    gamma;
  1512. X
  1513. X  int
  1514. X    degrees,
  1515. X    i,
  1516. X    x;
  1517. X
  1518. X  unsigned int
  1519. X    compression,
  1520. X    enhance,
  1521. X    *image_marker,
  1522. X    image_number,
  1523. X    inverse,
  1524. X    noise,
  1525. X    normalize,
  1526. X    reflect,
  1527. X    scene,
  1528. X    verbose;
  1529. X
  1530. X  unsigned long int
  1531. X    state;
  1532. X
  1533. X  XrmDatabase
  1534. X    resource_database,
  1535. X    server_database;
  1536. X
  1537. X  XResourceInfo
  1538. X    resource_info;
  1539. X
  1540. X  /*
  1541. X    Display usage profile if there are no command line arguments.
  1542. X  */
  1543. X  application_name=(*argv);
  1544. X  if (argc < 2)
  1545. X    Usage(True);
  1546. X  /*
  1547. X    Set defaults.
  1548. X  */
  1549. X  GetAlienInfo(&alien_info);
  1550. X  display=(Display *) NULL;
  1551. X  image_marker=(unsigned int *) malloc(argc*sizeof(unsigned int));
  1552. X  if (image_marker == (unsigned int *) NULL)
  1553. X    Error("unable to display image","memory allocation failed");
  1554. X  for (i=0; i < argc; i++)
  1555. X    image_marker[i]=argc;
  1556. X  image_number=0;
  1557. X  resource_database=(XrmDatabase) NULL;
  1558. X  server_name=(char *) NULL;
  1559. X  state=DefaultState;
  1560. X  window_id=(char *) NULL;
  1561. X  /*
  1562. X    Check for server name specified on the command line.
  1563. X  */
  1564. X  for (i=1; i < argc; i++)
  1565. X  {
  1566. X    /*
  1567. X      Check command line for server name.
  1568. X    */
  1569. X    option=argv[i];
  1570. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1571. X      if (strncmp("display",option+1,3) == 0)
  1572. X        {
  1573. X          /*
  1574. X            User specified server name.
  1575. X          */
  1576. X          i++;
  1577. X          if (i == argc)
  1578. X            Error("missing server name on -display",(char *) NULL);
  1579. X          server_name=argv[i];
  1580. X          break;
  1581. X        }
  1582. X  }
  1583. X  /*
  1584. X    Open X server connection.
  1585. X  */
  1586. X  display=XOpenDisplay(server_name);
  1587. X  if (display == (Display *) NULL)
  1588. X    Error("unable to connect to X server",XDisplayName(server_name));
  1589. X  /*
  1590. X    Set our forgiving error handler.
  1591. X  */
  1592. X  XSetErrorHandler(XError);
  1593. X  /*
  1594. X    Initialize resource database.
  1595. X  */
  1596. X  XrmInitialize();
  1597. X  XGetDefault(display,application_name,"dummy");
  1598. X  resource_database=XrmGetDatabase(display);
  1599. X  resource_value=XResourceManagerString(display);
  1600. X  if (resource_value == (char *) NULL)
  1601. X    resource_value="";
  1602. X  server_database=XrmGetStringDatabase(resource_value);
  1603. X  XrmMergeDatabases(server_database,&resource_database);
  1604. X  /*
  1605. X    Get user defaults from X resource database.
  1606. X  */
  1607. X  XGetResourceInfo(resource_database,application_name,&resource_info);
  1608. X  clip_geometry=XGetResource(resource_database,application_name,"clipGeometry",
  1609. X    "ClipGeometry",(char *) NULL);
  1610. X  resource_value=XGetResource(resource_database,application_name,"compression",
  1611. X    (char *) NULL,"RunlengthEncoded");
  1612. X  if (Latin1Compare("qencoded",resource_value) == 0)
  1613. X    compression=QEncodedCompression;
  1614. X  else
  1615. X    compression=RunlengthEncodedCompression;
  1616. X  resource_value=XGetResource(resource_database,application_name,"enhance",
  1617. X    (char *) NULL,"False");
  1618. X  enhance=IsTrue(resource_value);
  1619. X  resource_value=XGetResource(resource_database,application_name,"gamma",
  1620. X    (char *) NULL,"0.0");
  1621. X  gamma=atof(resource_value);
  1622. X  resource_value=XGetResource(resource_database,application_name,"inverse",
  1623. X    (char *) NULL,"False");
  1624. X  inverse=IsTrue(resource_value);
  1625. X  resource_value=XGetResource(resource_database,application_name,"noise",
  1626. X    (char *) NULL,"False");
  1627. X  noise=IsTrue(resource_value);
  1628. X  resource_value=XGetResource(resource_database,application_name,"normalize",
  1629. X    (char *) NULL,"False");
  1630. X  normalize=IsTrue(resource_value);
  1631. X  resource_value=XGetResource(resource_database,application_name,"reflect",
  1632. X    (char *) NULL,"False");
  1633. X  reflect=IsTrue(resource_value);
  1634. X  resource_value=XGetResource(resource_database,application_name,"rotate",
  1635. X    (char *) NULL,"0");
  1636. X  degrees=atoi(resource_value);
  1637. X  scale_geometry=XGetResource(resource_database,application_name,
  1638. X    "scaleGeometry","ScaleGeometry",(char *) NULL);
  1639. X  resource_value=XGetResource(resource_database,application_name,"scene",
  1640. X    (char *) NULL,"0");
  1641. X  scene=atoi(resource_value);
  1642. X  resource_value=XGetResource(resource_database,application_name,"verbose",
  1643. X    (char *) NULL,"False");
  1644. X  verbose=IsTrue(resource_value);
  1645. X  window_id=XGetResource(resource_database,application_name,"windowId",
  1646. X    "WindowId",(char *) NULL);
  1647. X  /*
  1648. X    Parse command line.
  1649. X  */
  1650. X  for (i=1; ((i < argc) && !(state & ExitState)); i++)
  1651. X  {
  1652. X    option=argv[i];
  1653. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1654. X      switch (*(option+1))
  1655. X      {
  1656. X        case 'b':
  1657. X        {
  1658. X          if (strncmp("backdrop",option+1,5) == 0)
  1659. X            {
  1660. X              resource_info.backdrop=(*option == '-');
  1661. X              break;
  1662. X            }
  1663. X          if (strncmp("background",option+1,5) == 0)
  1664. X            {
  1665. X              resource_info.background_color=(char *) NULL;
  1666. X              if (*option == '-')
  1667. X                {
  1668. X                  i++;
  1669. X                  if (i == argc)
  1670. X                    Error("missing color on -background",(char *) NULL);
  1671. X                  resource_info.background_color=argv[i];
  1672. X                }
  1673. X              break;
  1674. X            }
  1675. X          if (strncmp("bordercolor",option+1,7) == 0)
  1676. X            {
  1677. X              resource_info.border_color=(char *) NULL;
  1678. X              if (*option == '-')
  1679. X                {
  1680. X                  i++;
  1681. X                  if (i == argc)
  1682. X                    Error("missing color on -bordercolor",(char *) NULL);
  1683. X                  resource_info.border_color=argv[i];
  1684. X                }
  1685. X              break;
  1686. X            }
  1687. X          if (strncmp("borderwidth",option+1,7) == 0)
  1688. X            {
  1689. X              resource_info.border_width=0;
  1690. X              if (*option == '-')
  1691. X                {
  1692. X                  i++;
  1693. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1694. X                    Error("missing width on -borderwidth",(char *) NULL);
  1695. X                  resource_info.border_width=atoi(argv[i]);
  1696. X                }
  1697. X              break;
  1698. X            }
  1699. X          Error("unrecognized option",option);
  1700. X          break;
  1701. X        }
  1702. X        case 'c':
  1703. X        {
  1704. X          if (strncmp("clip",option+1,2) == 0)
  1705. X            {
  1706. X              clip_geometry=(char *) NULL;
  1707. X              if (*option == '-')
  1708. X                {
  1709. X                  i++;
  1710. X                  if (i == argc)
  1711. X                    Error("missing geometry on -clip",(char *) NULL);
  1712. X                  clip_geometry=argv[i];
  1713. X                }
  1714. X              break;
  1715. X            }
  1716. X          if (strncmp("colormap",option+1,6) == 0)
  1717. X            {
  1718. X              resource_info.colormap=PrivateColormap;
  1719. X              if (*option == '-')
  1720. X                {
  1721. X                  i++;
  1722. X                  if (i == argc)
  1723. X                    Error("missing type on -colormap",(char *) NULL);
  1724. X                  option=argv[i];
  1725. X                  resource_info.colormap=UndefinedColormap;
  1726. X                  if (Latin1Compare("private",option) == 0)
  1727. X                    resource_info.colormap=PrivateColormap;
  1728. X                  if (Latin1Compare("shared",option) == 0)
  1729. X                    resource_info.colormap=SharedColormap;
  1730. X                  if (resource_info.colormap == UndefinedColormap)
  1731. X                    Error("invalid colormap type on -colormap",option);
  1732. X                }
  1733. X              break;
  1734. X            }
  1735. X          if (strncmp("colors",option+1,7) == 0)
  1736. X            {
  1737. X              resource_info.number_colors=0;
  1738. X              if (*option == '-')
  1739. X                {
  1740. X                  i++;
  1741. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1742. X                    Error("missing colors on -colors",(char *) NULL);
  1743. X                  resource_info.number_colors=atoi(argv[i]);
  1744. X                }
  1745. X              break;
  1746. X            }
  1747. X          if (strncmp("colorspace",option+1,7) == 0)
  1748. X            {
  1749. X              resource_info.colorspace=RGBColorspace;
  1750. X              if (*option == '-')
  1751. X                {
  1752. X                  i++;
  1753. X                  if (i == argc)
  1754. X                    Error("missing type on -colorspace",(char *) NULL);
  1755. X                  option=argv[i];
  1756. X                  resource_info.colorspace=UndefinedColorspace;
  1757. X                  if (Latin1Compare("gray",option) == 0)
  1758. X                    resource_info.colorspace=GRAYColorspace;
  1759. X                  if (Latin1Compare("rgb",option) == 0)
  1760. X                    resource_info.colorspace=RGBColorspace;
  1761. X                  if (Latin1Compare("yiq",option) == 0)
  1762. X                    resource_info.colorspace=YIQColorspace;
  1763. X                  if (Latin1Compare("yuv",option) == 0)
  1764. X                    resource_info.colorspace=YUVColorspace;
  1765. X                  if (Latin1Compare("xyz",option) == 0)
  1766. X                    resource_info.colorspace=XYZColorspace;
  1767. X                  if (resource_info.colorspace == UndefinedColorspace)
  1768. X                    Error("invalid colorspace type on -colorspace",option);
  1769. X                }
  1770. X              break;
  1771. X            }
  1772. X          if (strncmp("compress",option+1,3) == 0)
  1773. X            {
  1774. X              compression=NoCompression;
  1775. X              if (*option == '-')
  1776. X                {
  1777. X                  i++;
  1778. X                  if (i == argc)
  1779. X                    Error("missing type on -compress",(char *) NULL);
  1780. X                  option=argv[i];
  1781. X                  if (Latin1Compare("runlengthencoded",option) == 0)
  1782. X                    compression=RunlengthEncodedCompression;
  1783. X                  else
  1784. X                    if (Latin1Compare("qencoded",option) == 0)
  1785. X                      compression=QEncodedCompression;
  1786. X                    else
  1787. X                      Error("invalid compression type on -compress",option);
  1788. X                }
  1789. X              break;
  1790. X            }
  1791. X          Error("unrecognized option",option);
  1792. X          break;
  1793. X        }
  1794. X        case 'd':
  1795. X        {
  1796. X          if (strncmp("debug",option+1,3) == 0)
  1797. X            {
  1798. X              resource_info.debug=(*option == '-');
  1799. X              break;
  1800. X            }
  1801. X          if (strncmp("delay",option+1,3) == 0)
  1802. X            {
  1803. X              resource_info.delay=0;
  1804. X              if (*option == '-')
  1805. X                {
  1806. X                  i++;
  1807. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1808. X                    Error("missing seconds on -delay",(char *) NULL);
  1809. X                  resource_info.delay=atoi(argv[i]);
  1810. X                }
  1811. X              break;
  1812. X            }
  1813. X          if (strncmp("density",option+1,3) == 0)
  1814. X            {
  1815. X              alien_info.density=(char *) NULL;
  1816. X              if (*option == '-')
  1817. X                {
  1818. X                  i++;
  1819. X                  if (i == argc)
  1820. X                    Error("missing density on -density",(char *) NULL);
  1821. X                  alien_info.density=argv[i];
  1822. X                }
  1823. X              break;
  1824. X            }
  1825. X          if (strncmp("display",option+1,3) == 0)
  1826. X            {
  1827. X              server_name=(char *) NULL;
  1828. X              if (*option == '-')
  1829. X                {
  1830. X                  i++;
  1831. X                  if (i == argc)
  1832. X                    Error("missing server name on -display",(char *) NULL);
  1833. X                  server_name=argv[i];
  1834. X                }
  1835. X              resource_info.server_name=server_name;
  1836. X              alien_info.server_name=server_name;
  1837. X              break;
  1838. X            }
  1839. X          if (strncmp("dither",option+1,3) == 0)
  1840. X            {
  1841. X              resource_info.dither=(*option == '-');
  1842. X              break;
  1843. X            }
  1844. X          Error("unrecognized option",option);
  1845. X          break;
  1846. X        }
  1847. X        case 'e':
  1848. X        {
  1849. X          enhance=(*option == '-');
  1850. X          break;
  1851. X        }
  1852. X        case 'f':
  1853. X        {
  1854. X          if (strncmp("font",option+1,3) == 0)
  1855. X            {
  1856. X              resource_info.font=(char *) NULL;
  1857. X              if (*option == '-')
  1858. X                {
  1859. X                  i++;
  1860. X                  if (i == argc)
  1861. X                    Error("missing font name on -font",(char *) NULL);
  1862. X                  resource_info.font=argv[i];
  1863. X                }
  1864. X              alien_info.font=resource_info.font;
  1865. SHAR_EOF
  1866. true || echo 'restore of ImageMagick/display.c failed'
  1867. fi
  1868. echo 'End of  part 13'
  1869. echo 'File ImageMagick/display.c is continued in part 14'
  1870. echo 14 > _shar_seq_.tmp
  1871. exit 0
  1872. exit 0 # Just in case...
  1873.