home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4180 < prev    next >
Encoding:
Text File  |  1992-12-14  |  57.5 KB  |  1,671 lines

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