home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / imagemgc / part22 < prev    next >
Encoding:
Text File  |  1993-07-13  |  50.6 KB  |  1,644 lines

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i078:  imagemagic - X11 image processing and display, Part22/38
  4. Message-ID: <1993Jul14.231910.22005@sparky.sterling.com>
  5. X-Md4-Signature: a3cc000e6e601efd297023107988083b
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:19:10 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 78
  13. Archive-name: imagemagic/part22
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.22 (part 22 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/display.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 22; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/display.c'
  36. else
  37. echo 'x - continuing file ImageMagick/display.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
  39. %      terminate immediately.
  40. %
  41. */
  42. static void Usage(terminate)
  43. unsigned int
  44. X  terminate;
  45. {
  46. X  char
  47. X    **p;
  48. X
  49. X  static char
  50. X    *buttons[]=
  51. X    {
  52. X      "1    press and drag to select a command from a pop-up menu",
  53. X      "2    press and drag to define a region of the image to clip",
  54. X      "3    press and drag to define a region of the image to magnify",
  55. X      (char *) NULL
  56. X    },
  57. X    *keys[]=
  58. X    {
  59. X      "i    display information about the image",
  60. X      "r    reflect the image scanlines",
  61. X      "/    rotate the image 90 degrees clockwise",
  62. X      "\\    rotate the image 90 degrees counter-clockwise",
  63. X      "<    half the image size",
  64. X      ">    double the image size",
  65. X      "o    restore the image to its original size",
  66. X      "a    annotate the image with text",
  67. X      "c    composite image with another",
  68. X      "l    load an image from a file",
  69. X      "w    write the image to a file",
  70. X      "n    display the next image",
  71. X      "p    display the previous image",
  72. X      "q    discard all images and exit program",
  73. X      "1-9  change the level of magnification",
  74. X      (char *) NULL
  75. X    },
  76. X    *options[]=
  77. X    {
  78. X      "-backdrop           display image centered on a backdrop",
  79. X      "-clip geometry      preferred size and location of the clipped image",
  80. X      "-colormap type      Shared or Private",
  81. X      "-colors value       preferred number of colors in the image",
  82. X      "-colorspace type    GRAY, RGB, XYZ, YCbCr, YIQ, or YUV",
  83. X      "-compress type      RunlengthEncoded or QEncoded",
  84. X      "-delay seconds      display the next image after pausing",
  85. X      "-density geometry   vertical and horizonal density of the image",
  86. X      "-display server     display image to this X server",
  87. X      "-dither             apply Floyd/Steinberg error diffusion to image",
  88. X      "-enhance            apply a digital filter to enhance a noisy image",
  89. X      "-gamma value        level of gamma correction",
  90. X      "-geometry geometry  preferred size and location of the image window",
  91. X      "-interlace type     NONE, LINE, or PLANE",
  92. X      "-inverse            apply color inversion to image",
  93. X      "-map type           display image using this Standard Colormap",
  94. X      "-monochrome         transform image to black and white",
  95. X      "-noise              reduce noise with a noise peak elimination filter",
  96. X      "-normalize          tranform image to span the full range of colors",
  97. X      "-page geometry      size and location of the Postscript page",
  98. X      "-quality value      JPEG quality setting",
  99. X      "-reflect            reflect the image scanlines",
  100. X      "-rotate degrees     apply Paeth rotation to the image",
  101. X      "-scale geometry     preferred size factors of the image",
  102. X      "-scene value        image scene number",
  103. X      "-treedepth value    depth of the color classification tree",
  104. X      "-update seconds     detect when image file is modified and redisplay",
  105. X      "-verbose            print detailed information about the image",
  106. X      "-visual type        display image using this visual type",
  107. X      "-window id          display image to background of this window",
  108. X      "-write filename     write image to a file",
  109. X      (char *) NULL
  110. X    };
  111. X  (void) fprintf(stderr,
  112. X    "Usage: %s [-options ...] file [ [-options ...] file ...]\n",client_name);
  113. X  (void) fprintf(stderr,"\nWhere options include: \n");
  114. X  for (p=options; *p != (char *) NULL; p++)
  115. X    (void) fprintf(stderr,"  %s\n",*p);
  116. X  (void) fprintf(stderr,
  117. X    "\nIn addition to those listed above, you can specify these standard X\n");
  118. X  (void) fprintf(stderr,
  119. X    "resources as command line options:  -background, -bordercolor,\n");
  120. X  (void) fprintf(stderr,
  121. X    "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name, or\n");
  122. X  (void) fprintf(stderr,"-title.\n");
  123. X  (void) fprintf(stderr,
  124. X    "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  125. X  (void) fprintf(stderr,
  126. X    "example, specify +compress to store the image as uncompressed.\n");
  127. X  (void) fprintf(stderr,
  128. X    "\nBy default, the image format of `file' is determined by its magic\n");
  129. X  (void) fprintf(stderr,
  130. X    "number.  To specify a particular image format, precede the filename\n");
  131. X  (void) fprintf(stderr,
  132. X    "with an image format name and a colon (i.e. ps:image) or specify the\n");
  133. X  (void) fprintf(stderr,
  134. X    "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
  135. X  (void) fprintf(stderr,"'-' for standard input or output.\n");
  136. X  (void) fprintf(stderr,"\nButtons: \n");
  137. X  for (p=buttons; *p != (char *) NULL; p++)
  138. X    (void) fprintf(stderr,"  %s\n",*p);
  139. X  (void) fprintf(stderr,"\nKeyboard accelerators: \n");
  140. X  for (p=keys; *p != (char *) NULL; p++)
  141. X    (void) fprintf(stderr,"  %s\n",*p);
  142. X  if (terminate)
  143. X    exit(1);
  144. }
  145. X
  146. /*
  147. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  148. %                                                                             %
  149. %                                                                             %
  150. %                                                                             %
  151. %   X A n n o t a t e I m a g e W i n d o w                                   %
  152. %                                                                             %
  153. %                                                                             %
  154. %                                                                             %
  155. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  156. %
  157. %  Function XAnnotateImageWindow annotates the image with text.
  158. %
  159. %  The format of the XAnnotateImageWindow routine is:
  160. %
  161. %    XAnnotateImageWindow(display,resource_info,window,image)
  162. %
  163. %  A description of each parameter follows:
  164. %
  165. %    o display: Specifies a connection to an X server;  returned from
  166. %      XOpenDisplay.
  167. %
  168. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  169. %
  170. %    o window: Specifies a pointer to a XWindows structure.
  171. %
  172. %    o image: Specifies a pointer to a Image structure; returned from
  173. %      ReadImage.
  174. %
  175. */
  176. static unsigned int XAnnotateImageWindow(display,resource_info,window,image)
  177. Display
  178. X  *display;
  179. X
  180. XXResourceInfo
  181. X  *resource_info;
  182. X
  183. XXWindows
  184. X  *window;
  185. X
  186. Image
  187. X  *image;
  188. {
  189. X  char
  190. X    *p,
  191. X    text[2048];
  192. X
  193. X  Cursor
  194. X    cursor;
  195. X
  196. X  GC
  197. X    graphic_context;
  198. X
  199. X  int
  200. X    i,
  201. X    x,
  202. X    y;
  203. X
  204. X  static unsigned int
  205. X    font_id=0,
  206. X    pen_id=0;
  207. X
  208. X  unsigned int
  209. X    height,
  210. X    mask,
  211. X    status,
  212. X    width;
  213. X
  214. X  unsigned long
  215. X    state,
  216. X    x_factor,
  217. X    y_factor;
  218. X
  219. X  Window
  220. X    xwindow;
  221. X
  222. X  XAnnotateInfo
  223. X    *annotate_info,
  224. X    *previous_info;
  225. X
  226. X  XColor
  227. X    pen_color;
  228. X
  229. X  XFontStruct
  230. X    *font_info;
  231. X
  232. X  XEvent
  233. X    event,
  234. X    text_event;
  235. X
  236. X  XGCValues
  237. X    graphic_context_value;
  238. X
  239. X  /*
  240. X    Map info window.
  241. X  */
  242. X  state=DefaultState;
  243. X  (void) sprintf(text," +%u+%u  ",window->image.width,window->image.height);
  244. X  XSetWindowExtents(display,&window->info,text);
  245. X  XMapWindow(display,window->info.id);
  246. X  state|=InfoMappedState;
  247. X  /*
  248. X    Track pointer until button 1 is pressed.
  249. X  */
  250. X  XQueryPointer(display,window->image.id,&xwindow,&xwindow,&i,&i,&x,&y,&mask);
  251. X  XSelectInput(display,window->image.id,window->image.attributes.event_mask |
  252. X    PointerMotionMask);
  253. X  do
  254. X  {
  255. X    if (state & InfoMappedState)
  256. X      {
  257. X        /*
  258. X          Display pointer position.
  259. X        */
  260. X        (void) sprintf(text," %+d%+d ",x-window->image.x,y-window->image.y);
  261. X        XDisplayInfoString(display,&window->info,text);
  262. X      }
  263. X    /*
  264. X      Wait for next event.
  265. X    */
  266. X    XWindowEvent(display,window->image.id,ButtonPressMask | ButtonReleaseMask |
  267. X      ExposureMask | KeyPressMask | PointerMotionMask,&event);
  268. X    switch (event.type)
  269. X    {
  270. X      case ButtonPress:
  271. X      {
  272. X        if ((event.xbutton.button == Button3) &&
  273. X            (event.xbutton.state & Mod1Mask))
  274. X          {
  275. X            /*
  276. X              Convert Alt-Button3 to Button2.
  277. X            */
  278. X            event.xbutton.button=Button2;
  279. X            event.xbutton.state&=(~Mod1Mask);
  280. X          }
  281. X        switch (event.xbutton.button)
  282. X        {
  283. X          case Button1:
  284. X          {
  285. X            /*
  286. X              Change to text entering mode.
  287. X            */
  288. X            x=event.xbutton.x;
  289. X            y=event.xbutton.y;
  290. X            state|=ExitState;
  291. X            break;
  292. X          }
  293. X          case Button2:
  294. X          {
  295. X            char
  296. X              font_name[2048],
  297. X              *MenuSelections[MaxNumberFonts];
  298. X
  299. X            int
  300. X              font_number;
  301. X
  302. X            /*
  303. X              Initialize menu selections.
  304. X            */
  305. X            for (i=0; i < MaxNumberFonts; i++)
  306. X              MenuSelections[i]=resource_info->font_name[i];
  307. X            /*
  308. X              Select a font name from the pop-up menu.
  309. X            */
  310. X            font_number=XPopupMenu(display,&window->popup,event.xbutton.x_root,
  311. X              event.xbutton.y_root,"Pen Fonts",MenuSelections,MaxNumberFonts,
  312. X              font_name);
  313. X            if (font_number >= 0)
  314. X              {
  315. X                /*
  316. X                  Initialize font info.
  317. X                */
  318. X                font_info=XLoadQueryFont(display,font_name);
  319. X                if (font_info == (XFontStruct *) NULL)
  320. X                  XPopupAlert(display,&window->popup,"unable to load font",
  321. X                    font_name);
  322. X                else
  323. X                  {
  324. X                    font_id=font_number;
  325. X                    XFreeFont(display,font_info);
  326. X                  }
  327. X              }
  328. X            break;
  329. X          }
  330. X          case Button3:
  331. X          {
  332. X            char
  333. X              color_name[2048],
  334. X              *MenuSelections[MaxNumberPens];
  335. X
  336. X            int
  337. X              pen_number;
  338. X
  339. X            /*
  340. X              Initialize menu selections.
  341. X            */
  342. X            for (i=0; i < MaxNumberPens; i++)
  343. X              MenuSelections[i]=resource_info->pen_color[i];
  344. X            /*
  345. X              Select a font color from the pop-up menu.
  346. X            */
  347. X            pen_number=XPopupMenu(display,&window->popup,event.xbutton.x_root,
  348. X              event.xbutton.y_root,"Pen Colors",MenuSelections,MaxNumberPens,
  349. X              color_name);
  350. X            if (pen_number >= 0)
  351. X              pen_id=pen_number;
  352. X            break;
  353. X          }
  354. X        }
  355. X        break;
  356. X      }
  357. X      case Expose:
  358. X      {
  359. X        /*
  360. X          Refresh image window.
  361. X        */
  362. X        XRefreshWindow(display,&window->image,&event);
  363. X        break;
  364. X      }
  365. X      case KeyPress:
  366. X      {
  367. X        static char
  368. X          command[2048];
  369. X
  370. X        static KeySym
  371. X          key_symbol;
  372. X
  373. X        /*
  374. X          Respond to a user key press.
  375. X        */
  376. X        *command='\0';
  377. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  378. X          &key_symbol,(XComposeStatus *) NULL);
  379. X        if (key_symbol == XK_Escape)
  380. X          {
  381. X            /*
  382. X              Prematurely exit.
  383. X            */
  384. X            state|=EscapeState;
  385. X            state|=ExitState;
  386. X            break;
  387. X          }
  388. X        break;
  389. X      }
  390. X      case MotionNotify:
  391. X      {
  392. X        /*
  393. X          Discard pending pointer motion events.
  394. X        */
  395. X        while (XCheckMaskEvent(display,PointerMotionMask,&event));
  396. X        x=event.xmotion.x;
  397. X        y=event.xmotion.y;
  398. X        /*
  399. X          Map and unmap info window as cursor crosses its boundaries.
  400. X        */
  401. X        if (state & InfoMappedState)
  402. X          {
  403. X            if ((x < (window->info.x+window->info.width)) &&
  404. X                (y < (window->info.y+window->info.height)))
  405. X              {
  406. X                XWithdrawWindow(display,window->info.id,window->info.screen);
  407. X                state&=(~InfoMappedState);
  408. X              }
  409. X          }
  410. X        else
  411. X          if ((x > (window->info.x+window->info.width)) ||
  412. X              (y > (window->info.y+window->info.height)))
  413. X            {
  414. X              XMapWindow(display,window->info.id);
  415. X              state|=InfoMappedState;
  416. X            }
  417. X        break;
  418. X      }
  419. X      default:
  420. X        break;
  421. X    }
  422. X  } while (!(state & ExitState));
  423. X  XSelectInput(display,window->image.id,window->image.attributes.event_mask);
  424. X  if (state & InfoMappedState)
  425. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  426. X  XFlush(display);
  427. X  if (state & EscapeState)
  428. X    return(True);
  429. X  /*
  430. X    Set font info and pen color.
  431. X  */
  432. X  font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
  433. X  if (font_info == (XFontStruct *) NULL)
  434. X    {
  435. X      XPopupAlert(display,&window->popup,"unable to load font",
  436. X        resource_info->font_name[font_id]);
  437. X      font_info=window->image.font_info;
  438. X    }
  439. X  /*
  440. X    Initialize graphic context.
  441. X  */
  442. X  pen_color=window->image.pixel_info->pen_color[pen_id];
  443. X  graphic_context_value.background=
  444. X    window->image.pixel_info->background_color.pixel;
  445. X  graphic_context_value.foreground=pen_color.pixel;
  446. X  graphic_context_value.font=font_info->fid;
  447. X  graphic_context_value.function=GXcopy;
  448. X  graphic_context_value.graphics_exposures=False;
  449. X  graphic_context_value.line_width=WindowBorderWidth;
  450. X  graphic_context_value.plane_mask=AllPlanes;
  451. X  graphic_context_value.subwindow_mode=IncludeInferiors;
  452. X  graphic_context=XCreateGC(display,window->image.id,GCBackground |
  453. X    GCFont | GCForeground | GCFunction | GCGraphicsExposures | GCLineWidth |
  454. X    GCPlaneMask | GCSubwindowMode,&graphic_context_value);
  455. X  if (graphic_context == (GC) NULL)
  456. X    return(False);
  457. X  /*
  458. X    Check boundary conditions.
  459. X  */
  460. X  if ((x+font_info->max_bounds.width) >= window->image.width)
  461. X    x=window->image.width-font_info->max_bounds.width;
  462. X  if (y < (font_info->ascent+font_info->descent))
  463. X    y=font_info->ascent+font_info->descent;
  464. X  if ((font_info->max_bounds.width > window->image.width) ||
  465. X      ((font_info->ascent+font_info->descent) >= window->image.height))
  466. X    return(False);
  467. X  /*
  468. X    Initialize annotate structure.
  469. X  */
  470. X  annotate_info=(XAnnotateInfo *) malloc(sizeof(XAnnotateInfo));
  471. X  if (annotate_info == (XAnnotateInfo *) NULL)
  472. X    return(False);
  473. X  XGetAnnotateInfo(annotate_info);
  474. X  annotate_info->x=x;
  475. X  annotate_info->y=y;
  476. X  annotate_info->height=font_info->ascent+font_info->descent;
  477. X  annotate_info->font_info=font_info;
  478. X  annotate_info->text=(char *) malloc(
  479. X    (window->image.width/Max(font_info->min_bounds.width,1)+2)*sizeof(char));
  480. X  if (annotate_info->text == (char *) NULL)
  481. X    return(False);
  482. X  /*
  483. X    Begin annotating the image with text.
  484. X  */
  485. X  state=DefaultState;
  486. X  cursor=XCreateFontCursor(display,XC_pencil);
  487. X  if (cursor == (Cursor) NULL)
  488. X    {
  489. X      Warning("unable to create cursor",(char *) NULL);
  490. X      return(False);
  491. X    }
  492. X  XRecolorCursor(display,cursor,&window->image.pixel_info->background_color,
  493. X    &window->image.pixel_info->foreground_color);
  494. X  XDefineCursor(display,window->image.id,cursor);
  495. X  XDrawString(display,window->image.id,graphic_context,x,y,"_",1);
  496. X  text_event.xexpose.width=(unsigned int) font_info->max_bounds.width;
  497. X  text_event.xexpose.height=annotate_info->height;
  498. X  p=annotate_info->text;
  499. X  *p='\0';
  500. X  do
  501. X  {
  502. X    /*
  503. X      Wait for next event.
  504. X    */
  505. X    XWindowEvent(display,window->image.id,ExposureMask | KeyPressMask,&event);
  506. X    switch (event.type)
  507. X    {
  508. X      case Expose:
  509. X      {
  510. X        if (event.xexpose.count == 0)
  511. X          {
  512. X            /*
  513. X              Refresh image window.
  514. X            */
  515. X            XRefreshWindow(display,&window->image,(XEvent *) NULL);
  516. X            XDrawString(display,window->image.id,graphic_context,
  517. X              annotate_info->x,annotate_info->y,annotate_info->text,
  518. X              strlen(annotate_info->text));
  519. X            XDrawString(display,window->image.id,graphic_context,x,y,"_",1);
  520. X          }
  521. X        break;
  522. X      }
  523. X      case KeyPress:
  524. X      {
  525. X        static char
  526. X          command[2048];
  527. X
  528. X        static KeySym
  529. X          key_symbol;
  530. X
  531. X        /*
  532. X          Erase text cursor.
  533. X        */
  534. X        text_event.xexpose.x=x;
  535. X        text_event.xexpose.y=y-font_info->max_bounds.ascent;
  536. X        XRefreshWindow(display,&window->image,&text_event);
  537. X        /*
  538. X          Respond to a user key press.
  539. X        */
  540. X        *command='\0';
  541. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  542. X          &key_symbol,(XComposeStatus *) NULL);
  543. X        if (event.xkey.state & ControlMask)
  544. X          switch (key_symbol)
  545. X          {
  546. X            case XK_u:
  547. X            case XK_U:
  548. X            {
  549. X              key_symbol=XK_Delete;
  550. X              break;
  551. X            }
  552. X            default:
  553. X              break;
  554. X          }
  555. X        switch (key_symbol)
  556. X        {
  557. X          case XK_BackSpace:
  558. X          {
  559. X            /*
  560. X              Erase one character.
  561. X            */
  562. X            if (p == annotate_info->text)
  563. X              if (annotate_info->previous == (XAnnotateInfo *) NULL)
  564. X                break;
  565. X              else
  566. X                {
  567. X                  /*
  568. X                    Go to end of the previous line of text.
  569. X                  */
  570. X                  annotate_info=annotate_info->previous;
  571. X                  p=annotate_info->text;
  572. X                  x=annotate_info->x+annotate_info->width;
  573. X                  y=annotate_info->y;
  574. X                  if (annotate_info->width != 0)
  575. X                    p+=strlen(annotate_info->text);
  576. X                  break;
  577. X                }
  578. X            p--;
  579. X            x-=XTextWidth(font_info,p,1);
  580. X            text_event.xexpose.x=x;
  581. X            text_event.xexpose.y=y-font_info->max_bounds.ascent;
  582. X            XRefreshWindow(display,&window->image,&text_event);
  583. X            break;
  584. X          }
  585. X          case XK_Delete:
  586. X          {
  587. X            /*
  588. X              Erase the entire line of text.
  589. X            */
  590. X            while (p != annotate_info->text)
  591. X            {
  592. X              p--;
  593. X              x-=XTextWidth(font_info,p,1);
  594. X              text_event.xexpose.x=x;
  595. X              XRefreshWindow(display,&window->image,&text_event);
  596. X            }
  597. X            break;
  598. X          }
  599. X          case XK_Escape:
  600. X          {
  601. X            /*
  602. X              Finished annotating.
  603. X            */
  604. X            annotate_info->width=XTextWidth(font_info,annotate_info->text,
  605. X              strlen(annotate_info->text));
  606. X            XRefreshWindow(display,&window->image,&text_event);
  607. X            state|=ExitState;
  608. X            break;
  609. X          }
  610. X          default:
  611. X          {
  612. X            /*
  613. X              Draw a single character on the image window.
  614. X            */
  615. X            if (*command == '\0')
  616. X              break;
  617. X            *p=(*command);
  618. X            XDrawString(display,window->image.id,graphic_context,x,y,p,1);
  619. X            x+=XTextWidth(font_info,p,1);
  620. X            p++;
  621. X            if ((x+font_info->max_bounds.width) < window->image.width)
  622. X              break;
  623. X          }
  624. X          case XK_Return:
  625. X          {
  626. X            /*
  627. X              Advance to the next line of text.
  628. X            */
  629. X            *p='\0';
  630. X            annotate_info->width=XTextWidth(font_info,annotate_info->text,
  631. X              strlen(annotate_info->text));
  632. X            if (annotate_info->next != (XAnnotateInfo *) NULL)
  633. X              {
  634. X                /*
  635. X                  Line of text already exists.
  636. X                */
  637. X                annotate_info=annotate_info->next;
  638. X                x=annotate_info->x;
  639. X                y=annotate_info->y;
  640. X                p=annotate_info->text;
  641. X                break;
  642. X              }
  643. X            annotate_info->next=(XAnnotateInfo *) malloc(sizeof(XAnnotateInfo));
  644. X            if (annotate_info->next == (XAnnotateInfo *) NULL)
  645. X              return(False);
  646. X            *annotate_info->next=(*annotate_info);
  647. X            annotate_info->next->previous=annotate_info;
  648. X            annotate_info=annotate_info->next;
  649. X            annotate_info->text=(char *) malloc((window->image.width/
  650. X              Max(font_info->min_bounds.width,1)+2)*sizeof(char));
  651. X            if (annotate_info->text == (char *) NULL)
  652. X              return(False);
  653. X            annotate_info->y+=annotate_info->height;
  654. X            if (annotate_info->y > window->image.height)
  655. X              annotate_info->y=annotate_info->height;
  656. X            annotate_info->next=(XAnnotateInfo *) NULL;
  657. X            x=annotate_info->x;
  658. X            y=annotate_info->y;
  659. X            p=annotate_info->text;
  660. X            break;
  661. X          }
  662. X        }
  663. X        /*
  664. X          Display text cursor.
  665. X        */
  666. X        *p='\0';
  667. X        XDrawString(display,window->image.id,graphic_context,x,y,"_",1);
  668. X        break;
  669. X      }
  670. X      default:
  671. X        break;
  672. X    }
  673. X  } while (!(state & ExitState));
  674. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  675. X  XFreeCursor(display,cursor);
  676. X  XFlush(display);
  677. X  /*
  678. X    Annotation is relative to image configuration.
  679. X  */
  680. X  x=0;
  681. X  y=0;
  682. X  width=image->columns;
  683. X  height=image->rows;
  684. X  if (window->image.clip_geometry != (char *) NULL)
  685. X    (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  686. X  /*
  687. X    Initialize annotated image.
  688. X  */
  689. X  while (annotate_info != (XAnnotateInfo *) NULL)
  690. X  {
  691. X    if (annotate_info->width == 0)
  692. X      {
  693. X        /*
  694. X          No text on this line--  go to the next line of text.
  695. X        */
  696. X        previous_info=annotate_info->previous;
  697. X        (void) free((char *) annotate_info->text);
  698. X        (void) free((char *) annotate_info);
  699. X        annotate_info=previous_info;
  700. X        continue;
  701. X      }
  702. X    /*
  703. X      Determine foreground pixel index for font color.
  704. X    */
  705. X    window->image.pixel_info->annotate_color=pen_color;
  706. X    window->image.pixel_info->annotate_index=0;
  707. X    if (window->image.pixel_info->colors != 0)
  708. X      for (i=0; i < window->image.pixel_info->colors; i++)
  709. X        if (window->image.pixel_info->pixels[i] == pen_color.pixel)
  710. X          {
  711. X            window->image.pixel_info->annotate_index=i;
  712. X            break;
  713. X          }
  714. X    /*
  715. X      Define the annotate geometry string.
  716. X    */
  717. X    x_factor=UpShift(width)/window->image.ximage->width;
  718. X    annotate_info->x+=window->image.x;
  719. X    annotate_info->x=DownShift(annotate_info->x*x_factor);
  720. X    y_factor=UpShift(height)/window->image.ximage->height;
  721. X    annotate_info->y+=(window->image.y-font_info->ascent);
  722. X    annotate_info->y=DownShift(annotate_info->y*y_factor);
  723. X    (void) sprintf(annotate_info->geometry,"%ux%u%+d%+d",
  724. X      (unsigned int) DownShift(annotate_info->width*x_factor),
  725. X      (unsigned int) DownShift(annotate_info->height*y_factor),
  726. X      annotate_info->x+x,annotate_info->y+y);
  727. X    /*
  728. X      Annotate image with text.
  729. X    */
  730. X    status=XAnnotateImage(display,&window->image,annotate_info,False,image);
  731. X    if (status == 0)
  732. X      return(False);
  733. X    /*
  734. X      Free up memory.
  735. X    */
  736. X    previous_info=annotate_info->previous;
  737. X    (void) free((char *) annotate_info->text);
  738. X    (void) free((char *) annotate_info);
  739. X    annotate_info=previous_info;
  740. X  }
  741. X  XDefineCursor(display,window->image.id,window->image.cursor);
  742. X  /*
  743. X    Free up memory.
  744. X  */
  745. X  if (font_info != window->image.font_info)
  746. X    XFreeFont(display,font_info);
  747. X  XFreeGC(display,graphic_context);
  748. X  return(True);
  749. }
  750. X
  751. /*
  752. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  753. %                                                                             %
  754. %                                                                             %
  755. %                                                                             %
  756. %   X C l i p I m a g e W i n d o w                                           %
  757. %                                                                             %
  758. %                                                                             %
  759. %                                                                             %
  760. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  761. %
  762. %  Function XClipImageWindow displays a rectangle whose sizes changes as the
  763. %  pointer moves.  When the mouse button is released, the geometry of the image
  764. %  region defined within the rectangle is returned.
  765. %
  766. %  The format of the XClipImageWindow routine is:
  767. %
  768. %    XClipImageWindow(display,resource_info,window,event,image)
  769. %
  770. %  A description of each parameter follows:
  771. %
  772. %    o display: Specifies a connection to an X server; returned from
  773. %      XOpenDisplay.
  774. %
  775. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  776. %
  777. %    o window: Specifies a pointer to a XWindows structure.
  778. %
  779. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  780. %      the entire image is refreshed.
  781. %
  782. %    o image: Specifies a pointer to a Image structure.
  783. %
  784. %
  785. */
  786. static void XClipImageWindow(display,resource_info,window,event,image,state)
  787. Display
  788. X  *display;
  789. X
  790. XXResourceInfo
  791. X  *resource_info;
  792. X
  793. XXWindows
  794. X  *window;
  795. X
  796. XXEvent
  797. X  *event;
  798. X
  799. Image
  800. X  *image;
  801. X
  802. unsigned long
  803. X  *state;
  804. {
  805. #define MinimumClipArea  (unsigned int) 9
  806. X
  807. X  char
  808. X    text[2048];
  809. X
  810. X  int
  811. X    x_offset,
  812. X    y_offset;
  813. X
  814. X  RectangleInfo
  815. X    clip_info;
  816. X
  817. X  /*
  818. X    Set the width of info window.
  819. X  */
  820. X  (void) sprintf(text," %ux%u+%u+%u ",window->image.width,
  821. X    window->image.height,window->image.width,window->image.height);
  822. X  XSetWindowExtents(display,&window->info,text);
  823. X  /*
  824. X    Size rectangle as pointer moves until the mouse button is released.
  825. X  */
  826. X  x_offset=event->xbutton.x;
  827. X  y_offset=event->xbutton.y;
  828. X  clip_info.x=x_offset;
  829. X  clip_info.y=y_offset;
  830. X  clip_info.width=0;
  831. X  clip_info.height=0;
  832. X  XSetFunction(display,window->image.graphic_context,GXinvert);
  833. X  do
  834. X  {
  835. X    if ((clip_info.width*clip_info.height) >= MinimumClipArea)
  836. X      {
  837. X        /*
  838. X          Display info and draw clipping rectangle.
  839. X        */
  840. X        if (!(*state & InfoMappedState))
  841. X          {
  842. X            XMapWindow(display,window->info.id);
  843. X            *state|=InfoMappedState;
  844. X          }
  845. X        (void) sprintf(text," %ux%u%+d%+d",clip_info.width,clip_info.height,
  846. X          clip_info.x,clip_info.y);
  847. X        XDisplayInfoString(display,&window->info,text);
  848. X        XDrawRectangle(display,window->image.id,window->image.graphic_context,
  849. X          clip_info.x,clip_info.y,clip_info.width-1,clip_info.height-1);
  850. X      }
  851. X    else
  852. X      if (*state & InfoMappedState)
  853. X        {
  854. X          /*
  855. X            Clipping rectangle is too small;  withdraw info window.
  856. X          */
  857. X          XWithdrawWindow(display,window->info.id,window->info.screen);
  858. X          *state&=(~InfoMappedState);
  859. X        }
  860. X    /*
  861. X      Wait for next event.
  862. X    */
  863. X    XWindowEvent(display,window->image.id,ButtonPressMask | ButtonMotionMask |
  864. X      ButtonReleaseMask | ExposureMask,event);
  865. X    if ((clip_info.width*clip_info.height) >= MinimumClipArea)
  866. X      XDrawRectangle(display,window->image.id,window->image.graphic_context,
  867. X        clip_info.x,clip_info.y,clip_info.width-1,clip_info.height-1);
  868. X    switch (event->type)
  869. X    {
  870. X      case ButtonPress:
  871. X        break;
  872. X      case ButtonRelease:
  873. X      {
  874. X        /*
  875. X          User has committed to clipping rectangle.
  876. X        */
  877. X        clip_info.x=event->xbutton.x;
  878. X        clip_info.y=event->xbutton.y;
  879. X        *state|=ExitState;
  880. X        break;
  881. X      }
  882. X      case Expose:
  883. X      {
  884. X        /*
  885. X          Refresh image window.
  886. X        */
  887. X        XRefreshWindow(display,&window->image,event);
  888. X        break;
  889. X      }
  890. X      case MotionNotify:
  891. X      {
  892. X        /*
  893. X          Discard pending button motion events.
  894. X        */
  895. X        while (XCheckMaskEvent(display,ButtonMotionMask,event));
  896. X        clip_info.x=event->xmotion.x;
  897. X        clip_info.y=event->xmotion.y;
  898. X      }
  899. X      default:
  900. X        break;
  901. X    }
  902. X    /*
  903. X      Check boundary conditions.
  904. X    */
  905. X    if (clip_info.x < 0)
  906. X      clip_info.x=0;
  907. X    else
  908. X      if (clip_info.x > window->image.width)
  909. X        clip_info.x=window->image.width;
  910. X    if (clip_info.x < x_offset)
  911. X      clip_info.width=(unsigned int) (x_offset-clip_info.x);
  912. X    else
  913. X      {
  914. X        clip_info.width=(unsigned int) (clip_info.x-x_offset);
  915. X        clip_info.x=x_offset;
  916. X      }
  917. X    if (clip_info.y < 0)
  918. X      clip_info.y=0;
  919. X    else
  920. X      if (clip_info.y > window->image.height)
  921. X        clip_info.y=window->image.height;
  922. X    if (clip_info.y < y_offset)
  923. X      clip_info.height=(unsigned int) (y_offset-clip_info.y);
  924. X    else
  925. X      {
  926. X        clip_info.height=(unsigned int) (clip_info.y-y_offset);
  927. X        clip_info.y=y_offset;
  928. X      }
  929. X  } while (!(*state & ExitState));
  930. X  *state&=(~ExitState);
  931. X  XSetFunction(display,window->image.graphic_context,GXcopy);
  932. X  if (*state & InfoMappedState)
  933. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  934. X  if ((clip_info.width*clip_info.height) >= MinimumClipArea)
  935. X    {
  936. X      unsigned int
  937. X        status;
  938. X
  939. X      XWindowChanges
  940. X        window_changes;
  941. X
  942. X      /*
  943. X        Image configuration has changed.
  944. X      */
  945. X      XSetClipGeometry(display,window,&clip_info,image);
  946. X      status=XConfigureImageWindow(display,resource_info,window,clip_info.width,
  947. X        clip_info.height,image);
  948. X      if (status == False)
  949. X        XPopupAlert(display,&window->popup,"unable to configure X image",
  950. X          window->image.name);
  951. X      /*
  952. X        Reconfigure image window as defined by clipping rectangle.
  953. X      */
  954. X      window_changes.width=clip_info.width;
  955. X      window_changes.height=clip_info.height;
  956. X      XReconfigureWMWindow(display,window->image.id,window->image.screen,
  957. X        CWWidth | CWHeight,&window_changes);
  958. X      *state|=ReconfigureImageState;
  959. X    }
  960. }
  961. X
  962. /*
  963. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  964. %                                                                             %
  965. %                                                                             %
  966. %                                                                             %
  967. %   X C o m p o s i t e I m a g e W i n d o w                                 %
  968. %                                                                             %
  969. %                                                                             %
  970. %                                                                             %
  971. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  972. %
  973. %  Function XCompositeImageWindow requests an image name from the user, reads
  974. %  the image and composites it with the X window image at a location the user
  975. %  chooses with the pointer.
  976. %
  977. %  The format of the XCompositeImageWindow routine is:
  978. %
  979. %    XCompositeImageWindow(display,resource_info,window,image)
  980. %
  981. %  A description of each parameter follows:
  982. %
  983. %    o display: Specifies a connection to an X server;  returned from
  984. %      XOpenDisplay.
  985. %
  986. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  987. %
  988. %    o window: Specifies a pointer to a XWindows structure.
  989. %
  990. %    o image: Specifies a pointer to a Image structure; returned from
  991. %      ReadImage.
  992. %
  993. */
  994. static unsigned int XCompositeImageWindow(display,resource_info,window,image)
  995. Display
  996. X  *display;
  997. X
  998. XXResourceInfo
  999. X  *resource_info;
  1000. X
  1001. XXWindows
  1002. X  *window;
  1003. X
  1004. Image
  1005. X  **image;
  1006. {
  1007. #define CompositeRectangle(composite_info)  \
  1008. {  \
  1009. X  if ((composite_info.width*composite_info.height) > (unsigned int) 0) \
  1010. X    {  \
  1011. X      XSetFunction(display,window->image.graphic_context,GXinvert);  \
  1012. X      XDrawRectangle(display,window->image.id,window->image.graphic_context,  \
  1013. X        composite_info.x,composite_info.y,composite_info.width-1,  \
  1014. X        composite_info.height-1);  \
  1015. X      XSetFunction(display,window->image.graphic_context,GXcopy);  \
  1016. X    }  \
  1017. }
  1018. X
  1019. X  char
  1020. X    filename[2048],
  1021. X    text[2048];
  1022. X
  1023. X  Cursor
  1024. X    cursor;
  1025. X
  1026. X  Image
  1027. X    *composite_image;
  1028. X
  1029. X  int
  1030. X    i,
  1031. X    x,
  1032. X    y;
  1033. X
  1034. X  static unsigned int
  1035. X    operator = OverCompositeOp;
  1036. X
  1037. X  unsigned int
  1038. X    height,
  1039. X    mask,
  1040. X    width;
  1041. X
  1042. X  unsigned long
  1043. X    scale_factor,
  1044. X    state;
  1045. X
  1046. X  Window
  1047. X    xwindow;
  1048. X
  1049. X  XEvent
  1050. X    event;
  1051. X
  1052. X  XRectangle
  1053. X    composite_info;
  1054. X
  1055. X  /*
  1056. X    Request image file name from user.
  1057. X  */
  1058. X  *filename='\0';
  1059. X  XPopupQuery(display,&window->popup,"File name:",filename);
  1060. X  XFlush(display);
  1061. X  if (*filename == '\0')
  1062. X    return(True);
  1063. X  /*
  1064. X    Read image.
  1065. X  */
  1066. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1067. X  XFlush(display);
  1068. X  (void) strcpy(resource_info->image_info->filename,filename);
  1069. X  composite_image=ReadImage(resource_info->image_info);
  1070. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1071. X  if (composite_image == (Image *) NULL)
  1072. X    {
  1073. X      XPopupAlert(display,&window->popup,"unable to read image",filename);
  1074. X      return(False);
  1075. X    }
  1076. X  /*
  1077. X    Map info window.
  1078. X  */
  1079. X  state=DefaultState;
  1080. X  (void) sprintf(text," +%u+%u  ",window->image.width,window->image.height);
  1081. X  XSetWindowExtents(display,&window->info,text);
  1082. X  XMapWindow(display,window->info.id);
  1083. X  state|=InfoMappedState;
  1084. X  /*
  1085. X    Track pointer until button 1 is pressed.
  1086. X  */
  1087. X  XQueryPointer(display,window->image.id,&xwindow,&xwindow,&i,&i,&x,&y,&mask);
  1088. X  composite_info.x=x;
  1089. X  composite_info.y=y;
  1090. X  composite_info.width=0;
  1091. X  composite_info.height=0;
  1092. X  XSelectInput(display,window->image.id,window->image.attributes.event_mask |
  1093. X    PointerMotionMask);
  1094. X  cursor=XCreateFontCursor(display,XC_ul_angle);
  1095. X  if (cursor == (Cursor) NULL)
  1096. X    {
  1097. X      Warning("unable to create cursor",(char *) NULL);
  1098. X      return(False);
  1099. X    }
  1100. X  do
  1101. X  {
  1102. X    if (state & InfoMappedState)
  1103. X      {
  1104. X        /*
  1105. X          Display pointer position.
  1106. X        */
  1107. X        (void) sprintf(text," %+d%+d ",x-window->image.x,y-window->image.y);
  1108. X        XDisplayInfoString(display,&window->info,text);
  1109. X      }
  1110. X    CompositeRectangle(composite_info);
  1111. X    /*
  1112. X      Wait for next event.
  1113. X    */
  1114. X    XWindowEvent(display,window->image.id,ButtonPressMask | ButtonReleaseMask |
  1115. X      ExposureMask | KeyPressMask | PointerMotionMask,&event);
  1116. X    CompositeRectangle(composite_info);
  1117. X    switch (event.type)
  1118. X    {
  1119. X      case ButtonPress:
  1120. X      {
  1121. X        if ((event.xbutton.button == Button3) &&
  1122. X            (event.xbutton.state & Mod1Mask))
  1123. X          {
  1124. X            /*
  1125. X              Convert Alt-Button3 to Button2.
  1126. X            */
  1127. X            event.xbutton.button=Button2;
  1128. X            event.xbutton.state&=(~Mod1Mask);
  1129. X          }
  1130. X        switch (event.xbutton.button)
  1131. X        {
  1132. X          case Button1:
  1133. X          {
  1134. X            composite_info.width=composite_image->columns;
  1135. X            composite_info.height=composite_image->rows;
  1136. X            XRecolorCursor(display,cursor,
  1137. X              &window->image.pixel_info->background_color,
  1138. X              &window->image.pixel_info->foreground_color);
  1139. X            XDefineCursor(display,window->image.id,cursor);
  1140. X            break;
  1141. X          }
  1142. X          case Button2:
  1143. X          {
  1144. X            char
  1145. X              command[2048];
  1146. X
  1147. X            static char
  1148. X              *CompositeSelections[]=
  1149. X              {
  1150. X                "over",
  1151. X                "in",
  1152. X                "out",
  1153. X                "atop",
  1154. X                "xor",
  1155. X                "plus",
  1156. X                "minus",
  1157. X                "add",
  1158. X                "subtract",
  1159. X                "difference",
  1160. X                "replace",
  1161. X              };
  1162. X
  1163. X            /*
  1164. X              Select a command from the pop-up menu.
  1165. X            */
  1166. X            operator=XPopupMenu(display,&window->popup,event.xbutton.x_root,
  1167. X              event.xbutton.y_root,"Operations",CompositeSelections,
  1168. X              sizeof(CompositeSelections)/sizeof(CompositeSelections[0]),
  1169. X              command);
  1170. X            break;
  1171. X          }
  1172. X          default:
  1173. X            break;
  1174. X        }
  1175. X        break;
  1176. X      }
  1177. X      case ButtonRelease:
  1178. X      {
  1179. X        if (event.xbutton.button == Button1)
  1180. X          {
  1181. X            /*
  1182. X              User has selected the location of the composite image.
  1183. X            */
  1184. X            composite_info.x=event.xbutton.x;
  1185. X            composite_info.y=event.xbutton.y;
  1186. X            state|=ExitState;
  1187. X          }
  1188. X        break;
  1189. X      }
  1190. X      case Expose:
  1191. X      {
  1192. X        /*
  1193. X          Refresh image window.
  1194. X        */
  1195. X        XRefreshWindow(display,&window->image,&event);
  1196. X        break;
  1197. X      }
  1198. X      case KeyPress:
  1199. X      {
  1200. X        static char
  1201. X          command[2048];
  1202. X
  1203. X        static KeySym
  1204. X          key_symbol;
  1205. X
  1206. X        /*
  1207. X          Respond to a user key press.
  1208. X        */
  1209. X        *command='\0';
  1210. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1211. X          &key_symbol,(XComposeStatus *) NULL);
  1212. X        if (key_symbol == XK_Escape)
  1213. X          {
  1214. X            /*
  1215. X              Prematurely exit.
  1216. X            */
  1217. X            DestroyImage(composite_image);
  1218. X            state|=EscapeState;
  1219. X            state|=ExitState;
  1220. X            break;
  1221. X          }
  1222. X        break;
  1223. X      }
  1224. X      case MotionNotify:
  1225. X      {
  1226. X        /*
  1227. X          Discard pending pointer motion events.
  1228. X        */
  1229. X        while (XCheckMaskEvent(display,PointerMotionMask,&event));
  1230. X        x=event.xmotion.x;
  1231. X        y=event.xmotion.y;
  1232. X        /*
  1233. X          Map and unmap info window as text cursor crosses its boundaries.
  1234. X        */
  1235. X        if (state & InfoMappedState)
  1236. X          {
  1237. X            if ((x < (window->info.x+window->info.width)) &&
  1238. X                (y < (window->info.y+window->info.height)))
  1239. X              {
  1240. X                XWithdrawWindow(display,window->info.id,window->info.screen);
  1241. X                state&=(~InfoMappedState);
  1242. X              }
  1243. X          }
  1244. X        else
  1245. X          if ((x > (window->info.x+window->info.width)) ||
  1246. X              (y > (window->info.y+window->info.height)))
  1247. X            {
  1248. X              XMapWindow(display,window->info.id);
  1249. X              state|=InfoMappedState;
  1250. X            }
  1251. X        composite_info.x=x;
  1252. X        composite_info.y=y;
  1253. X        break;
  1254. X      }
  1255. X      default:
  1256. X        break;
  1257. X    }
  1258. X  } while (!(state & ExitState));
  1259. X  XSelectInput(display,window->image.id,window->image.attributes.event_mask);
  1260. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1261. X  XFreeCursor(display,cursor);
  1262. X  if (state & InfoMappedState)
  1263. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1264. X  XFlush(display);
  1265. X  if (state & EscapeState)
  1266. X    return(True);
  1267. X  /*
  1268. X    Image compositing is relative to image configuration.
  1269. X  */
  1270. X  x=0;
  1271. X  y=0;
  1272. X  width=(*image)->columns;
  1273. X  height=(*image)->rows;
  1274. X  if (window->image.clip_geometry != (char *) NULL)
  1275. X    (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1276. X  scale_factor=UpShift(width)/window->image.ximage->width;
  1277. X  composite_info.x+=window->image.x;
  1278. X  composite_info.x=DownShift(composite_info.x*scale_factor);
  1279. X  composite_info.width=DownShift(composite_info.width*scale_factor);
  1280. X  scale_factor=UpShift(height)/window->image.ximage->height;
  1281. X  composite_info.y+=window->image.y;
  1282. X  composite_info.y=DownShift(composite_info.y*scale_factor);
  1283. X  composite_info.height=DownShift(composite_info.height*scale_factor);
  1284. X  if ((composite_info.width != composite_image->columns) ||
  1285. X      (composite_info.height != composite_image->rows))
  1286. X    {
  1287. X      Image
  1288. X        *scaled_image;
  1289. X
  1290. X      /*
  1291. X        Scale composite image.
  1292. X      */
  1293. X      scaled_image=
  1294. X        ScaleImage(composite_image,composite_info.width,composite_info.height);
  1295. X      if (scaled_image == (Image *) NULL)
  1296. X        {
  1297. X          XDefineCursor(display,window->image.id,window->image.cursor);
  1298. X          DestroyImage(composite_image);
  1299. X          return(False);
  1300. X        }
  1301. X      composite_image=scaled_image;
  1302. X    }
  1303. X  /*
  1304. X    Composite image with X image window.
  1305. X  */
  1306. X  CompositeImage(*image,operator,composite_image,composite_info.x+x,
  1307. X    composite_info.y+y);
  1308. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1309. X  return(True);
  1310. }
  1311. X
  1312. /*
  1313. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1314. %                                                                             %
  1315. %                                                                             %
  1316. %                                                                             %
  1317. %   X C o n f i g u r e I m a g e W i n d o w                                 %
  1318. %                                                                             %
  1319. %                                                                             %
  1320. %                                                                             %
  1321. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1322. %
  1323. %  Function XConfigureImageWindow creates a new X image.  It's size is
  1324. %  determined by the width and height parameters.  If the size does not
  1325. %  change, the image is displayed to the X image window.
  1326. %
  1327. %  The format of the XConfigureImageWindow routine is:
  1328. %
  1329. %    status=XConfigureImageWindow(display,resource_info,window,width,height,
  1330. %      image)
  1331. %
  1332. %  A description of each parameter follows:
  1333. %
  1334. %    o status: Function XConfigureImageWindow returns True if the window is
  1335. %      resized.  False is returned is there is a memory shortage or if the
  1336. %      window fails to resize.
  1337. %
  1338. %    o display: Specifies a connection to an X server; returned from
  1339. %      XOpenDisplay.
  1340. %
  1341. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1342. %
  1343. %    o window: Specifies a pointer to a XWindows structure.
  1344. %
  1345. %    o width: Specifies the new width in pixels of the image.
  1346. %
  1347. %    o height: Specifies the new height in pixels of the image.
  1348. %
  1349. %    o image: Specifies a pointer to a Image structure;  returned from
  1350. %      ReadImage.
  1351. %
  1352. %
  1353. */
  1354. static unsigned int XConfigureImageWindow(display,resource_info,window,width,
  1355. X  height,image)
  1356. Display
  1357. X  *display;
  1358. X
  1359. XXResourceInfo
  1360. X  *resource_info;
  1361. X
  1362. XXWindows
  1363. X  *window;
  1364. X
  1365. unsigned int
  1366. X  width,
  1367. X  height;
  1368. X
  1369. Image
  1370. X  *image;
  1371. {
  1372. X  char
  1373. X    text[2048];
  1374. X
  1375. X  unsigned int
  1376. X    status;
  1377. X
  1378. X  unsigned long
  1379. X    state;
  1380. X
  1381. X  state=DefaultState;
  1382. X  if ((window->image.width*window->image.height) > MinInfoSize)
  1383. X    {
  1384. X      /*
  1385. X        Map info window.
  1386. X      */
  1387. X      (void) strcpy(text," Configuring image... ");
  1388. X      XSetWindowExtents(display,&window->info,text);
  1389. X      XMapWindow(display,window->info.id);
  1390. X      XDisplayInfoString(display,&window->info,text);
  1391. X      state|=InfoMappedState;
  1392. X    }
  1393. X  /*
  1394. X    Resize image to fit image window dimensions.
  1395. X  */
  1396. X  if (resource_info->debug)
  1397. X    (void) fprintf(stderr,"Configure Image: %dx%d=>%ux%u\n",
  1398. X      window->image.ximage->width,window->image.ximage->height,width,height);
  1399. X  status=XMakeImage(display,resource_info,&window->image,image,width,height);
  1400. X  if (resource_info->use_pixmap)
  1401. X    (void) XMakePixmap(display,resource_info,&window->image);
  1402. X  if (state & InfoMappedState)
  1403. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1404. X  return(status);
  1405. }
  1406. X
  1407. /*
  1408. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1409. %                                                                             %
  1410. %                                                                             %
  1411. %                                                                             %
  1412. %   X D i s p l a y B a c k g r o u n d I m a g e                             %
  1413. %                                                                             %
  1414. %                                                                             %
  1415. %                                                                             %
  1416. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1417. %
  1418. %  Function XDisplayBackgroundImage displays an image in the root window.
  1419. %
  1420. %  The format of the XDisplayBackgroundImage routine is:
  1421. %
  1422. %      XDisplayBackgroundImage(display,resource_info,window_id,image)
  1423. %
  1424. %  A description of each parameter follows:
  1425. %
  1426. %    o display: Specifies a connection to an X server;  returned from
  1427. %      XOpenDisplay.
  1428. %
  1429. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1430. %
  1431. %    o window_id: Specifies a pointer to a string with a window id or name.
  1432. %
  1433. %    o image: Specifies a pointer to a Image structure; returned from
  1434. %      ReadImage.
  1435. %
  1436. %
  1437. */
  1438. static void XDisplayBackgroundImage(display,resource_info,window_id,image)
  1439. Display
  1440. X  *display;
  1441. X
  1442. XXResourceInfo
  1443. X  *resource_info;
  1444. X
  1445. char
  1446. X  *window_id;
  1447. X
  1448. Image
  1449. X  *image;
  1450. {
  1451. X  Atom
  1452. X    property,
  1453. X    type;
  1454. X
  1455. X  int
  1456. X    format;
  1457. X
  1458. X  unsigned char
  1459. X    *data;
  1460. X
  1461. X  unsigned int
  1462. X    height,
  1463. X    status,
  1464. X    width;
  1465. X
  1466. X  unsigned long
  1467. X    after,
  1468. X    length;
  1469. X
  1470. X  Window
  1471. X    root_window;
  1472. X
  1473. X  XGCValues
  1474. X    graphic_context_value;
  1475. X
  1476. X  XPixelInfo
  1477. X    pixel_info;
  1478. X
  1479. X  XStandardColormap
  1480. X    *map_info;
  1481. X
  1482. X  XWindowInfo
  1483. X    window_info;
  1484. X
  1485. X  XVisualInfo
  1486. X    *visual_info;
  1487. X
  1488. X  /*
  1489. X    Allocate standard colormap.
  1490. X  */
  1491. X  map_info=XAllocStandardColormap();
  1492. X  if (map_info == (XStandardColormap *) NULL)
  1493. X    Error("unable to create standard colormap","memory allocation failed");
  1494. X  map_info->colormap=(Colormap) NULL;
  1495. X  pixel_info.pixels=(unsigned long *) NULL;
  1496. X  /*
  1497. X    Initialize visual info.
  1498. X  */
  1499. X  if ((resource_info->visual_type != (char *) NULL) ||
  1500. X      (resource_info->map_type != (char *) NULL))
  1501. X    visual_info=XBestVisualInfo(display,resource_info->visual_type,
  1502. X      resource_info->map_type,map_info);
  1503. X  else
  1504. X    {
  1505. X      int
  1506. X        number_visuals;
  1507. X
  1508. X      XVisualInfo
  1509. X        visual_template;
  1510. X
  1511. X      /*
  1512. X        Get the default visual.
  1513. X      */
  1514. X      visual_template.visualid=
  1515. X        XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
  1516. X      visual_info=XGetVisualInfo(display,VisualIDMask,&visual_template,
  1517. X        &number_visuals);
  1518. X    }
  1519. X  if (visual_info == (XVisualInfo *) NULL)
  1520. X    Error("unable to get visual",resource_info->visual_type);
  1521. X  if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  1522. X    Error("visual must be server default",resource_info->visual_type);
  1523. X  /*
  1524. X    If there are previous resources on the root window, destroy them.
  1525. X  */
  1526. X  root_window=XRootWindow(display,visual_info->screen);
  1527. X  property=XInternAtom(display,"_XSETROOT_ID",False);
  1528. X  if (property == (Atom) NULL)
  1529. X    Error("unable to create X property","_XSETROOT_ID");
  1530. X  (void) XGetWindowProperty(display,root_window,property,0L,1L,True,
  1531. X    (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
  1532. X  if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
  1533. X    {
  1534. X      /*
  1535. X        Free previous resources on the root window.
  1536. X      */
  1537. X      XKillClient(display,(XID) (*((Pixmap *) data)));
  1538. X      XFree((void *) data);
  1539. X    }
  1540. X  /*
  1541. X    Initialize colormap.
  1542. X  */
  1543. X  XMakeStandardColormap(display,visual_info,resource_info,&pixel_info,image,
  1544. X    map_info);
  1545. X  if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  1546. X    Error("unable to display X image on the root window","too many colors");
  1547. X  /*
  1548. X    Graphic context superclass.
  1549. X  */
  1550. X  graphic_context_value.background=pixel_info.background_color.pixel;
  1551. X  graphic_context_value.foreground=pixel_info.foreground_color.pixel;
  1552. X  graphic_context_value.fill_style=FillSolid;
  1553. X  graphic_context_value.function=GXcopy;
  1554. X  graphic_context_value.graphics_exposures=False;
  1555. X  graphic_context_value.plane_mask=AllPlanes;
  1556. X  pixel_info.graphic_context=XCreateGC(display,root_window,GCBackground |
  1557. X    GCFillStyle | GCForeground | GCFunction | GCGraphicsExposures |
  1558. X    GCPlaneMask,&graphic_context_value);
  1559. X  if (pixel_info.graphic_context == (GC) NULL)
  1560. X    Error("unable to create graphic context",(char *) NULL);
  1561. X  graphic_context_value.background=pixel_info.foreground_color.pixel;
  1562. X  graphic_context_value.foreground=pixel_info.background_color.pixel;
  1563. X  pixel_info.highlight_context=XCreateGC(display,root_window,GCBackground |
  1564. X    GCFillStyle | GCForeground | GCFunction | GCGraphicsExposures |
  1565. X    GCPlaneMask,&graphic_context_value);
  1566. X  if (pixel_info.highlight_context == (GC) NULL)
  1567. X    Error("unable to create graphic context",(char *) NULL);
  1568. X  /*
  1569. X    Initialize image window attributes.
  1570. X  */
  1571. X  window_info.id=(Window) NULL;
  1572. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,(XFontStruct *) NULL,
  1573. X    resource_info,&window_info);
  1574. X  /*
  1575. X    Determine target window.
  1576. X  */
  1577. X  if (Latin1Compare(window_id,"root") == 0)
  1578. X    window_info.id=root_window;
  1579. X  else
  1580. X    {
  1581. X      if (isdigit(*window_id))
  1582. X        window_info.id=XWindowByID(display,root_window,
  1583. X          (Window) strtol((char *) window_id,(char **) NULL,0));
  1584. X      if (window_info.id == (Window) NULL)
  1585. X        window_info.id=XWindowByName(display,root_window,window_id);
  1586. X      if (window_info.id == (Window) NULL)
  1587. X        Error("No window with specified id exists",window_id);
  1588. X    }
  1589. X  /*
  1590. X    Create the X image.
  1591. X  */
  1592. X  window_info.width=image->columns;
  1593. X  if (window_info.width >= XDisplayWidth(display,visual_info->screen))
  1594. X    window_info.width=XDisplayWidth(display,visual_info->screen);
  1595. X  window_info.height=image->rows;
  1596. X  if (window_info.height >= XDisplayHeight(display,visual_info->screen))
  1597. X    window_info.height=XDisplayHeight(display,visual_info->screen);
  1598. X  status=XMakeImage(display,resource_info,&window_info,image,image->columns,
  1599. X    image->rows);
  1600. X  if (status == False)
  1601. X    Error("unable to create X image",(char *) NULL);
  1602. X  /*
  1603. X    Adjust image dimensions as specified by backdrop or geometry options.
  1604. X  */
  1605. X  width=window_info.width;
  1606. X  height=window_info.height;
  1607. X  if (resource_info->backdrop)
  1608. X    {
  1609. X      /*
  1610. X        Center image on root window.
  1611. X      */
  1612. X      window_info.x=
  1613. X        XDisplayWidth(display,visual_info->screen)/2-image->columns/2;
  1614. X      window_info.y=
  1615. X        XDisplayHeight(display,visual_info->screen)/2-image->rows/2;
  1616. X      width=XDisplayWidth(display,visual_info->screen);
  1617. X      height=XDisplayHeight(display,visual_info->screen);
  1618. X    }
  1619. X  if (resource_info->image_geometry != (char *) NULL)
  1620. X    {
  1621. X      char
  1622. X        default_geometry[2048];
  1623. X
  1624. X      int
  1625. X        flags,
  1626. X        gravity;
  1627. X
  1628. X      XSizeHints
  1629. X        *size_hints;
  1630. SHAR_EOF
  1631. true || echo 'restore of ImageMagick/display.c failed'
  1632. fi
  1633. echo 'End of ImageMagick part 22'
  1634. echo 'File ImageMagick/display.c is continued in part 23'
  1635. echo 23 > _shar_seq_.tmp
  1636. exit 0
  1637.  
  1638. exit 0 # Just in case...
  1639. -- 
  1640.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1641. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1642.  "It's intuitively obvious to the |
  1643.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1644.