home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume34 / imagemagick / part12 < prev    next >
Encoding:
Text File  |  1992-12-14  |  57.3 KB  |  1,665 lines

  1. Newsgroups: comp.sources.misc
  2. From: cristy@eplrx7.es.duPont.com (John Cristy)
  3. Subject:  v34i040:  imagemagick - X11 image processing and display v2.2, Part12/26
  4. Message-ID: <1992Dec15.035143.21544@sparky.imd.sterling.com>
  5. X-Md4-Signature: c4a06df659543192ed0d3e71248dbb9c
  6. Date: Tue, 15 Dec 1992 03:51:43 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 40
  11. Archive-name: imagemagick/part12
  12. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  13.  
  14. #!/bin/sh
  15. # this is Part.12 (part 12 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" != 12; 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            composite_info.height=composite_image->rows;
  37. X            cursor=XCreateFontCursor(display,XC_ul_angle);
  38. X            XRecolorCursor(display,cursor,
  39. X              &window->image.pixel_info->background_color,
  40. X              &window->image.pixel_info->foreground_color);
  41. X            XDefineCursor(display,window->image.id,cursor);
  42. X            break;
  43. X          }
  44. X          case Button2:
  45. X          {
  46. X            static char
  47. X              command[2048],
  48. X              *CompositeSelections[]=
  49. X              {
  50. X                "over",
  51. X                "in",
  52. X                "out",
  53. X                "atop",
  54. X                "xor",
  55. X                "plus",
  56. X                "minus",
  57. X                "add",
  58. X                "subtract",
  59. X                "difference",
  60. X                "replace",
  61. X              };
  62. X
  63. X            /*
  64. X              Select a command from the pop-up menu.
  65. X            */
  66. X            operator=XPopupMenu(display,&window->popup,event.xbutton.x_root,
  67. X              event.xbutton.y_root,"Operations",CompositeSelections,
  68. X              sizeof(CompositeSelections)/sizeof(CompositeSelections[0]),
  69. X              command);
  70. X            break;
  71. X          }
  72. X          default:
  73. X            break;
  74. X        }
  75. X        break;
  76. X      }
  77. X      case ButtonRelease:
  78. X      {
  79. X        if (event.xbutton.button == Button1)
  80. X          {
  81. X            /*
  82. X              User has selected the location of the composite image.
  83. X            */
  84. X            composite_info.x=event.xbutton.x;
  85. X            composite_info.y=event.xbutton.y;
  86. X            state|=ExitState;
  87. X          }
  88. X        break;
  89. X      }
  90. X      case Expose:
  91. X      {
  92. X        /*
  93. X          Refresh image window.
  94. X        */
  95. X        XRefreshWindow(display,&window->image,&event);
  96. X        break;
  97. X      }
  98. X      case KeyPress:
  99. X      {
  100. X        static char
  101. X          command[2048];
  102. X
  103. X        static KeySym
  104. X          key_symbol;
  105. X
  106. X        /*
  107. X          Respond to a user key press.
  108. X        */
  109. X        *command='\0';
  110. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  111. X          &key_symbol,(XComposeStatus *) NULL);
  112. X        if (key_symbol == XK_Escape)
  113. X          {
  114. X            /*
  115. X              Prematurely exit.
  116. X            */
  117. X            DestroyImage(composite_image);
  118. X            state|=EscapeState;
  119. X            state|=ExitState;
  120. X            break;
  121. X          }
  122. X        break;
  123. X      }
  124. X      case MotionNotify:
  125. X      {
  126. X        /*
  127. X          Discard pending pointer motion events.
  128. X        */
  129. X        while (XCheckMaskEvent(display,PointerMotionMask,&event));
  130. X        x=event.xmotion.x;
  131. X        y=event.xmotion.y;
  132. X        /*
  133. X          Map and unmap info window as text cursor crosses its boundaries.
  134. X        */
  135. X        if (state & InfoMappedState)
  136. X          {
  137. X            if ((x < (window->info.x+window->info.width)) &&
  138. X                (y < (window->info.y+window->info.height)))
  139. X              {
  140. X                XWithdrawWindow(display,window->info.id,window->info.screen);
  141. X                state&=(~InfoMappedState);
  142. X              }
  143. X          }
  144. X        else
  145. X          if ((x > (window->info.x+window->info.width)) ||
  146. X              (y > (window->info.y+window->info.height)))
  147. X            {
  148. X              XMapWindow(display,window->info.id);
  149. X              state|=InfoMappedState;
  150. X            }
  151. X        composite_info.x=x;
  152. X        composite_info.y=y;
  153. X        break;
  154. X      }
  155. X      default:
  156. X        break;
  157. X    }
  158. X  } while (!(state & ExitState));
  159. X  XSelectInput(display,window->image.id,window->image.attributes.event_mask);
  160. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  161. X  XFreeCursor(display,cursor);
  162. X  if (state & InfoMappedState)
  163. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  164. X  XFlush(display);
  165. X  if (state & EscapeState)
  166. X    return(True);
  167. X  /*
  168. X    Image compositing is relative to image configuration.
  169. X  */
  170. X  x=0;
  171. X  y=0;
  172. X  width=(*image)->columns;
  173. X  height=(*image)->rows;
  174. X  if (window->image.clip_geometry != (char *) NULL)
  175. X    (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  176. X  scale_factor=UpShift(width)/window->image.ximage->width;
  177. X  composite_info.x+=window->image.x;
  178. X  composite_info.x=DownShift(composite_info.x*scale_factor);
  179. X  composite_info.width=DownShift(composite_info.width*scale_factor);
  180. X  scale_factor=UpShift(height)/window->image.ximage->height;
  181. X  composite_info.y+=window->image.y;
  182. X  composite_info.y=DownShift(composite_info.y*scale_factor);
  183. X  composite_info.height=DownShift(composite_info.height*scale_factor);
  184. X  if ((composite_info.width != composite_image->columns) ||
  185. X      (composite_info.height != composite_image->rows))
  186. X    {
  187. X      Image
  188. X        *scaled_image;
  189. X
  190. X      /*
  191. X        Scale composite image.
  192. X      */
  193. X      scaled_image=
  194. X        ScaleImage(composite_image,composite_info.width,composite_info.height);
  195. X      if (scaled_image == (Image *) NULL)
  196. X        {
  197. X          XDefineCursor(display,window->image.id,window->image.cursor);
  198. X          DestroyImage(composite_image);
  199. X          return(False);
  200. X        }
  201. X      composite_image=scaled_image;
  202. X    }
  203. X  /*
  204. X    Composite image with X image window.
  205. X  */
  206. X  CompositeImage(*image,operator,composite_image,composite_info.x+x,
  207. X    composite_info.y+y);
  208. X  XDefineCursor(display,window->image.id,window->image.cursor);
  209. X  return(True);
  210. }
  211. X
  212. /*
  213. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  214. %                                                                             %
  215. %                                                                             %
  216. %                                                                             %
  217. %   X C o n f i g u r e I m a g e W i n d o w                                 %
  218. %                                                                             %
  219. %                                                                             %
  220. %                                                                             %
  221. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  222. %
  223. %  Function XConfigureImageWindow creates a new X image.  It's size is
  224. %  determined by the width and height parameters.  If the size does not
  225. %  change, the image is displayed to the X image window.
  226. %
  227. %  The format of the XConfigureImageWindow routine is:
  228. %
  229. %    status=XConfigureImageWindow(display,resource_info,window,width,height,
  230. %      image)
  231. %
  232. %  A description of each parameter follows:
  233. %
  234. %    o status: Function XConfigureImageWindow returns True if the window is
  235. %      resized.  False is returned is there is a memory shortage or if the
  236. %      window fails to resize.
  237. %
  238. %    o display: Specifies a connection to an X server; returned from
  239. %      XOpenDisplay.
  240. %
  241. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  242. %
  243. %    o window: Specifies a pointer to a XWindows structure.
  244. %
  245. %    o width: Specifies the new width in pixels of the image.
  246. %
  247. %    o height: Specifies the new height in pixels of the image.
  248. %
  249. %    o image: Specifies a pointer to a Image structure;  returned from
  250. %      ReadImage.
  251. %
  252. %
  253. */
  254. static unsigned int XConfigureImageWindow(display,resource_info,window,width,
  255. X  height,image)
  256. Display
  257. X  *display;
  258. X
  259. XXResourceInfo
  260. X  *resource_info;
  261. X
  262. XXWindows
  263. X  *window;
  264. X
  265. unsigned int
  266. X  width,
  267. X  height;
  268. X
  269. Image
  270. X  *image;
  271. {
  272. X  char
  273. X    text[2048];
  274. X
  275. X  unsigned int
  276. X    status;
  277. X
  278. X  unsigned long int
  279. X    state;
  280. X
  281. X  state=DefaultState;
  282. X  if ((window->image.width*window->image.height) > MinInfoSize)
  283. X    {
  284. X      /*
  285. X        Map info window.
  286. X      */
  287. X      (void) strcpy(text," Configuring image... ");
  288. X      XSetWindowExtents(window->info,text,2);
  289. X      XMapWindow(display,window->info.id);
  290. X      XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  291. X        window->info.font_info->ascent+2,text,strlen(text));
  292. X      state|=InfoMappedState;
  293. X    }
  294. X  /*
  295. X    Resize image to fit image window dimensions.
  296. X  */
  297. X  if (resource_info->debug)
  298. X    (void) fprintf(stderr,"Configure Image: %dx%d=>%ux%u\n",
  299. X      window->image.ximage->width,window->image.ximage->height,width,height);
  300. X  status=XMakeImage(display,resource_info,&window->image,image,width,height);
  301. X  (void) XMakePixmap(display,resource_info,&window->image);
  302. X  if (state & InfoMappedState)
  303. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  304. X  return(status);
  305. }
  306. X
  307. /*
  308. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  309. %                                                                             %
  310. %                                                                             %
  311. %                                                                             %
  312. %   X D i s p l a y B a c k g r o u n d I m a g e                             %
  313. %                                                                             %
  314. %                                                                             %
  315. %                                                                             %
  316. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  317. %
  318. %  Function XDisplayBackgroundImage displays an image in the root window.
  319. %
  320. %  The format of the XDisplayBackgroundImage routine is:
  321. %
  322. %      XDisplayBackgroundImage(display,resource_info,window_id,image)
  323. %
  324. %  A description of each parameter follows:
  325. %
  326. %    o display: Specifies a connection to an X server;  returned from
  327. %      XOpenDisplay.
  328. %
  329. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  330. %
  331. %    o window_id: Specifies a pointer to a string with a window id or name.
  332. %
  333. %    o image: Specifies a pointer to a Image structure; returned from
  334. %      ReadImage.
  335. %
  336. %
  337. */
  338. static void XDisplayBackgroundImage(display,resource_info,window_id,image)
  339. Display
  340. X  *display;
  341. X
  342. XXResourceInfo
  343. X  *resource_info;
  344. X
  345. char
  346. X  *window_id;
  347. X
  348. Image
  349. X  *image;
  350. {
  351. X  Atom
  352. X    property,
  353. X    type;
  354. X
  355. X  Cursor
  356. X    arrow_cursor,
  357. X    watch_cursor;
  358. X
  359. X  int
  360. X    format;
  361. X
  362. X  Pixmap
  363. X    pixmap;
  364. X
  365. X  unsigned char
  366. X    *data;
  367. X
  368. X  unsigned int
  369. X    height,
  370. X    status,
  371. X    width;
  372. X
  373. X  unsigned long
  374. X    after,
  375. X    length;
  376. X
  377. X  Window
  378. X    root_window,
  379. X    target_window;
  380. X
  381. X  XGCValues
  382. X    graphic_context_value;
  383. X
  384. X  XPixelInfo
  385. X    pixel_info;
  386. X
  387. X  XStandardColormap
  388. X    *map_info;
  389. X
  390. X  XWindowInfo
  391. X    window_info;
  392. X
  393. X  XVisualInfo
  394. X    *visual_info;
  395. X
  396. X  /*
  397. X    Allocate standard colormap.
  398. X  */
  399. X  map_info=XAllocStandardColormap();
  400. X  if (map_info == (XStandardColormap *) NULL)
  401. X    Error("unable to create standard colormap","memory allocation failed");
  402. X  map_info->colormap=(Colormap) NULL;
  403. X  pixel_info.pixels=(unsigned long *) NULL;
  404. X  /*
  405. X    Initialize visual info.
  406. X  */
  407. X  if ((resource_info->visual_type != (char *) NULL) ||
  408. X      (resource_info->map_type != (char *) NULL))
  409. X    visual_info=XBestVisualInfo(display,resource_info->visual_type,
  410. X      resource_info->map_type,map_info);
  411. X  else
  412. X    {
  413. X      int
  414. X        number_visuals;
  415. X
  416. X      XVisualInfo
  417. X        visual_template;
  418. X
  419. X      /*
  420. X        Get the default visual.
  421. X      */
  422. X      visual_template.visualid=
  423. X        XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
  424. X      visual_info=XGetVisualInfo(display,VisualIDMask,&visual_template,
  425. X        &number_visuals);
  426. X    }
  427. X  if (visual_info == (XVisualInfo *) NULL)
  428. X    Error("unable to get visual",resource_info->visual_type);
  429. X  if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  430. X    Error("visual must be server default",resource_info->visual_type);
  431. X  /*
  432. X    If there are previous resources on the root window, destroy them.
  433. X  */
  434. X  root_window=XRootWindow(display,visual_info->screen);
  435. X  property=XInternAtom(display,"_XSETROOT_ID",False);
  436. X  if (property == (Atom) NULL)
  437. X    Error("unable to create X property","_XSETROOT_ID");
  438. X  (void) XGetWindowProperty(display,root_window,property,0L,1L,True,
  439. X    (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
  440. X  if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
  441. X    {
  442. X      /*
  443. X        Free previous resources on the root window.
  444. X      */
  445. X      XKillClient(display,*((Pixmap *) data));
  446. X      XFree((void *) data);
  447. X    }
  448. X  /*
  449. X    Initialize colormap.
  450. X  */
  451. X  XMakeStandardColormap(display,visual_info,resource_info,&pixel_info,image,
  452. X    map_info);
  453. X  if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  454. X    Error("unable to display X image on the root window","too many colors");
  455. X  /*
  456. X    Determine target window.
  457. X  */
  458. X  target_window=(Window) NULL;
  459. X  if (Latin1Compare(window_id,"root") == 0)
  460. X    target_window=root_window;
  461. X  else
  462. X    {
  463. X      if (isdigit(*window_id))
  464. X        target_window=XWindowByID(display,root_window,
  465. X          (Window) strtol(window_id,(char **) NULL,0));
  466. X      if (target_window == (Window) NULL)
  467. X        target_window=XWindowByName(display,root_window,window_id);
  468. X      if (target_window == (Window) NULL)
  469. X        Error("No window with specified id exists",window_id);
  470. X    }
  471. X  /*
  472. X    Initialize cursor.
  473. X  */
  474. X  arrow_cursor=XCreateFontCursor(display,XC_arrow);
  475. X  watch_cursor=XCreateFontCursor(display,XC_watch);
  476. X  if ((arrow_cursor == (Cursor) NULL) || (watch_cursor == (Cursor) NULL))
  477. X    Error("unable to create cursor",(char *) NULL);
  478. X  XRecolorCursor(display,arrow_cursor,&pixel_info.background_color,
  479. X    &pixel_info.foreground_color);
  480. X  XRecolorCursor(display,watch_cursor,&pixel_info.background_color,
  481. X    &pixel_info.foreground_color);
  482. X  /*
  483. X    Initialize image window attributes.
  484. X  */
  485. X  window_info.id=target_window;
  486. X  window_info.visual_info=visual_info;
  487. X  window_info.screen=visual_info->screen;
  488. X  window_info.depth=visual_info->depth;
  489. X  window_info.clip_geometry=(char *) NULL;
  490. X  window_info.map_info=map_info;
  491. X  window_info.pixel_info=(&pixel_info);
  492. X  window_info.cursor=arrow_cursor;
  493. X  window_info.busy_cursor=watch_cursor;
  494. X  window_info.x=0;
  495. X  window_info.y=0;
  496. X  window_info.width=image->columns;
  497. X  if (window_info.width > XDisplayWidth(display,visual_info->screen))
  498. X    window_info.width=XDisplayWidth(display,visual_info->screen);
  499. X  window_info.height=image->rows;
  500. X  if (window_info.height > XDisplayHeight(display,visual_info->screen))
  501. X    window_info.height=XDisplayHeight(display,visual_info->screen);
  502. X  window_info.border_width=resource_info->border_width;
  503. X  window_info.ximage=(XImage *) NULL;
  504. X  window_info.pixmap=(Pixmap) NULL;
  505. X  /*
  506. X    Graphic context superclass.
  507. X  */
  508. X  graphic_context_value.background=pixel_info.background_color.pixel;
  509. X  graphic_context_value.foreground=pixel_info.foreground_color.pixel;
  510. X  graphic_context_value.fill_style=FillSolid;
  511. X  graphic_context_value.function=GXcopy;
  512. X  graphic_context_value.plane_mask=AllPlanes;
  513. X  window_info.graphic_context=XCreateGC(display,window_info.id,
  514. X    GCBackground | GCFillStyle | GCForeground | GCFunction | GCPlaneMask,
  515. X    &graphic_context_value);
  516. X  if (window_info.graphic_context == (GC) NULL)
  517. X    Error("unable to create graphic context",(char *) NULL);
  518. X  graphic_context_value.background=pixel_info.foreground_color.pixel;
  519. X  graphic_context_value.foreground=pixel_info.background_color.pixel;
  520. X  window_info.highlight_context=XCreateGC(display,window_info.id,
  521. X    GCBackground | GCForeground | GCFunction | GCPlaneMask,
  522. X    &graphic_context_value);
  523. X  if (window_info.highlight_context == (GC) NULL)
  524. X    Error("unable to create graphic context",(char *) NULL);
  525. X  /*
  526. X    Create the X image.
  527. X  */
  528. X  status=XMakeImage(display,resource_info,&window_info,image,image->columns,
  529. X    image->rows);
  530. X  if (status == False)
  531. X    Error("unable to create X image",(char *) NULL);
  532. X  /*
  533. X    Adjust image dimensions as specified by backdrop or geometry options.
  534. X  */
  535. X  width=window_info.width;
  536. X  height=window_info.height;
  537. X  if (resource_info->backdrop)
  538. X    {
  539. X      /*
  540. X        Center image on root window.
  541. X      */
  542. X      window_info.x=
  543. X        XDisplayWidth(display,visual_info->screen)/2-image->columns/2;
  544. X      window_info.y=
  545. X        XDisplayHeight(display,visual_info->screen)/2-image->rows/2;
  546. X      width=XDisplayWidth(display,visual_info->screen);
  547. X      height=XDisplayHeight(display,visual_info->screen);
  548. X    }
  549. X  if (resource_info->image_geometry != (char *) NULL)
  550. X    {
  551. X      char
  552. X        default_geometry[2048];
  553. X
  554. X      int
  555. X        flags,
  556. X        gravity;
  557. X
  558. X      XSizeHints
  559. X        *size_hints;
  560. X
  561. X      /*
  562. X        User specified geometry.
  563. X      */
  564. X      size_hints=XAllocSizeHints();
  565. X      if (size_hints == (XSizeHints *) NULL)
  566. X        Error("unable to display on root","memory allocation failed");
  567. X      size_hints->flags=(long int) NULL;
  568. X      (void) sprintf(default_geometry,"%ux%u\0",width,height);
  569. X      flags=XWMGeometry(display,visual_info->screen,
  570. X        resource_info->image_geometry,default_geometry,
  571. X        window_info.border_width,size_hints,&window_info.x,&window_info.y,
  572. X        (int *) &width,(int *) &height,&gravity);
  573. X      if (flags & (XValue | YValue))
  574. X        {
  575. X          width=XDisplayWidth(display,visual_info->screen);
  576. X          height=XDisplayHeight(display,visual_info->screen);
  577. X        }
  578. X      XFree((void *) size_hints);
  579. X    }
  580. X  /*
  581. X    Create the root pixmap.
  582. X  */
  583. X  pixmap=XCreatePixmap(display,window_info.id,width,height,window_info.depth);
  584. X  if (pixmap == (Pixmap) NULL)
  585. X    Error("unable to create X pixmap",(char *) NULL);
  586. X  /*
  587. X    Display pixmap on the root window.
  588. X  */
  589. X  if ((width > window_info.width) || (height > window_info.height))
  590. X    XFillRectangle(display,pixmap,window_info.highlight_context,0,0,width,
  591. X      height);
  592. X  XPutImage(display,pixmap,window_info.graphic_context,window_info.ximage,
  593. X    0,0,window_info.x,window_info.y,window_info.width,window_info.height);
  594. X  XSetWindowBackgroundPixmap(display,window_info.id,pixmap);
  595. X  XClearWindow(display,window_info.id);
  596. X  /*
  597. X    Free resources.
  598. X  */
  599. X  XFreePixmap(display,pixmap);
  600. X  XDestroyImage(window_info.ximage);
  601. X  XFreeGC(display,window_info.graphic_context);
  602. X  XFreeGC(display,window_info.highlight_context);
  603. X  XFreeCursor(display,arrow_cursor);
  604. X  XFreeCursor(display,watch_cursor);
  605. X  XFree((void *) visual_info);
  606. X  XFree((void *) map_info);
  607. X  if (pixel_info.pixels != (unsigned long *) NULL)
  608. X    (void) free((char *) pixel_info.pixels);
  609. X  /*
  610. X    Put property on root window and set close-down mode to RetainPermanent.
  611. X  */
  612. X  pixmap=XCreatePixmap(display,root_window,1,1,1);
  613. X  if (pixmap == (Pixmap) NULL)
  614. X    Error("unable to create X pixmap",(char *) NULL);
  615. X  XChangeProperty(display,root_window,property,XA_PIXMAP,32,PropModeReplace,
  616. X    (unsigned char *) &pixmap,1);
  617. X  XSetCloseDownMode(display,RetainPermanent);
  618. }
  619. X
  620. /*
  621. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  622. %                                                                             %
  623. %                                                                             %
  624. %                                                                             %
  625. %   X D i s p l a y I m a g e                                                 %
  626. %                                                                             %
  627. %                                                                             %
  628. %                                                                             %
  629. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  630. %
  631. %  Function XDisplayImage displays an image via X11.  A new image is created
  632. %  and returned if the user interactively transforms the displayed image.
  633. %
  634. %  The format of the XDisplayImage routine is:
  635. %
  636. %      tile_image=XDisplayImage(display,resource_info,argv,argc,image,state)
  637. %
  638. %  A description of each parameter follows:
  639. %
  640. %    o tile_image:  If the image to display is a composite image and the
  641. %      user selects a particular tile to display, XDisplayImage returns
  642. %      the selected tile.
  643. %
  644. %    o display: Specifies a connection to an X server;  returned from
  645. %      XOpenDisplay.
  646. %
  647. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  648. %
  649. %    o argv: Specifies the application's argument list.
  650. %
  651. %    o argc: Specifies the number of arguments.
  652. %
  653. %    o image: Specifies an address to an address of an Image structure;
  654. %      returned from ReadImage.
  655. %
  656. %
  657. */
  658. static Image *XDisplayImage(display,resource_info,argv,argc,image,state)
  659. Display
  660. X  *display;
  661. X
  662. XXResourceInfo
  663. X  *resource_info;
  664. X
  665. char
  666. X  **argv;
  667. X
  668. int
  669. X  argc;
  670. X
  671. Image
  672. X  **image;
  673. X
  674. unsigned long int
  675. X  *state;
  676. {
  677. #define MagnifySize  256  /* must be a power of 2 */
  678. #define MaxWindows  9
  679. X
  680. X  char
  681. X    command[2048],
  682. X    text[2048];
  683. X
  684. X  GC
  685. X    graphic_context;
  686. X
  687. X  Image
  688. X    *displayed_image,
  689. X    *tile_image;
  690. X
  691. X  KeySym
  692. X    key_symbol;
  693. X
  694. X  register int
  695. X    i;
  696. X
  697. X  static Atom
  698. X    delete_property,
  699. X    protocols_property;
  700. X
  701. X  static Cursor
  702. X    arrow_cursor,
  703. X    watch_cursor;
  704. X
  705. X  static XClassHint
  706. X    *class_hint;
  707. X
  708. X  static XPixelInfo
  709. X    pixel_info;
  710. X
  711. X  static XStandardColormap
  712. X    *map_info;
  713. X
  714. X  static XVisualInfo
  715. X    *visual_info = (XVisualInfo *) NULL;
  716. X
  717. X  static XWindowInfo
  718. X    *magick_windows[MaxWindows];
  719. X
  720. X  static XWindows
  721. X    *window;
  722. X
  723. X  static XWMHints
  724. X    *manager_hints;
  725. X
  726. X  static unsigned int
  727. X    number_windows;
  728. X
  729. X  unsigned int
  730. X    status;
  731. X
  732. X  unsigned long
  733. X    timeout;
  734. X
  735. X  Window
  736. X    root_window;
  737. X
  738. X  XEvent
  739. X    event;
  740. X
  741. X  XFontStruct
  742. X    *font_info;
  743. X
  744. X  XGCValues
  745. X    graphic_context_value;
  746. X
  747. X  XWindowInfo
  748. X    previous_window;
  749. X
  750. X  if (visual_info == (XVisualInfo *) NULL)
  751. X    {
  752. X      /*
  753. X        Allocate standard colormap.
  754. X      */
  755. X      if (resource_info->debug)
  756. X        XSynchronize(display,True);
  757. X      map_info=XAllocStandardColormap();
  758. X      if (map_info == (XStandardColormap *) NULL)
  759. X        Error("unable to create standard colormap","memory allocation failed");
  760. X      map_info->colormap=(Colormap) NULL;
  761. X      pixel_info.pixels=(unsigned long *) NULL;
  762. X      /*
  763. X        Allocate visual.
  764. X      */
  765. X      visual_info=XBestVisualInfo(display,resource_info->visual_type,
  766. X        resource_info->map_type,map_info);
  767. X      if (visual_info == (XVisualInfo *) NULL)
  768. X        Error("unable to get visual",resource_info->visual_type);
  769. X      if (resource_info->debug)
  770. X        {
  771. X          (void) fprintf(stderr,"Visual:\n");
  772. X          (void) fprintf(stderr,"  visual id: 0x%lx\n",visual_info->visualid);
  773. X          (void) fprintf(stderr,"  class: %s\n",XVisualClassName(visual_info));
  774. X          (void) fprintf(stderr,"  depth: %d planes\n",visual_info->depth);
  775. X          (void) fprintf(stderr,"  size of colormap: %d entries\n",
  776. X            visual_info->colormap_size);
  777. X          (void) fprintf(stderr,"  red, green, blue masks: 0x%lx 0x%lx 0x%lx\n",
  778. X            visual_info->red_mask,visual_info->green_mask,
  779. X            visual_info->blue_mask);
  780. X          (void) fprintf(stderr,"  significant bits in color: %d bits\n",
  781. X            visual_info->bits_per_rgb);
  782. X        }
  783. X      /*
  784. X        Allocate cursors.
  785. X      */
  786. X      arrow_cursor=XCreateFontCursor(display,XC_arrow);
  787. X      watch_cursor=XCreateFontCursor(display,XC_watch);
  788. X      if ((arrow_cursor == (Cursor) NULL) || (watch_cursor == (Cursor) NULL))
  789. X        Error("unable to create cursor",(char *) NULL);
  790. X      /*
  791. X        Allocate atoms.
  792. X      */
  793. X      protocols_property=XInternAtom(display,"WM_PROTOCOLS",False);
  794. X      delete_property=XInternAtom(display,"WM_DELETE_WINDOW",False);
  795. X      if ((protocols_property == (Atom) NULL) ||
  796. X          (delete_property == (Atom) NULL))
  797. X        Error("unable to create property",(char *) NULL);
  798. X      /*
  799. X        Allocate class and manager hints.
  800. X      */
  801. X      class_hint=XAllocClassHint();
  802. X      manager_hints=XAllocWMHints();
  803. X      if ((class_hint == (XClassHint *) NULL) ||
  804. X          (manager_hints == (XWMHints *) NULL))
  805. X        Error("unable to allocate X hints",(char *) NULL);
  806. X      /*
  807. X        Initialize window id's.
  808. X      */
  809. X      window=(XWindows *) malloc(sizeof(XWindows));
  810. X      if (window == (XWindows *) NULL)
  811. X        Error("unable to create X windows","memory allocation failed");
  812. X      number_windows=0;
  813. X      magick_windows[number_windows++]=(&window->backdrop);
  814. X      magick_windows[number_windows++]=(&window->icon);
  815. X      magick_windows[number_windows++]=(&window->image);
  816. X      magick_windows[number_windows++]=(&window->info);
  817. X      magick_windows[number_windows++]=(&window->magnify);
  818. X      magick_windows[number_windows++]=(&window->pan);
  819. X      magick_windows[number_windows++]=(&window->popup);
  820. X      for (i=0; i < number_windows; i++)
  821. X        magick_windows[i]->id=(Window) NULL;
  822. X    }
  823. X  /*
  824. X    Initialize Standard Colormap.
  825. X  */
  826. X  displayed_image=(*image);
  827. X  if (resource_info->debug)
  828. X    {
  829. X      (void) fprintf(stderr,"Image: [%u] %s %ux%u ",displayed_image->scene,
  830. X        displayed_image->filename,displayed_image->columns,
  831. X        displayed_image->rows);
  832. X      if (displayed_image->colors > 0)
  833. X        (void) fprintf(stderr,"%uc ",displayed_image->colors);
  834. X      (void) fprintf(stderr,"%s\n",displayed_image->magick);
  835. X    }
  836. X  XMakeStandardColormap(display,visual_info,resource_info,&pixel_info,
  837. X    displayed_image,map_info);
  838. X  /*
  839. X    Color cursor.
  840. X  */
  841. X  XRecolorCursor(display,arrow_cursor,&pixel_info.background_color,
  842. X    &pixel_info.foreground_color);
  843. X  XRecolorCursor(display,watch_cursor,&pixel_info.background_color,
  844. X    &pixel_info.foreground_color);
  845. X  /*
  846. X    Initialize font info.
  847. X  */
  848. X  (void) sprintf(text," [%u] %s %ux%u %s \0",displayed_image->scene,
  849. X    displayed_image->filename,displayed_image->columns,displayed_image->rows,
  850. X    XVisualClassName(visual_info));
  851. X  if (displayed_image->colors > 0)
  852. X    (void) sprintf(text,"%s%uc \0",text,displayed_image->colors);
  853. X  font_info=XBestFont(display,resource_info,text,displayed_image->columns);
  854. X  if (font_info == (XFontStruct *) NULL)
  855. X    Error("unable to load font",resource_info->font);
  856. X  /*
  857. X    Initialize class and manager hints.
  858. X  */
  859. X  if (resource_info->name == (char *) NULL)
  860. X    class_hint->res_name=application_name;
  861. X  else
  862. X    class_hint->res_name=resource_info->name;
  863. X  class_hint->res_class=(char *) "ImageMagick";
  864. X  manager_hints->flags=InputHint | StateHint;
  865. X  manager_hints->input=False;
  866. X  manager_hints->initial_state=NormalState;
  867. X  /*
  868. X    Window superclass.
  869. X  */
  870. X  window->superclass.id=(Window) NULL;
  871. X  window->superclass.screen=visual_info->screen;
  872. X  window->superclass.depth=visual_info->depth;
  873. X  window->superclass.visual_info=visual_info;
  874. X  window->superclass.map_info=map_info;
  875. X  window->superclass.pixel_info=(&pixel_info);
  876. X  window->superclass.font_info=font_info;
  877. X  window->superclass.cursor=arrow_cursor;
  878. X  window->superclass.busy_cursor=watch_cursor;
  879. X  window->superclass.graphic_context=(GC) NULL;
  880. X  window->superclass.name=(char *) NULL;
  881. X  window->superclass.geometry=(char *) NULL;
  882. X  window->superclass.icon_name=(char *) NULL;
  883. X  window->superclass.icon_geometry=resource_info->icon_geometry;
  884. X  window->superclass.clip_geometry=(char *) NULL;
  885. X  window->superclass.flags=PSize;
  886. X  window->superclass.x=0;
  887. X  window->superclass.y=0;
  888. X  window->superclass.width=1;
  889. X  window->superclass.height=1;
  890. X  window->superclass.min_width=1;
  891. X  window->superclass.min_height=1;
  892. X  window->superclass.width_inc=1;
  893. X  window->superclass.height_inc=1;
  894. X  window->superclass.border_width=2;
  895. X  window->superclass.immutable=True;
  896. X  window->superclass.ximage=(XImage *) NULL;
  897. X  window->superclass.pixmap=(Pixmap) NULL;
  898. X  window->superclass.attributes.background_pixel=
  899. X    pixel_info.background_color.pixel;
  900. X  window->superclass.attributes.background_pixmap=(Pixmap) NULL;
  901. X  window->superclass.attributes.backing_store=WhenMapped;
  902. X  window->superclass.attributes.bit_gravity=ForgetGravity;
  903. X  window->superclass.attributes.border_pixel=pixel_info.border_color.pixel;
  904. X  window->superclass.attributes.colormap=map_info->colormap;
  905. X  window->superclass.attributes.cursor=arrow_cursor;
  906. X  window->superclass.attributes.do_not_propagate_mask=NoEventMask;
  907. X  window->superclass.attributes.event_mask=NoEventMask;
  908. X  window->superclass.attributes.override_redirect=False;
  909. X  window->superclass.attributes.save_under=True;
  910. X  window->superclass.attributes.win_gravity=NorthWestGravity;
  911. X  root_window=XRootWindow(display,visual_info->screen);
  912. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  913. X    delete_property,&window->superclass);
  914. X  if (resource_info->debug)
  915. X    (void) fprintf(stderr,"Window id: 0x%lx (superclass)\n",
  916. X      window->superclass.id);
  917. X  /*
  918. X    Initialize graphic context.
  919. X  */
  920. X  graphic_context_value.background=pixel_info.background_color.pixel;
  921. X  graphic_context_value.foreground=pixel_info.foreground_color.pixel;
  922. X  graphic_context_value.font=font_info->fid;
  923. X  graphic_context_value.function=GXcopy;
  924. X  graphic_context_value.line_width=2;
  925. X  graphic_context_value.plane_mask=AllPlanes;
  926. X  graphic_context=XCreateGC(display,window->superclass.id,GCBackground |
  927. X    GCFont | GCForeground | GCFunction | GCLineWidth | GCPlaneMask,
  928. X    &graphic_context_value);
  929. X  if (graphic_context == (GC) NULL)
  930. X    Error("unable to create graphic context",(char *) NULL);
  931. X  window->superclass.graphic_context=graphic_context;
  932. X  graphic_context_value.background=pixel_info.foreground_color.pixel;
  933. X  graphic_context_value.foreground=pixel_info.background_color.pixel;
  934. X  graphic_context=XCreateGC(display,window->superclass.id,GCBackground |
  935. X    GCFont | GCForeground | GCFunction | GCLineWidth | GCPlaneMask,
  936. X    &graphic_context_value);
  937. X  if (graphic_context == (GC) NULL)
  938. X    Error("unable to create graphic context",(char *) NULL);
  939. X  window->superclass.highlight_context=graphic_context;
  940. X  XDestroyWindow(display,window->superclass.id);
  941. X  window->superclass.id=(Window) NULL;
  942. X  /*
  943. X    Initialize icon window.
  944. X  */
  945. X  XGetWindowInfo(&window->superclass,&window->icon);
  946. X  XBestIconSize(display,&window->icon,displayed_image);
  947. X  window->icon.attributes.event_mask=StructureNotifyMask;
  948. X  manager_hints->flags=InputHint | StateHint;
  949. X  manager_hints->input=False;
  950. X  manager_hints->initial_state=IconicState;
  951. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  952. X    delete_property,&window->icon);
  953. X  if (resource_info->debug)
  954. X    (void) fprintf(stderr,"Window id: 0x%lx (icon)\n",window->icon.id);
  955. X  /*
  956. X    Initialize image window.
  957. X  */
  958. X  previous_window=window->image;
  959. X  XGetWindowInfo(&window->superclass,&window->image);
  960. X  window->image.name=(char *) malloc(2048*sizeof(char));
  961. X  window->image.icon_name=(char *) malloc(2048*sizeof(char));
  962. X  if ((window->image.name == NULL) || (window->image.icon_name == NULL))
  963. X    Error("unable to create image window","memory allocation failed");
  964. X  if (resource_info->title != (char *) NULL)
  965. X    {
  966. X      (void) strcpy(window->image.name,resource_info->title);
  967. X      (void) strcpy(window->image.icon_name,resource_info->title);
  968. X    }
  969. X  else
  970. X    {
  971. X      char
  972. X        *icon_name;
  973. X
  974. X      (void) strcpy(window->image.name,"ImageMagick: ");
  975. X      (void) strcat(window->image.name,displayed_image->filename);
  976. X      icon_name=displayed_image->filename+strlen(displayed_image->filename)-1;
  977. X      while ((icon_name > displayed_image->filename) && (*(icon_name-1) != '/'))
  978. X        icon_name--;
  979. X      (void) strcpy(window->image.icon_name,icon_name);
  980. X    }
  981. X  window->image.geometry=resource_info->image_geometry;
  982. X  window->image.width=displayed_image->columns;
  983. X  if (window->image.width > XDisplayWidth(display,visual_info->screen))
  984. X    window->image.width=(XDisplayWidth(display,visual_info->screen)*7) >> 3;
  985. X  window->image.height=displayed_image->rows;
  986. X  if (window->image.height > XDisplayHeight(display,visual_info->screen))
  987. X    window->image.height=(XDisplayHeight(display,visual_info->screen)*7) >> 3;
  988. X  window->image.border_width=resource_info->border_width;
  989. X  XGetWindowInfo(&window->superclass,&window->backdrop);
  990. X  if (resource_info->backdrop || (window->backdrop.id != (Window) NULL))
  991. X    {
  992. X      unsigned int
  993. X        height,
  994. X        width;
  995. X
  996. X      /*
  997. X        Initialize backdrop window.
  998. X      */
  999. X      window->backdrop.cursor=XMakeInvisibleCursor(display,root_window);
  1000. X      if (window->backdrop.cursor == (Cursor) NULL)
  1001. X        Error("unable to create cursor",(char *) NULL);
  1002. X      window->backdrop.name="ImageMagick Backdrop";
  1003. X      window->backdrop.flags=USSize | USPosition;
  1004. X      window->backdrop.width=XDisplayWidth(display,visual_info->screen);
  1005. X      window->backdrop.height=XDisplayHeight(display,visual_info->screen);
  1006. X      window->backdrop.border_width=0;
  1007. X      window->backdrop.attributes.cursor=window->backdrop.cursor;
  1008. X      window->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
  1009. X        ButtonReleaseMask;
  1010. X      window->backdrop.attributes.event_mask=KeyPressMask | KeyReleaseMask;
  1011. X      window->backdrop.attributes.override_redirect=True;
  1012. X      manager_hints->flags=IconWindowHint | InputHint | StateHint;
  1013. X      manager_hints->icon_window=window->icon.id;
  1014. X      manager_hints->input=True;
  1015. X      manager_hints->initial_state=
  1016. X        resource_info->iconic ? IconicState : NormalState;
  1017. X      XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1018. X        delete_property,&window->backdrop);
  1019. X      if (resource_info->debug)
  1020. X        (void) fprintf(stderr,"Window id: 0x%lx (backdrop)\n",
  1021. X          window->backdrop.id);
  1022. X      XMapWindow(display,window->backdrop.id);
  1023. X      XInstallColormap(display,map_info->colormap);
  1024. X      XSetInputFocus(display,window->backdrop.id,RevertToNone,CurrentTime);
  1025. X      XClearWindow(display,window->backdrop.id);
  1026. X      /*
  1027. X        Position image in the center the backdrop.
  1028. X      */
  1029. X      window->image.flags|=USPosition;
  1030. X      window->image.x=0;
  1031. X      width=displayed_image->columns+window->image.border_width;
  1032. X      if (width < XDisplayWidth(display,visual_info->screen))
  1033. X        window->image.x=XDisplayWidth(display,visual_info->screen)/2-width/2;
  1034. X      window->image.y=0;
  1035. X      height=displayed_image->rows+window->image.border_width;
  1036. X      if (height < XDisplayHeight(display,visual_info->screen))
  1037. X        window->image.y=XDisplayHeight(display,visual_info->screen)/2-height/2;
  1038. X      if (window->backdrop.id != (Window) NULL)
  1039. X        {
  1040. X          XDestroyWindow(display,window->image.id);
  1041. X          window->image.id=(Window) NULL;
  1042. X        }
  1043. X    }
  1044. X  window->image.immutable=False;
  1045. X  window->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  1046. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
  1047. X    KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
  1048. X    StructureNotifyMask;
  1049. X  manager_hints->flags=IconWindowHint | InputHint | StateHint;
  1050. X  manager_hints->icon_window=window->icon.id;
  1051. X  manager_hints->input=True;
  1052. X  manager_hints->initial_state=
  1053. X    resource_info->iconic ? IconicState : NormalState;
  1054. X  XMakeWindow(display,
  1055. X    (resource_info->backdrop ? window->backdrop.id : root_window),argv,argc,
  1056. X    class_hint,manager_hints,delete_property,&window->image);
  1057. X  if (resource_info->debug)
  1058. X    (void) fprintf(stderr,"Window id: 0x%lx (image)\n",window->image.id);
  1059. X  *state|=ReconfigureImageState;
  1060. X  window->image.x=0;
  1061. X  window->image.y=0;
  1062. X  /*
  1063. X    Initialize X image structure.
  1064. X  */
  1065. X  status=XMakeImage(display,resource_info,&window->image,displayed_image,
  1066. X    displayed_image->columns,displayed_image->rows);
  1067. X  (void) XMakePixmap(display,resource_info,&window->image);
  1068. X  if (status == False)
  1069. X    Error("unable to create X image",(char *) NULL);
  1070. X  XMapWindow(display,window->image.id);
  1071. X  /*
  1072. X    Initialize magnify window and cursor.
  1073. X  */
  1074. X  XGetWindowInfo(&window->superclass,&window->magnify);
  1075. X  window->magnify.name=(char *) malloc(2048*sizeof(char));
  1076. X  if (window->magnify.name == NULL)
  1077. X    Error("unable to create magnify window","memory allocation failed");
  1078. X  (void) sprintf(window->magnify.name,"Magnify %uX",resource_info->magnify);
  1079. X  window->magnify.cursor=XMakeCursor(display,window->image.id,
  1080. X    map_info->colormap,resource_info->background_color,
  1081. X    resource_info->foreground_color);
  1082. X  if (window->magnify.cursor == (Cursor) NULL)
  1083. X    Error("unable to create cursor",(char *) NULL);
  1084. X  XRecolorCursor(display,window->magnify.cursor,&pixel_info.background_color,
  1085. X    &pixel_info.foreground_color);
  1086. X  window->magnify.width=MagnifySize;
  1087. X  window->magnify.height=MagnifySize;
  1088. X  window->magnify.min_width=MagnifySize;
  1089. X  window->magnify.min_height=MagnifySize;
  1090. X  window->magnify.width_inc=MagnifySize;
  1091. X  window->magnify.height_inc=MagnifySize;
  1092. X  window->magnify.immutable=False;
  1093. X  window->magnify.attributes.cursor=window->magnify.cursor;
  1094. X  window->magnify.attributes.event_mask=ExposureMask | KeyPressMask |
  1095. X    StructureNotifyMask;
  1096. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1097. X  manager_hints->input=False;
  1098. X  manager_hints->initial_state=NormalState;
  1099. X  manager_hints->window_group=window->image.id;
  1100. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1101. X    delete_property,&window->magnify);
  1102. X  if (resource_info->debug)
  1103. X    (void) fprintf(stderr,"Window id: 0x%lx (magnify)\n",window->magnify.id);
  1104. X  /*
  1105. X    Initialize panning window.
  1106. X  */
  1107. X  XGetWindowInfo(&window->superclass,&window->pan);
  1108. X  window->pan.name="Pan Icon";
  1109. X  XBestIconSize(display,&window->pan,displayed_image);
  1110. X  window->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  1111. X    ButtonReleaseMask | StructureNotifyMask | VisibilityChangeMask;
  1112. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1113. X  manager_hints->input=False;
  1114. X  manager_hints->initial_state=NormalState;
  1115. X  manager_hints->window_group=window->image.id;
  1116. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1117. X    delete_property,&window->pan);
  1118. X  if (resource_info->debug)
  1119. X    (void) fprintf(stderr,"Window id: 0x%lx (pan)\n",window->pan.id);
  1120. X  /*
  1121. X    Initialize popup window.
  1122. X  */
  1123. X  XGetWindowInfo(&window->superclass,&window->popup);
  1124. X  window->popup.name="ImageMagick Popup";
  1125. X  window->popup.flags=PSize | PPosition;
  1126. X  window->popup.attributes.override_redirect=True;
  1127. X  window->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  1128. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
  1129. X    OwnerGrabButtonMask | VisibilityChangeMask;
  1130. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1131. X  manager_hints->input=True;
  1132. X  manager_hints->initial_state=NormalState;
  1133. X  manager_hints->window_group=window->image.id;
  1134. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  1135. X    delete_property,&window->popup);
  1136. X  if (resource_info->debug)
  1137. X    (void) fprintf(stderr,"Window id: 0x%lx (pop up)\n",window->popup.id);
  1138. X  XSetTransientForHint(display,window->popup.id,window->image.id);
  1139. X  /*
  1140. X    Initialize info window.
  1141. X  */
  1142. X  XGetWindowInfo(&window->superclass,&window->info);
  1143. X  window->info.name="ImageMagick Info";
  1144. X  window->info.flags=PSize | PPosition;
  1145. X  window->info.x=2;
  1146. X  window->info.y=2;
  1147. X  window->info.attributes.event_mask=StructureNotifyMask;
  1148. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  1149. X  manager_hints->input=False;
  1150. X  manager_hints->initial_state=NormalState;
  1151. X  manager_hints->window_group=window->image.id;
  1152. X  XMakeWindow(display,window->image.id,argv,argc,class_hint,manager_hints,
  1153. X    delete_property,&window->info);
  1154. X  if (resource_info->debug)
  1155. X    (void) fprintf(stderr,"Window id: 0x%lx (info)\n",window->info.id);
  1156. X  if (*state & ImageMappedState)
  1157. X    {
  1158. X      /*
  1159. X        Image window is already mapped-- refresh window, map pan window.
  1160. X      */
  1161. X      if ((window->image.width == previous_window.width) &&
  1162. X          (window->image.height == previous_window.height))
  1163. X        {
  1164. X          XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1165. X          *state&=(~ReconfigureImageState);
  1166. X        }
  1167. X      if ((window->image.width < window->image.ximage->width) ||
  1168. X          (window->image.height < window->image.ximage->height))
  1169. X        XMapRaised(display,window->pan.id);
  1170. X    }
  1171. X  /*
  1172. X    Respond to events.
  1173. X  */
  1174. X  *state&=(~LastImageState);
  1175. X  *state&=(~NextImageState);
  1176. X  *state&=(~TileImageState);
  1177. X  if (resource_info->delay == 0)
  1178. X    timeout=(~0);
  1179. X  else
  1180. X    timeout=(unsigned long) time((time_t *) 0)+resource_info->delay;
  1181. X  do
  1182. X  {
  1183. X    /*
  1184. X      Handle a window event.
  1185. X    */
  1186. X    if (resource_info->delay > 0)
  1187. X      if (XEventsQueued(display,QueuedAfterFlush) == 0)
  1188. X        {
  1189. X          /*
  1190. X            Block if delay > 0.
  1191. X          */
  1192. X          (void) sleep(1);
  1193. X          continue;
  1194. X        }
  1195. X    XNextEvent(display,&event);
  1196. X    switch (event.type)
  1197. X    {
  1198. X      case ButtonPress:
  1199. X      {
  1200. X        if ((event.xbutton.button == Button3) &&
  1201. X            (event.xbutton.state & Mod1Mask))
  1202. X          {
  1203. X            /* 
  1204. X              Convert Alt-Button3 to Button2.
  1205. X            */
  1206. X            event.xbutton.button=Button2;
  1207. X            event.xbutton.state&=(~Mod1Mask);
  1208. X          }
  1209. X        if (event.xbutton.window == window->image.id)
  1210. X          switch (event.xbutton.button)
  1211. X          {
  1212. X            case Button1:
  1213. X            {
  1214. X              static char
  1215. X                *MenuCommand="ir/\\<>oacwpnlq",
  1216. X                *MenuSelections[]=
  1217. X                {
  1218. X                  "Image Info",
  1219. X                  "Reflect",
  1220. X                  "Rotate Right",
  1221. X                  "Rotate Left",
  1222. X                  "Half Size",
  1223. X                  "Double Size",
  1224. X                  "Restore",
  1225. X                  "Annotate",
  1226. X                  "Composite",
  1227. X                  "Write",
  1228. X                  "Print",
  1229. X                  "Next",
  1230. X                  "Last",
  1231. X                  "Quit"
  1232. X                };
  1233. X
  1234. X              static int
  1235. X                command_number;
  1236. X
  1237. X              /*
  1238. X                Select a command from the pop-up menu.
  1239. X              */
  1240. X              command_number=XPopupMenu(display,&window->popup,
  1241. X                event.xbutton.x_root,event.xbutton.y_root,"Commands",
  1242. X                MenuSelections,sizeof(MenuSelections)/sizeof(MenuSelections[0]),
  1243. X                command);
  1244. X              if (*command != '\0')
  1245. X                UserCommand(display,resource_info,window,
  1246. X                  MenuCommand[command_number],&displayed_image,state);
  1247. X              break;
  1248. X            }
  1249. X            case Button2:
  1250. X            {
  1251. X              /*
  1252. X                User pressed the image clip button.
  1253. X              */
  1254. X              XClipImageWindow(display,resource_info,window,&event,
  1255. X                displayed_image,state);
  1256. X              break;
  1257. X            }
  1258. X            case Button3:
  1259. X            {
  1260. X              if (displayed_image->montage != (char *) NULL)
  1261. X                {
  1262. X                  /*
  1263. X                    User picked an image tile to display.
  1264. X                  */
  1265. X                  tile_image=XTileImageWindow(display,resource_info,window,
  1266. X                    displayed_image,&event);
  1267. X                  if (tile_image != (Image *) NULL)
  1268. X                    *state|=TileImageState | NextImageState | ExitState;
  1269. X                  break;
  1270. X                }
  1271. X              /*
  1272. X                User pressed the image magnify button.
  1273. X              */
  1274. X              if (*state & MagnifyMappedState)
  1275. X                XRaiseWindow(display,window->magnify.id);
  1276. X              else
  1277. X                {
  1278. X                  /*
  1279. X                    Make magnify image.
  1280. X                  */
  1281. X                  status=XMakeImage(display,resource_info,&window->magnify,
  1282. X                    (Image *) NULL,window->magnify.width,
  1283. X                    window->magnify.height);
  1284. X                  status|=XMakePixmap(display,resource_info,&window->magnify);
  1285. X                  if (status == False)
  1286. X                    Error("unable to create magnify image",(char *) NULL);
  1287. X                  XMapRaised(display,window->magnify.id);
  1288. X                }
  1289. X              XMagnifyImageWindow(display,resource_info,window,&event);
  1290. X              break;
  1291. X            }
  1292. X            default:
  1293. X              break;
  1294. X          }
  1295. X        if (event.xbutton.window == window->pan.id)
  1296. X          {
  1297. X            XPanImageWindow(display,window,&event);
  1298. X            break;
  1299. X          }
  1300. X        break;
  1301. X      }
  1302. X      case ClientMessage:
  1303. X      {
  1304. X        /*
  1305. X          If client window delete message, exit.
  1306. X        */
  1307. X        if (event.xclient.message_type == protocols_property)
  1308. X          if (*event.xclient.data.l == delete_property)
  1309. X            if (event.xclient.window == window->image.id)
  1310. X              *state|=ExitState;
  1311. X            else
  1312. X              XWithdrawWindow(display,event.xclient.window,visual_info->screen);
  1313. X        break;
  1314. X      }
  1315. X      case ConfigureNotify:
  1316. X      {
  1317. X        if (resource_info->debug)
  1318. X          (void) fprintf(stderr,"Configure Notify: 0x%lx %dx%d+%d+%d\n",
  1319. X            event.xconfigure.window,event.xconfigure.width,
  1320. X            event.xconfigure.height,event.xconfigure.x,event.xconfigure.y);
  1321. X        if (event.xconfigure.window == window->image.id)
  1322. X          {
  1323. X            /*
  1324. X              Image window has a new configuration.
  1325. X            */
  1326. X            window->image.x=0;
  1327. X            window->image.y=0;
  1328. X            if ((event.xconfigure.width != window->image.width) ||
  1329. X                (event.xconfigure.height != window->image.height))
  1330. X              {
  1331. X                window->image.width=event.xconfigure.width;
  1332. X                window->image.height=event.xconfigure.height;
  1333. X                if (!(*state & ReconfigureImageState))
  1334. X                  {
  1335. X                    status=XConfigureImageWindow(display,resource_info,window,
  1336. X                      window->image.width,window->image.height,displayed_image);
  1337. X                    if (status == False)
  1338. X                      XPopupAlert(display,&window->popup,
  1339. X                        "unable to configure image",window->image.name);
  1340. X                  }
  1341. X                *state|=UpdateConfigurationState;
  1342. X              }
  1343. X            *state&=(~ReconfigureImageState);
  1344. X            break;
  1345. X          }
  1346. X        if (event.xconfigure.window == window->magnify.id)
  1347. X          {
  1348. X            unsigned int
  1349. X              magnify;
  1350. X
  1351. X            /*
  1352. X              Magnify window has a new configuration.
  1353. X            */
  1354. X            window->magnify.width=event.xconfigure.width;
  1355. X            window->magnify.height=event.xconfigure.height;
  1356. X            if (!(*state & MagnifyMappedState))
  1357. X              break;
  1358. X            magnify=1;
  1359. X            while (magnify <= event.xconfigure.width)
  1360. X              magnify<<=1;
  1361. X            while (magnify <= event.xconfigure.height)
  1362. X              magnify<<=1;
  1363. X            magnify>>=1;
  1364. X            if ((magnify != event.xconfigure.width) ||
  1365. X                (magnify != event.xconfigure.height))
  1366. X              {
  1367. X                XResizeWindow(display,window->magnify.id,magnify,magnify);
  1368. X                break;
  1369. X              }
  1370. X            status=XMakeImage(display,resource_info,&window->magnify,
  1371. X              (Image *) NULL,window->magnify.width,window->magnify.height);
  1372. X            status|=XMakePixmap(display,resource_info,&window->magnify);
  1373. X            if (status == False)
  1374. X              Error("unable to create magnify image",(char *) NULL);
  1375. X            XMakeMagnifyImage(display,resource_info,window);
  1376. X            break;
  1377. X          }
  1378. X        if (event.xconfigure.window == window->pan.id)
  1379. X          {
  1380. X            /*
  1381. X              Pan window has a new configuration.
  1382. X            */
  1383. X            window->pan.width=event.xconfigure.width;
  1384. X            window->pan.height=event.xconfigure.height;
  1385. X            break;
  1386. X          }
  1387. X        if (event.xconfigure.window == window->icon.id)
  1388. X          {
  1389. X            /*
  1390. X              Icon window has a new configuration.
  1391. X            */
  1392. X            window->icon.width=event.xconfigure.width;
  1393. X            window->icon.height=event.xconfigure.height;
  1394. X          }
  1395. X        break;
  1396. X      }
  1397. X      case EnterNotify:
  1398. X      {
  1399. X        /*
  1400. X          Selectively install colormap.
  1401. X        */
  1402. X        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  1403. X          if (event.xcrossing.mode != NotifyUngrab)
  1404. X            XInductColormap(display,map_info->colormap);
  1405. X        if (window->backdrop.id != (Window) NULL)
  1406. X          if (event.xbutton.window == window->image.id)
  1407. X            {
  1408. X              XInstallColormap(display,map_info->colormap);
  1409. X              XSetInputFocus(display,window->image.id,RevertToNone,CurrentTime);
  1410. X              break;
  1411. X            }
  1412. X        break;
  1413. X      }
  1414. X      case Expose:
  1415. X      {
  1416. X        if (resource_info->debug)
  1417. X          (void) fprintf(stderr,"Expose: 0x%lx %dx%d+%d+%d\n",
  1418. X            event.xexpose.window,event.xexpose.width,event.xexpose.height,
  1419. X            event.xexpose.x,event.xexpose.y);
  1420. X        /*
  1421. X          Refresh windows that are now exposed.
  1422. X        */
  1423. X        if (event.xexpose.window == window->image.id)
  1424. X          if (*state & ImageMappedState)
  1425. X            {
  1426. X              XRefreshWindow(display,&window->image,&event);
  1427. X              /*
  1428. X                Reset timeout after expose.
  1429. X              */
  1430. X              if (resource_info->delay == 0)
  1431. X                timeout=(~0);
  1432. X              else
  1433. X                timeout=(unsigned long) time((time_t *) 0)+resource_info->delay;
  1434. X              break;
  1435. X            }
  1436. X        if (event.xexpose.window == window->magnify.id)
  1437. X          if (event.xexpose.count == 0)
  1438. X            if (*state & MagnifyMappedState)
  1439. X              {
  1440. X                XMakeMagnifyImage(display,resource_info,window);
  1441. X                break;
  1442. X              }
  1443. X        if (event.xexpose.window == window->pan.id)
  1444. X          if (event.xexpose.count == 0)
  1445. X            if (*state & PanIconMappedState)
  1446. X              {
  1447. X                XDrawPanRectangle(display,window);
  1448. X                break;
  1449. X              }
  1450. X        break;
  1451. X      }
  1452. X      case KeyPress:
  1453. X      {
  1454. X        /*
  1455. X          Respond to a user key press.
  1456. X        */
  1457. X        *command='\0';
  1458. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1459. X          &key_symbol,(XComposeStatus *) NULL);
  1460. X        if (key_symbol == XK_Control_L)
  1461. X          *state|=ControlState;
  1462. X        else
  1463. X          if (key_symbol == XK_Help)
  1464. X            Usage(False);
  1465. X          else
  1466. X            if (IsCursorKey(key_symbol) || isdigit(*command))
  1467. X              {
  1468. X                /*
  1469. X                  User specified a magnify factor or position.
  1470. X                */
  1471. X                if (key_symbol == XK_Home)
  1472. X                  {
  1473. X                    window->magnify.x=window->image.width >> 1;
  1474. X                    window->magnify.y=window->image.height >> 1;
  1475. X                  }
  1476. X                if (key_symbol == XK_Left)
  1477. X                  if (window->magnify.x > 0)
  1478. X                    window->magnify.x--;
  1479. X                if (key_symbol == XK_Up)
  1480. X                  if (window->magnify.y > 0)
  1481. X                    window->magnify.y--;
  1482. X                if (key_symbol == XK_Right)
  1483. X                  if (window->magnify.x < (window->image.width-1))
  1484. X                    window->magnify.x++;
  1485. X                if (key_symbol == XK_Down)
  1486. X                  if (window->magnify.y < (window->image.height-1))
  1487. X                    window->magnify.y++;
  1488. X                if (isdigit(*command))
  1489. X                  resource_info->magnify=atoi(command);
  1490. X                if (*state & MagnifyMappedState)
  1491. X                  XMakeMagnifyImage(display,resource_info,window);
  1492. X              }
  1493. X            else
  1494. X              if (event.xkey.window == window->image.id)
  1495. X                UserCommand(display,resource_info,window,*command,
  1496. X                  &displayed_image,state);
  1497. X        break;
  1498. X      }
  1499. X      case KeyRelease:
  1500. X      {
  1501. X        /*
  1502. X          Respond to a user key release.
  1503. X        */
  1504. X        *command='\0';
  1505. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1506. X          &key_symbol,(XComposeStatus *) NULL);
  1507. X        if (key_symbol == XK_Control_L)
  1508. X          *state&=(~ControlState);
  1509. X        break;
  1510. X      }
  1511. X      case LeaveNotify:
  1512. X      {
  1513. X        /*
  1514. X          Selectively uninstall colormap.
  1515. X        */
  1516. X        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  1517. X          if (event.xcrossing.mode != NotifyUngrab)
  1518. X            XUninductColormap(display,map_info->colormap);
  1519. X        break;
  1520. X      }
  1521. X      case MapNotify:
  1522. X      {
  1523. X        if (resource_info->debug)
  1524. X          (void) fprintf(stderr,"Map Notify: 0x%lx\n",event.xmap.window);
  1525. X        if (event.xmap.window == window->image.id)
  1526. X          {
  1527. X            if ((window->image.width < window->image.ximage->width) ||
  1528. X                (window->image.height < window->image.ximage->height))
  1529. X              XMapRaised(display,window->pan.id);
  1530. X            *state|=ImageMappedState;
  1531. X            break;
  1532. X          }
  1533. X        if (event.xmap.window == window->magnify.id)
  1534. X          {
  1535. X            *state|=MagnifyMappedState;
  1536. X            break;
  1537. X          }
  1538. X        if (event.xmap.window == window->pan.id)
  1539. X          {
  1540. X            XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1541. X            XFlush(display);
  1542. X            status=XMakeImage(display,resource_info,&window->pan,
  1543. X              displayed_image,window->pan.width,window->pan.height);
  1544. X            status|=XMakePixmap(display,resource_info,&window->pan);
  1545. X            if (status == False)
  1546. X              Error("unable to create pan icon image",(char *) NULL);
  1547. X            XSetWindowBackgroundPixmap(display,window->pan.id,
  1548. X              window->pan.pixmap);
  1549. X            XClearWindow(display,window->pan.id);
  1550. X            XDrawPanRectangle(display,window);
  1551. X            XDefineCursor(display,window->image.id,window->image.cursor);
  1552. X            *state|=PanIconMappedState;
  1553. X            break;
  1554. X          }
  1555. X        if (event.xmap.window == window->info.id)
  1556. X          {
  1557. X            *state|=InfoMappedState;
  1558. X            break;
  1559. X          }
  1560. X        if (event.xmap.window == window->icon.id)
  1561. X          {
  1562. X            status=XMakeImage(display,resource_info,&window->icon,
  1563. X              displayed_image,window->icon.width,window->icon.height);
  1564. X            status|=XMakePixmap(display,resource_info,&window->icon);
  1565. X            if (status == False)
  1566. X              Error("unable to create icon image",(char *) NULL);
  1567. X            XSetWindowBackgroundPixmap(display,window->icon.id,
  1568. X              window->icon.pixmap);
  1569. X            XClearWindow(display,window->icon.id);
  1570. X            break;
  1571. X          }
  1572. X        break;
  1573. X      }
  1574. X      case MappingNotify:
  1575. X      {
  1576. X        XRefreshKeyboardMapping(&event.xmapping);
  1577. X        break;
  1578. X      }
  1579. X      case NoExpose:
  1580. X        break;
  1581. X      case ReparentNotify:
  1582. X      {
  1583. X        if (resource_info->debug)
  1584. X          (void) fprintf(stderr,"Reparent Notify: 0x%lx=>0x%lx\n",
  1585. X            event.xreparent.parent,event.xreparent.window);
  1586. X        break;
  1587. X      }
  1588. X      case UnmapNotify:
  1589. X      {
  1590. X        if (resource_info->debug)
  1591. X          (void) fprintf(stderr,"Unmap Notify: 0x%lx\n",event.xunmap.window);
  1592. X        if (event.xunmap.window == window->image.id)
  1593. X          {
  1594. X            *state&=(~ImageMappedState);
  1595. X            if (*state & PanIconMappedState)
  1596. X              XWithdrawWindow(display,window->pan.id,window->pan.screen);
  1597. X            if (*state & MagnifyMappedState)
  1598. X              XWithdrawWindow(display,window->magnify.id,
  1599. X                window->magnify.screen);
  1600. X            break;
  1601. X          }
  1602. X        if (event.xunmap.window == window->magnify.id)
  1603. X          {
  1604. X            *state&=(~MagnifyMappedState);
  1605. X            break;
  1606. X          }
  1607. X        if (event.xunmap.window == window->pan.id)
  1608. X          {
  1609. X            *state&=(~PanIconMappedState);
  1610. X            break;
  1611. X          }
  1612. X        if (event.xunmap.window == window->info.id)
  1613. X          {
  1614. X            *state&=(~InfoMappedState);
  1615. X            break;
  1616. X          }
  1617. X        break;
  1618. X      }
  1619. X      case VisibilityNotify:
  1620. X      {
  1621. X        if (event.xvisibility.window == window->pan.id)
  1622. X          {
  1623. X            XMapRaised(display,window->pan.id);
  1624. X            break;
  1625. X          }
  1626. X        break;
  1627. X      }
  1628. X      default:
  1629. X      {
  1630. X        if (resource_info->debug)
  1631. X          (void) fprintf(stderr,"Event type: %d\n",event.type);
  1632. X        break;
  1633. X      }
  1634. X    }
  1635. X  if (*state & UpdateColormapState)
  1636. X    {
  1637. X      /*
  1638. X        Update window colormap and graphic context.
  1639. X      */
  1640. X      if (resource_info->debug)
  1641. X        (void) fprintf(stderr,"Update Colormap\n");
  1642. X      for (i=0; i < number_windows; i++)
  1643. X      {
  1644. X        XSetWindowColormap(display,magick_windows[i]->id,map_info->colormap);
  1645. X        XSetBackground(display,magick_windows[i]->graphic_context,
  1646. X          pixel_info.background_color.pixel);
  1647. X        XSetForeground(display,magick_windows[i]->graphic_context,
  1648. X          pixel_info.foreground_color.pixel);
  1649. X        XSetBackground(display,magick_windows[i]->highlight_context,
  1650. X          pixel_info.foreground_color.pixel);
  1651. X        XSetForeground(display,magick_windows[i]->highlight_context,
  1652. X          pixel_info.background_color.pixel);
  1653. X      }
  1654. X      *state&=(~UpdateColormapState);
  1655. X    }
  1656. X  if (*state & UpdateConfigurationState)
  1657. SHAR_EOF
  1658. true || echo 'restore of ImageMagick/display.c failed'
  1659. fi
  1660. echo 'End of  part 12'
  1661. echo 'File ImageMagick/display.c is continued in part 13'
  1662. echo 13 > _shar_seq_.tmp
  1663. exit 0
  1664. exit 0 # Just in case...
  1665.