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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i079:  imagemagic - X11 image processing and display, Part23/38
  4. Message-ID: <1993Jul14.231928.22107@sparky.sterling.com>
  5. X-Md4-Signature: 5838ce95e458d010445ee51cc81e264f
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:19:28 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 79
  13. Archive-name: imagemagic/part23
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.23 (part 23 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/display.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 23; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/display.c'
  36. else
  37. echo 'x - continuing file ImageMagick/display.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
  39. X
  40. X      /*
  41. X        User specified geometry.
  42. X      */
  43. X      size_hints=XAllocSizeHints();
  44. X      if (size_hints == (XSizeHints *) NULL)
  45. X        Error("unable to display on root","memory allocation failed");
  46. X      size_hints->flags=(long) NULL;
  47. X      (void) sprintf(default_geometry,"%ux%u",width,height);
  48. X      flags=XWMGeometry(display,visual_info->screen,
  49. X        resource_info->image_geometry,default_geometry,
  50. X        window_info.border_width,size_hints,&window_info.x,&window_info.y,
  51. X        (int *) &width,(int *) &height,&gravity);
  52. X      if (flags & (XValue | YValue))
  53. X        {
  54. X          width=XDisplayWidth(display,visual_info->screen);
  55. X          height=XDisplayHeight(display,visual_info->screen);
  56. X        }
  57. X      XFree((void *) size_hints);
  58. X    }
  59. X  /*
  60. X    Create the root pixmap.
  61. X  */
  62. X  window_info.pixmap=
  63. X    XCreatePixmap(display,window_info.id,width,height,window_info.depth);
  64. X  if (window_info.pixmap == (Pixmap) NULL)
  65. X    Error("unable to create X pixmap",(char *) NULL);
  66. X  /*
  67. X    Display pixmap on the root window.
  68. X  */
  69. X  if ((width > window_info.width) || (height > window_info.height))
  70. X    XFillRectangle(display,window_info.pixmap,window_info.highlight_context,
  71. X      0,0,width,height);
  72. X  XPutImage(display,window_info.pixmap,window_info.graphic_context,
  73. X    window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
  74. X    window_info.height);
  75. X  XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
  76. X  XClearWindow(display,window_info.id);
  77. X  /*
  78. X    Free resources.
  79. X  */
  80. X  XFreePixmap(display,window_info.pixmap);
  81. X  XDestroyImage(window_info.ximage);
  82. X  XFreeGC(display,window_info.graphic_context);
  83. X  XFreeGC(display,window_info.highlight_context);
  84. X  XFreeCursor(display,window_info.cursor);
  85. X  XFreeCursor(display,window_info.busy_cursor);
  86. X  if (pixel_info.pixels != (unsigned long *) NULL)
  87. X    (void) free((char *) pixel_info.pixels);
  88. X  XFree((void *) map_info);
  89. X  XFree((void *) visual_info);
  90. X  /*
  91. X    Put property on root window and set close-down mode to RetainPermanent.
  92. X  */
  93. X  window_info.pixmap=XCreatePixmap(display,root_window,1,1,1);
  94. X  if (window_info.pixmap == (Pixmap) NULL)
  95. X    Error("unable to create X pixmap",(char *) NULL);
  96. X  XChangeProperty(display,root_window,property,XA_PIXMAP,32,PropModeReplace,
  97. X    (unsigned char *) &window_info.pixmap,1);
  98. X  XSetCloseDownMode(display,RetainPermanent);
  99. }
  100. X
  101. /*
  102. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  103. %                                                                             %
  104. %                                                                             %
  105. %                                                                             %
  106. %   X D i s p l a y I m a g e                                                 %
  107. %                                                                             %
  108. %                                                                             %
  109. %                                                                             %
  110. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  111. %
  112. %  Function XDisplayImage displays an image via X11.  A new image is created
  113. %  and returned if the user interactively transforms the displayed image.
  114. %
  115. %  The format of the XDisplayImage routine is:
  116. %
  117. %      loaded_image=XDisplayImage(display,resource_info,argv,argc,image,state)
  118. %
  119. %  A description of each parameter follows:
  120. %
  121. %    o loaded_image:  Function XDisplayImage returns an image when the
  122. %      user chooses 'Load Image' from the command menu or picks a tile
  123. %      from the image directory.  Otherwise a null image is returned.
  124. %
  125. %    o display: Specifies a connection to an X server;  returned from
  126. %      XOpenDisplay.
  127. %
  128. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  129. %
  130. %    o argv: Specifies the application's argument list.
  131. %
  132. %    o argc: Specifies the number of arguments.
  133. %
  134. %    o image: Specifies an address to an address of an Image structure;
  135. %      returned from ReadImage.
  136. %
  137. %
  138. */
  139. static Image *XDisplayImage(display,resource_info,argv,argc,image,state)
  140. Display
  141. X  *display;
  142. X
  143. XXResourceInfo
  144. X  *resource_info;
  145. X
  146. char
  147. X  **argv;
  148. X
  149. int
  150. X  argc;
  151. X
  152. Image
  153. X  **image;
  154. X
  155. unsigned long
  156. X  *state;
  157. {
  158. #define MagnifySize  256  /* must be a power of 2 */
  159. #define MaxPanSize  96
  160. #define MaxWindows  9
  161. X
  162. X  char
  163. X    command[2048],
  164. X    text[2048];
  165. X
  166. X  Image
  167. X    *displayed_image,
  168. X    *loaded_image;
  169. X
  170. X  int
  171. X    status;
  172. X
  173. X  KeySym
  174. X    key_symbol;
  175. X
  176. X  register int
  177. X    i;
  178. X
  179. X  static Atom
  180. X    delete_property,
  181. X    protocols_property;
  182. X
  183. X  static Window
  184. X    root_window;
  185. X
  186. X  static XClassHint
  187. X    *class_hint;
  188. X
  189. X  static XPixelInfo
  190. X    pixel_info;
  191. X
  192. X  static XStandardColormap
  193. X    *map_info;
  194. X
  195. X  static XVisualInfo
  196. X    *visual_info = (XVisualInfo *) NULL;
  197. X
  198. X  static XWindowInfo
  199. X    *magick_windows[MaxWindows];
  200. X
  201. X  static XWindows
  202. X    *window;
  203. X
  204. X  static XWMHints
  205. X    *manager_hints;
  206. X
  207. X  static unsigned int
  208. X    number_windows;
  209. X
  210. X  struct stat
  211. X    file_info;
  212. X
  213. X  time_t
  214. X    update_time,
  215. X    timer;
  216. X
  217. X  unsigned int
  218. X    scale_factor;
  219. X
  220. X  XEvent
  221. X    event;
  222. X
  223. X  XFontStruct
  224. X    *font_info;
  225. X
  226. X  XGCValues
  227. X    graphic_context_value;
  228. X
  229. X  XWindowInfo
  230. X    previous_window;
  231. X
  232. X  if (visual_info == (XVisualInfo *) NULL)
  233. X    {
  234. X      /*
  235. X        Allocate standard colormap.
  236. X      */
  237. X      if (resource_info->debug)
  238. X        XSynchronize(display,True);
  239. X      map_info=XAllocStandardColormap();
  240. X      if (map_info == (XStandardColormap *) NULL)
  241. X        Error("unable to create standard colormap","memory allocation failed");
  242. X      map_info->colormap=(Colormap) NULL;
  243. X      pixel_info.pixels=(unsigned long *) NULL;
  244. X      /*
  245. X        Allocate visual.
  246. X      */
  247. X      visual_info=XBestVisualInfo(display,resource_info->visual_type,
  248. X        resource_info->map_type,map_info);
  249. X      if (visual_info == (XVisualInfo *) NULL)
  250. X        Error("unable to get visual",resource_info->visual_type);
  251. X      if (resource_info->debug)
  252. X        {
  253. X          (void) fprintf(stderr,"Visual:\n");
  254. X          (void) fprintf(stderr,"  visual id: 0x%lx\n",visual_info->visualid);
  255. X          (void) fprintf(stderr,"  class: %s\n",XVisualClassName(visual_info));
  256. X          (void) fprintf(stderr,"  depth: %d planes\n",visual_info->depth);
  257. X          (void) fprintf(stderr,"  size of colormap: %d entries\n",
  258. X            visual_info->colormap_size);
  259. X          (void) fprintf(stderr,"  red, green, blue masks: 0x%lx 0x%lx 0x%lx\n",
  260. X            visual_info->red_mask,visual_info->green_mask,
  261. X            visual_info->blue_mask);
  262. X          (void) fprintf(stderr,"  significant bits in color: %d bits\n",
  263. X            visual_info->bits_per_rgb);
  264. X        }
  265. X      /*
  266. X        Allocate atoms.
  267. X      */
  268. X      protocols_property=XInternAtom(display,"WM_PROTOCOLS",False);
  269. X      delete_property=XInternAtom(display,"WM_DELETE_WINDOW",False);
  270. X      if ((protocols_property == (Atom) NULL) ||
  271. X          (delete_property == (Atom) NULL))
  272. X        Error("unable to create property",(char *) NULL);
  273. X      /*
  274. X        Allocate class and manager hints.
  275. X      */
  276. X      class_hint=XAllocClassHint();
  277. X      manager_hints=XAllocWMHints();
  278. X      if ((class_hint == (XClassHint *) NULL) ||
  279. X          (manager_hints == (XWMHints *) NULL))
  280. X        Error("unable to allocate X hints",(char *) NULL);
  281. X      /*
  282. X        Initialize window id's.
  283. X      */
  284. X      root_window=XRootWindow(display,visual_info->screen);
  285. X      window=(XWindows *) malloc(sizeof(XWindows));
  286. X      if (window == (XWindows *) NULL)
  287. X        Error("unable to create X windows","memory allocation failed");
  288. X      number_windows=0;
  289. X      magick_windows[number_windows++]=(&window->backdrop);
  290. X      magick_windows[number_windows++]=(&window->icon);
  291. X      magick_windows[number_windows++]=(&window->image);
  292. X      magick_windows[number_windows++]=(&window->info);
  293. X      magick_windows[number_windows++]=(&window->magnify);
  294. X      magick_windows[number_windows++]=(&window->pan);
  295. X      magick_windows[number_windows++]=(&window->popup);
  296. X      for (i=0; i < number_windows; i++)
  297. X        magick_windows[i]->id=(Window) NULL;
  298. X    }
  299. X  /*
  300. X    Initialize Standard Colormap.
  301. X  */
  302. X  loaded_image=(Image *) NULL;
  303. X  displayed_image=(*image);
  304. X  if (resource_info->debug)
  305. X    {
  306. X      (void) fprintf(stderr,"Image: [%u] %s %ux%u ",displayed_image->scene,
  307. X        displayed_image->filename,displayed_image->columns,
  308. X        displayed_image->rows);
  309. X      if (displayed_image->colors != 0)
  310. X        (void) fprintf(stderr,"%uc ",displayed_image->colors);
  311. X      (void) fprintf(stderr,"%s\n",displayed_image->magick);
  312. X    }
  313. X  XMakeStandardColormap(display,visual_info,resource_info,&pixel_info,
  314. X    displayed_image,map_info);
  315. X  /*
  316. X    Initialize font info.
  317. X  */
  318. X  (void) sprintf(text," [%u] %s %ux%u %s ",displayed_image->scene,
  319. X    displayed_image->filename,displayed_image->columns,displayed_image->rows,
  320. X    XVisualClassName(visual_info));
  321. X  if (displayed_image->colors != 0)
  322. X    (void) sprintf(text,"%s%uc ",text,displayed_image->colors);
  323. X  font_info=XBestFont(display,resource_info,text,displayed_image->columns);
  324. X  if (font_info == (XFontStruct *) NULL)
  325. X    Error("unable to load font",resource_info->font);
  326. X  /*
  327. X    Initialize class hints.
  328. X  */
  329. X  if (resource_info->name == (char *) NULL)
  330. X    class_hint->res_name=client_name;
  331. X  else
  332. X    class_hint->res_name=resource_info->name;
  333. X  class_hint->res_class=(char *) "ImageMagick";
  334. X  /*
  335. X    Initialize graphic context.
  336. X  */
  337. X  window->context.id=(Window) NULL;
  338. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  339. X    resource_info,&window->context);
  340. X  manager_hints->flags=InputHint | StateHint;
  341. X  manager_hints->input=False;
  342. X  manager_hints->initial_state=WithdrawnState;
  343. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  344. X    delete_property,&window->context);
  345. X  if (resource_info->debug)
  346. X    (void) fprintf(stderr,"Window id: 0x%lx (context)\n",window->context.id);
  347. X  graphic_context_value.background=pixel_info.background_color.pixel;
  348. X  graphic_context_value.foreground=pixel_info.foreground_color.pixel;
  349. X  graphic_context_value.font=font_info->fid;
  350. X  graphic_context_value.function=GXcopy;
  351. X  graphic_context_value.line_width=2;
  352. X  graphic_context_value.graphics_exposures=False;
  353. X  graphic_context_value.plane_mask=AllPlanes;
  354. X  pixel_info.graphic_context=XCreateGC(display,window->context.id,GCBackground |
  355. X    GCFont | GCForeground | GCFunction | GCGraphicsExposures | GCLineWidth |
  356. X    GCPlaneMask,&graphic_context_value);
  357. X  if (pixel_info.graphic_context == (GC) NULL)
  358. X    Error("unable to create graphic context",(char *) NULL);
  359. X  graphic_context_value.background=pixel_info.foreground_color.pixel;
  360. X  graphic_context_value.foreground=pixel_info.background_color.pixel;
  361. X  pixel_info.highlight_context=XCreateGC(display,window->context.id,
  362. X    GCBackground | GCFont | GCForeground | GCFunction | GCGraphicsExposures |
  363. X    GCLineWidth | GCPlaneMask,&graphic_context_value);
  364. X  if (pixel_info.highlight_context == (GC) NULL)
  365. X    Error("unable to create graphic context",(char *) NULL);
  366. X  XDestroyWindow(display,window->context.id);
  367. X  /*
  368. X    Initialize icon window.
  369. X  */
  370. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  371. X    resource_info,&window->icon);
  372. X  XBestIconSize(display,&window->icon,displayed_image);
  373. X  window->icon.attributes.event_mask=StructureNotifyMask;
  374. X  manager_hints->flags=InputHint | StateHint;
  375. X  manager_hints->input=False;
  376. X  manager_hints->initial_state=IconicState;
  377. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  378. X    delete_property,&window->icon);
  379. X  if (resource_info->debug)
  380. X    (void) fprintf(stderr,"Window id: 0x%lx (icon)\n",window->icon.id);
  381. X  /*
  382. X    Initialize image window.
  383. X  */
  384. X  previous_window=window->image;
  385. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  386. X    resource_info,&window->image);
  387. X  window->image.name=(char *) malloc(2048*sizeof(char));
  388. X  window->image.icon_name=(char *) malloc(2048*sizeof(char));
  389. X  if ((window->image.name == NULL) || (window->image.icon_name == NULL))
  390. X    Error("unable to create image window","memory allocation failed");
  391. X  if (resource_info->title != (char *) NULL)
  392. X    {
  393. X      /*
  394. X        User specified window name.
  395. X      */
  396. X      (void) strcpy(window->image.name,resource_info->title);
  397. X      (void) strcpy(window->image.icon_name,resource_info->title);
  398. X    }
  399. X  else
  400. X    {
  401. X      char
  402. X        *p;
  403. X
  404. X      /*
  405. X        Window name is the base of the filename.
  406. X      */
  407. X      p=displayed_image->filename+strlen(displayed_image->filename)-1;
  408. X      while ((p > displayed_image->filename) && (*(p-1) != '/'))
  409. X        p--;
  410. X      (void) strcpy(window->image.name,"ImageMagick: ");
  411. X      (void) strcat(window->image.name,p);
  412. X      (void) strcpy(window->image.icon_name,p);
  413. X    }
  414. X  window->image.geometry=resource_info->image_geometry;
  415. X  window->image.width=displayed_image->columns;
  416. X  if (window->image.width >= XDisplayWidth(display,visual_info->screen))
  417. X    window->image.width=(XDisplayWidth(display,visual_info->screen)*7) >> 3;
  418. X  window->image.height=displayed_image->rows;
  419. X  if (window->image.height >= XDisplayHeight(display,visual_info->screen))
  420. X    window->image.height=(XDisplayHeight(display,visual_info->screen)*7) >> 3;
  421. X  window->image.border_width=resource_info->border_width;
  422. X  window->image.immutable=False;
  423. X  window->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  424. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
  425. X    KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
  426. X    StructureNotifyMask;
  427. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  428. X    resource_info,&window->backdrop);
  429. X  if (resource_info->backdrop || (window->backdrop.id != (Window) NULL))
  430. X    {
  431. X      /*
  432. X        Initialize backdrop window.
  433. X      */
  434. X      window->backdrop.cursor=XMakeInvisibleCursor(display,root_window);
  435. X      if (window->backdrop.cursor == (Cursor) NULL)
  436. X        Error("unable to create cursor",(char *) NULL);
  437. X      window->backdrop.name="ImageMagick Backdrop";
  438. X      window->backdrop.flags=USSize | USPosition;
  439. X      window->backdrop.width=XDisplayWidth(display,visual_info->screen);
  440. X      window->backdrop.height=XDisplayHeight(display,visual_info->screen);
  441. X      window->backdrop.border_width=0;
  442. X      window->backdrop.attributes.cursor=window->backdrop.cursor;
  443. X      window->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
  444. X        ButtonReleaseMask;
  445. X      window->backdrop.attributes.event_mask=KeyPressMask;
  446. X      window->backdrop.attributes.override_redirect=True;
  447. X      manager_hints->flags=IconWindowHint | InputHint | StateHint;
  448. X      manager_hints->icon_window=window->icon.id;
  449. X      manager_hints->input=True;
  450. X      manager_hints->initial_state=
  451. X        resource_info->iconic ? IconicState : NormalState;
  452. X      XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  453. X        delete_property,&window->backdrop);
  454. X      if (resource_info->debug)
  455. X        (void) fprintf(stderr,"Window id: 0x%lx (backdrop)\n",
  456. X          window->backdrop.id);
  457. X      XMapWindow(display,window->backdrop.id);
  458. X      XClearWindow(display,window->backdrop.id);
  459. X      if (window->image.id != (Window) NULL)
  460. X        {
  461. X          XDestroyWindow(display,window->image.id);
  462. X          window->image.id=(Window) NULL;
  463. X        }
  464. X      /*
  465. X        Position image in the center the backdrop.
  466. X      */
  467. X      window->image.flags|=USPosition;
  468. X      window->image.x=XDisplayWidth(display,visual_info->screen)/2-
  469. X        window->image.width/2;
  470. X      window->image.y=XDisplayHeight(display,visual_info->screen)/2-
  471. X        window->image.height/2;
  472. X      window->image.attributes.event_mask|=FocusChangeMask;
  473. X    }
  474. X  manager_hints->flags=IconWindowHint | InputHint | StateHint;
  475. X  manager_hints->icon_window=window->icon.id;
  476. X  manager_hints->input=True;
  477. X  manager_hints->initial_state=
  478. X    resource_info->iconic ? IconicState : NormalState;
  479. X  XMakeWindow(display,
  480. X    (resource_info->backdrop ? window->backdrop.id : root_window),argv,argc,
  481. X    class_hint,manager_hints,delete_property,&window->image);
  482. X  if (resource_info->debug)
  483. X    (void) fprintf(stderr,"Window id: 0x%lx (image)\n",window->image.id);
  484. X  if (window->backdrop.id == (Window) NULL)
  485. X    *state|=ReconfigureImageState;
  486. X  /*
  487. X    Initialize X image structure.
  488. X  */
  489. X  window->image.x=displayed_image->columns/2-window->image.width/2;
  490. X  window->image.y=displayed_image->rows/2-window->image.height/2;
  491. X  status=XMakeImage(display,resource_info,&window->image,displayed_image,
  492. X    displayed_image->columns,displayed_image->rows);
  493. X  if (status == False)
  494. X    Error("unable to create X image",(char *) NULL);
  495. X  if (resource_info->use_pixmap)
  496. X    (void) XMakePixmap(display,resource_info,&window->image);
  497. X  XMapWindow(display,window->image.id);
  498. X  /*
  499. X    Initialize magnify window and cursor.
  500. X  */
  501. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  502. X    resource_info,&window->magnify);
  503. X  window->magnify.name=(char *) malloc(2048*sizeof(char));
  504. X  if (window->magnify.name == NULL)
  505. X    Error("unable to create magnify window","memory allocation failed");
  506. X  (void) sprintf(window->magnify.name,"Magnify %uX",resource_info->magnify);
  507. X  window->magnify.cursor=XMakeMagnifyCursor(display,window->image.id,
  508. X    map_info->colormap,resource_info->background_color,
  509. X    resource_info->foreground_color);
  510. X  if (window->magnify.cursor == (Cursor) NULL)
  511. X    Error("unable to create cursor",(char *) NULL);
  512. X  XRecolorCursor(display,window->magnify.cursor,&pixel_info.background_color,
  513. X    &pixel_info.foreground_color);
  514. X  window->magnify.width=MagnifySize;
  515. X  window->magnify.height=MagnifySize;
  516. X  window->magnify.min_width=MagnifySize;
  517. X  window->magnify.min_height=MagnifySize;
  518. X  window->magnify.width_inc=MagnifySize;
  519. X  window->magnify.height_inc=MagnifySize;
  520. X  window->magnify.immutable=False;
  521. X  window->magnify.attributes.save_under=True;
  522. X  window->magnify.attributes.cursor=window->magnify.cursor;
  523. X  window->magnify.attributes.event_mask=ExposureMask | KeyPressMask |
  524. X    StructureNotifyMask;
  525. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  526. X  manager_hints->input=False;
  527. X  manager_hints->initial_state=NormalState;
  528. X  manager_hints->window_group=window->image.id;
  529. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  530. X    delete_property,&window->magnify);
  531. X  if (resource_info->debug)
  532. X    (void) fprintf(stderr,"Window id: 0x%lx (magnify)\n",window->magnify.id);
  533. X  /*
  534. X    Initialize panning window.
  535. X  */
  536. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  537. X    resource_info,&window->pan);
  538. X  window->pan.name="Pan Icon";
  539. X  scale_factor=UpShift(MaxPanSize)/displayed_image->columns;
  540. X  if (scale_factor > (UpShift(MaxPanSize)/displayed_image->rows))
  541. X    scale_factor=UpShift(MaxPanSize)/displayed_image->rows;
  542. X  window->pan.width=DownShift(displayed_image->columns*scale_factor);
  543. X  window->pan.height=DownShift(displayed_image->rows*scale_factor);
  544. X  window->pan.attributes.save_under=True;
  545. X  window->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  546. X    ButtonReleaseMask | StructureNotifyMask | VisibilityChangeMask;
  547. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  548. X  manager_hints->input=False;
  549. X  manager_hints->initial_state=NormalState;
  550. X  manager_hints->window_group=window->image.id;
  551. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  552. X    delete_property,&window->pan);
  553. X  if (resource_info->debug)
  554. X    (void) fprintf(stderr,"Window id: 0x%lx (pan)\n",window->pan.id);
  555. X  /*
  556. X    Initialize popup window.
  557. X  */
  558. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  559. X    resource_info,&window->popup);
  560. X  window->popup.name="ImageMagick Popup";
  561. X  window->popup.flags=PSize | PPosition;
  562. X  window->popup.attributes.override_redirect=True;
  563. X  window->popup.attributes.save_under=True;
  564. X  window->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
  565. X    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
  566. X    LeaveWindowMask | OwnerGrabButtonMask | VisibilityChangeMask;
  567. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  568. X  manager_hints->input=True;
  569. X  manager_hints->initial_state=NormalState;
  570. X  manager_hints->window_group=window->image.id;
  571. X  XMakeWindow(display,root_window,argv,argc,class_hint,manager_hints,
  572. X    delete_property,&window->popup);
  573. X  if (resource_info->debug)
  574. X    (void) fprintf(stderr,"Window id: 0x%lx (pop up)\n",window->popup.id);
  575. X  XSetTransientForHint(display,window->popup.id,window->image.id);
  576. X  /*
  577. X    Initialize info window.
  578. X  */
  579. X  XGetWindowInfo(display,visual_info,map_info,&pixel_info,font_info,
  580. X    resource_info,&window->info);
  581. X  window->info.name="ImageMagick Info";
  582. X  window->info.flags=PSize;
  583. X  window->info.attributes.save_under=True;
  584. X  window->info.attributes.win_gravity=UnmapGravity;
  585. X  window->info.attributes.event_mask=StructureNotifyMask;
  586. X  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  587. X  manager_hints->input=False;
  588. X  manager_hints->initial_state=NormalState;
  589. X  manager_hints->window_group=window->image.id;
  590. X  XMakeWindow(display,window->image.id,argv,argc,class_hint,manager_hints,
  591. X    delete_property,&window->info);
  592. X  if (resource_info->debug)
  593. X    (void) fprintf(stderr,"Window id: 0x%lx (info)\n",window->info.id);
  594. X  if (*state & ImageMappedState)
  595. X    {
  596. X      /*
  597. X        Image window already mapped-- selectively refresh or map pan window.
  598. X      */
  599. X      if ((window->image.width == previous_window.width) &&
  600. X          (window->image.height == previous_window.height))
  601. X        {
  602. X          XRefreshWindow(display,&window->image,(XEvent *) NULL);
  603. X          *state&=(~ReconfigureImageState);
  604. X        }
  605. X      if ((window->image.width < window->image.ximage->width) ||
  606. X          (window->image.height < window->image.ximage->height))
  607. X        XMapRaised(display,window->pan.id);  /* map panning window */
  608. X    }
  609. X  /*
  610. X    Respond to events.
  611. X  */
  612. X  timer=time((time_t *) NULL)+resource_info->delay;
  613. X  update_time=0;
  614. X  if (resource_info->update)
  615. X    {
  616. X      /*
  617. X        Determine when file data was last modified.
  618. X      */
  619. X      status=stat(displayed_image->filename,&file_info);
  620. X      if (status == 0)
  621. X        update_time=file_info.st_mtime;
  622. X    }
  623. X  *state&=(~LastImageState);
  624. X  *state&=(~NextImageState);
  625. X  do
  626. X  {
  627. X    /*
  628. X      Handle a window event.
  629. X    */
  630. X    if (resource_info->delay != 0)
  631. X      {
  632. X        if (timer < time((time_t *) NULL))
  633. X          if (!resource_info->update)
  634. X            *state|=NextImageState | ExitState;
  635. X          else
  636. X            {
  637. X              /*
  638. X                Determine if image file was modified.
  639. X              */
  640. X              status=stat(displayed_image->filename,&file_info);
  641. X              if (status == 0)
  642. X                if (update_time != file_info.st_mtime)
  643. X                  {
  644. X                    /*
  645. X                      Redisplay image.
  646. X                    */
  647. X                    loaded_image=ReadImage(resource_info->image_info);
  648. X                    if (loaded_image != (Image *) NULL)
  649. X                      *state|=NextImageState | ExitState;
  650. X                  }
  651. X              timer=time((time_t *) NULL)+resource_info->delay;
  652. X            }
  653. X        if (XEventsQueued(display,QueuedAfterFlush) == 0)
  654. X          {
  655. X            /*
  656. X              Block if delay > 0.
  657. X            */
  658. X            (void) sleep(1);
  659. X            continue;
  660. X          }
  661. X      }
  662. X    XNextEvent(display,&event);
  663. X    switch (event.type)
  664. X    {
  665. X      case ButtonPress:
  666. X      {
  667. X        if ((event.xbutton.button == Button3) &&
  668. X            (event.xbutton.state & Mod1Mask))
  669. X          {
  670. X            /*
  671. X              Convert Alt-Button3 to Button2.
  672. X            */
  673. X            event.xbutton.button=Button2;
  674. X            event.xbutton.state&=(~Mod1Mask);
  675. X          }
  676. X        if (event.xbutton.window == window->image.id)
  677. X          switch (event.xbutton.button)
  678. X          {
  679. X            case Button1:
  680. X            {
  681. X              int
  682. X                command_number;
  683. X
  684. X              static char
  685. X                *MenuSelections[]=
  686. X                {
  687. X                  "Image Info",
  688. X                  "Reflect",
  689. X                  "Rotate Right",
  690. X                  "Rotate Left",
  691. X                  "Half Size",
  692. X                  "Double Size",
  693. X                  "Restore",
  694. X                  "Annotate",
  695. X                  "Composite",
  696. X                  "Load",
  697. X                  "Write",
  698. X                  "Next",
  699. X                  "Previous",
  700. X                  "Quit"
  701. X                };
  702. X
  703. X              static KeySym
  704. X                MenuCommand[]=
  705. X                {
  706. X                  XK_i,
  707. X                  XK_r,
  708. X                  XK_slash,
  709. X                  XK_backslash,
  710. X                  XK_less,
  711. X                  XK_greater,
  712. X                  XK_o,
  713. X                  XK_a,
  714. X                  XK_c,
  715. X                  XK_l,
  716. X                  XK_w,
  717. X                  XK_n,
  718. X                  XK_p,
  719. X                  XK_q
  720. X                };
  721. X
  722. X              /*
  723. X                Select a command from the pop-up menu.
  724. X              */
  725. X              command_number=XPopupMenu(display,&window->popup,
  726. X                event.xbutton.x_root,event.xbutton.y_root,"Commands",
  727. X                MenuSelections,sizeof(MenuSelections)/sizeof(MenuSelections[0]),
  728. X                command);
  729. X              if (command_number >= 0)
  730. X                loaded_image=XImageWindowCommand(display,resource_info,window,
  731. X                  MenuCommand[command_number],&displayed_image,state);
  732. X              break;
  733. X            }
  734. X            case Button2:
  735. X            {
  736. X              /*
  737. X                User pressed the image clip button.
  738. X              */
  739. X              XClipImageWindow(display,resource_info,window,&event,
  740. X                displayed_image,state);
  741. X              break;
  742. X            }
  743. X            case Button3:
  744. X            {
  745. X              if (displayed_image->montage != (char *) NULL)
  746. X                {
  747. X                  /*
  748. X                    User picked an image tile to display.
  749. X                  */
  750. X                  loaded_image=XTileImageWindow(display,resource_info,window,
  751. X                    displayed_image,&event);
  752. X                  if (loaded_image != (Image *) NULL)
  753. X                    *state|=NextImageState | ExitState;
  754. X                  break;
  755. X                }
  756. X              /*
  757. X                User pressed the image magnify button.
  758. X              */
  759. X              if (*state & MagnifyMappedState)
  760. X                XRaiseWindow(display,window->magnify.id);
  761. X              else
  762. X                {
  763. X                  /*
  764. X                    Make magnify image.
  765. X                  */
  766. X                  status=XMakeImage(display,resource_info,&window->magnify,
  767. X                    (Image *) NULL,window->magnify.width,
  768. X                    window->magnify.height);
  769. X                  status|=XMakePixmap(display,resource_info,&window->magnify);
  770. X                  if (status == False)
  771. X                    Error("unable to create magnify image",(char *) NULL);
  772. X                  XMapRaised(display,window->magnify.id);
  773. X                }
  774. X              XMagnifyImageWindow(display,resource_info,window,&event);
  775. X              break;
  776. X            }
  777. X            default:
  778. X              break;
  779. X          }
  780. X        if (event.xbutton.window == window->pan.id)
  781. X          {
  782. X            XPanImageWindow(display,window,&event);
  783. X            break;
  784. X          }
  785. X        break;
  786. X      }
  787. X      case ClientMessage:
  788. X      {
  789. X        /*
  790. X          If client window delete message, exit.
  791. X        */
  792. X        if (event.xclient.message_type == protocols_property)
  793. X          if (*event.xclient.data.l == delete_property)
  794. X            if (event.xclient.window == window->image.id)
  795. X              *state|=ExitState;
  796. X            else
  797. X              XWithdrawWindow(display,event.xclient.window,visual_info->screen);
  798. X        break;
  799. X      }
  800. X      case ConfigureNotify:
  801. X      {
  802. X        if (resource_info->debug)
  803. X          (void) fprintf(stderr,"Configure Notify: 0x%lx %dx%d+%d+%d\n",
  804. X            event.xconfigure.window,event.xconfigure.width,
  805. X            event.xconfigure.height,event.xconfigure.x,event.xconfigure.y);
  806. X        if (event.xconfigure.window == window->image.id)
  807. X          {
  808. X            /*
  809. X              Image window has a new configuration.
  810. X            */
  811. X            if ((event.xconfigure.width != window->image.width) ||
  812. X                (event.xconfigure.height != window->image.height))
  813. X              {
  814. X                window->image.x=0;
  815. X                window->image.y=0;
  816. X                window->image.width=event.xconfigure.width;
  817. X                window->image.height=event.xconfigure.height;
  818. X                if (!(*state & ReconfigureImageState))
  819. X                  {
  820. X                    status=XConfigureImageWindow(display,resource_info,window,
  821. X                      window->image.width,window->image.height,displayed_image);
  822. X                    if (status == False)
  823. X                      XPopupAlert(display,&window->popup,
  824. X                        "unable to configure image",window->image.name);
  825. X                  }
  826. X                *state|=UpdateConfigurationState;
  827. X              }
  828. X            *state&=(~ReconfigureImageState);
  829. X            break;
  830. X          }
  831. X        if (event.xconfigure.window == window->magnify.id)
  832. X          {
  833. X            unsigned int
  834. X              magnify;
  835. X
  836. X            /*
  837. X              Magnify window has a new configuration.
  838. X            */
  839. X            window->magnify.width=event.xconfigure.width;
  840. X            window->magnify.height=event.xconfigure.height;
  841. X            if (!(*state & MagnifyMappedState))
  842. X              break;
  843. X            magnify=1;
  844. X            while (magnify <= event.xconfigure.width)
  845. X              magnify<<=1;
  846. X            while (magnify <= event.xconfigure.height)
  847. X              magnify<<=1;
  848. X            magnify>>=1;
  849. X            if ((magnify != event.xconfigure.width) ||
  850. X                (magnify != event.xconfigure.height))
  851. X              {
  852. X                XResizeWindow(display,window->magnify.id,magnify,magnify);
  853. X                break;
  854. X              }
  855. X            status=XMakeImage(display,resource_info,&window->magnify,
  856. X              (Image *) NULL,window->magnify.width,window->magnify.height);
  857. X            status|=XMakePixmap(display,resource_info,&window->magnify);
  858. X            if (status == False)
  859. X              Error("unable to create magnify image",(char *) NULL);
  860. X            XMakeMagnifyImage(display,resource_info,window);
  861. X            break;
  862. X          }
  863. X        if (event.xconfigure.window == window->pan.id)
  864. X          {
  865. X            /*
  866. X              Icon window has a new configuration.
  867. X            */
  868. X            window->pan.width=event.xconfigure.width;
  869. X            window->pan.height=event.xconfigure.height;
  870. X            break;
  871. X          }
  872. X        if (event.xconfigure.window == window->icon.id)
  873. X          {
  874. X            /*
  875. X              Icon window has a new configuration.
  876. X            */
  877. X            window->icon.width=event.xconfigure.width;
  878. X            window->icon.height=event.xconfigure.height;
  879. X            break;
  880. X          }
  881. X        break;
  882. X      }
  883. X      case EnterNotify:
  884. X      {
  885. X        /*
  886. X          Selectively install colormap.
  887. X        */
  888. X        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  889. X          if (event.xcrossing.mode != NotifyUngrab)
  890. X            XInductColormap(display,map_info->colormap);
  891. X        break;
  892. X      }
  893. X      case Expose:
  894. X      {
  895. X        if (resource_info->debug)
  896. X          (void) fprintf(stderr,"Expose: 0x%lx %dx%d+%d+%d\n",
  897. X            event.xexpose.window,event.xexpose.width,event.xexpose.height,
  898. X            event.xexpose.x,event.xexpose.y);
  899. X        /*
  900. X          Refresh windows that are now exposed.
  901. X        */
  902. X        if (event.xexpose.window == window->image.id)
  903. X          if (*state & ImageMappedState)
  904. X            {
  905. X              XRefreshWindow(display,&window->image,&event);
  906. X              timer=time((time_t *) NULL)+resource_info->delay;
  907. X              break;
  908. X            }
  909. X        if (event.xexpose.window == window->magnify.id)
  910. X          if (event.xexpose.count == 0)
  911. X            if (*state & MagnifyMappedState)
  912. X              {
  913. X                XMakeMagnifyImage(display,resource_info,window);
  914. X                break;
  915. X              }
  916. X        break;
  917. X      }
  918. X      case FocusOut:
  919. X      {
  920. X        /*
  921. X          Set input focus for backdrop window.
  922. X        */
  923. X        if (resource_info->debug)
  924. X          (void) fprintf(stderr,"FocusOut Notify: 0x%lx\n",event.xfocus.window);
  925. X        if (event.xfocus.window == window->image.id)
  926. X          XSetInputFocus(display,window->image.id,RevertToNone,CurrentTime);
  927. X        break;
  928. X      }
  929. X      case KeyPress:
  930. X      {
  931. X        if (*state & ReconfigureImageState)
  932. X          {
  933. X            /*
  934. X              No key press during image reconfiguration.
  935. X            */
  936. X            XBell(display,0);
  937. X            break;
  938. X          }
  939. X        /*
  940. X          Respond to a user key press.
  941. X        */
  942. X        *command=' ';
  943. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  944. X          &key_symbol,(XComposeStatus *) NULL);
  945. X        if (resource_info->debug)
  946. X          (void) fprintf(stderr,"Key press: 0x%lx (%c)\n",key_symbol,*command);
  947. X        if (event.xkey.state & ControlMask)
  948. X          *state|=ControlState;
  949. X        if (event.xkey.window == window->image.id)
  950. X          loaded_image=XImageWindowCommand(display,resource_info,window,
  951. X            key_symbol,&displayed_image,state);
  952. X        if (event.xkey.window == window->magnify.id)
  953. X          XMagnifyWindowCommand(display,resource_info,window,key_symbol);
  954. X        break;
  955. X      }
  956. X      case KeyRelease:
  957. X      {
  958. X        /*
  959. X          Respond to a user key release.
  960. X        */
  961. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  962. X          &key_symbol,(XComposeStatus *) NULL);
  963. X        if (resource_info->debug)
  964. X          (void) fprintf(stderr,"Key release: 0x%lx (%c)\n",key_symbol,
  965. X            *command);
  966. X        *state&=(~ControlState);
  967. X        break;
  968. X      }
  969. X      case LeaveNotify:
  970. X      {
  971. X        /*
  972. X          Selectively uninstall colormap.
  973. X        */
  974. X        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  975. X          if (event.xcrossing.mode != NotifyUngrab)
  976. X            XUninductColormap(display,map_info->colormap);
  977. X        break;
  978. X      }
  979. X      case MapNotify:
  980. X      {
  981. X        if (resource_info->debug)
  982. X          (void) fprintf(stderr,"Map Notify: 0x%lx\n",event.xmap.window);
  983. X        if (event.xmap.window == window->image.id)
  984. X          {
  985. X            if (window->backdrop.id != (Window) NULL)
  986. X              {
  987. X                /*
  988. X                  Install colormap and set input focus for backdrop window.
  989. X                */
  990. X                XInstallColormap(display,map_info->colormap);
  991. X                XSetInputFocus(display,window->image.id,RevertToNone,
  992. X                  CurrentTime);
  993. X              }
  994. X            if ((window->image.width < window->image.ximage->width) ||
  995. X                (window->image.height < window->image.ximage->height))
  996. X              XMapRaised(display,window->pan.id);
  997. X            *state|=ImageMappedState;
  998. X            break;
  999. X          }
  1000. X        if (event.xmap.window == window->magnify.id)
  1001. X          {
  1002. X            *state|=MagnifyMappedState;
  1003. X            break;
  1004. X          }
  1005. X        if (event.xmap.window == window->pan.id)
  1006. X          {
  1007. X            XMakePanImage(display,resource_info,window,displayed_image);
  1008. X            *state|=PanMappedState;
  1009. X            break;
  1010. X          }
  1011. X        if (event.xmap.window == window->info.id)
  1012. X          {
  1013. X            *state|=InfoMappedState;
  1014. X            break;
  1015. X          }
  1016. X        if (event.xmap.window == window->icon.id)
  1017. X          {
  1018. X            if (resource_info->colormap == PrivateColormap)
  1019. X              if ((visual_info->class == GrayScale) ||
  1020. X                  (visual_info->class == PseudoColor))
  1021. X                {
  1022. X                  /*
  1023. X                    Icons look best with a shared colormap.
  1024. X                  */
  1025. X                  resource_info->colormap=SharedColormap;
  1026. X                  XMakeStandardColormap(display,visual_info,resource_info,
  1027. X                    &pixel_info,displayed_image,map_info);
  1028. X                  *state|=UpdateColormapState;
  1029. X                  resource_info->colormap=PrivateColormap;
  1030. X                }
  1031. X            /*
  1032. X              Create an icon image.
  1033. X            */
  1034. X            status=XMakeImage(display,resource_info,&window->icon,
  1035. X              displayed_image,window->icon.width,window->icon.height);
  1036. X            status|=XMakePixmap(display,resource_info,&window->icon);
  1037. X            if (status == False)
  1038. X              Error("unable to create icon image",(char *) NULL);
  1039. X            XSetWindowBackgroundPixmap(display,window->icon.id,
  1040. X              window->icon.pixmap);
  1041. X            XClearWindow(display,window->icon.id);
  1042. X            break;
  1043. X          }
  1044. X        break;
  1045. X      }
  1046. X      case MappingNotify:
  1047. X      {
  1048. X        XRefreshKeyboardMapping(&event.xmapping);
  1049. X        break;
  1050. X      }
  1051. X      case NoExpose:
  1052. X        break;
  1053. X      case ReparentNotify:
  1054. X      {
  1055. X        if (resource_info->debug)
  1056. X          (void) fprintf(stderr,"Reparent Notify: 0x%lx=>0x%lx\n",
  1057. X            event.xreparent.parent,event.xreparent.window);
  1058. X        break;
  1059. X      }
  1060. X      case UnmapNotify:
  1061. X      {
  1062. X        if (resource_info->debug)
  1063. X          (void) fprintf(stderr,"Unmap Notify: 0x%lx\n",event.xunmap.window);
  1064. X        if (event.xunmap.window == window->image.id)
  1065. X          {
  1066. X            *state&=(~ImageMappedState);
  1067. X            if (*state & PanMappedState)
  1068. X              XWithdrawWindow(display,window->pan.id,window->pan.screen);
  1069. X            if (*state & MagnifyMappedState)
  1070. X              XWithdrawWindow(display,window->magnify.id,
  1071. X                window->magnify.screen);
  1072. X            break;
  1073. X          }
  1074. X        if (event.xunmap.window == window->magnify.id)
  1075. X          {
  1076. X            *state&=(~MagnifyMappedState);
  1077. X            break;
  1078. X          }
  1079. X        if (event.xunmap.window == window->pan.id)
  1080. X          {
  1081. X            *state&=(~PanMappedState);
  1082. X            break;
  1083. X          }
  1084. X        if (event.xunmap.window == window->info.id)
  1085. X          {
  1086. X            *state&=(~InfoMappedState);
  1087. X            break;
  1088. X          }
  1089. X        if (event.xunmap.window == window->icon.id)
  1090. X          if (resource_info->colormap == PrivateColormap)
  1091. X            if ((visual_info->class == GrayScale) ||
  1092. X                (visual_info->class == PseudoColor))
  1093. X              {
  1094. X                XMakeStandardColormap(display,visual_info,resource_info,
  1095. X                  &pixel_info,displayed_image,map_info);
  1096. X                *state|=UpdateColormapState;
  1097. X                break;
  1098. X              }
  1099. X        break;
  1100. X      }
  1101. X      case VisibilityNotify:
  1102. X      {
  1103. X        if (resource_info->debug)
  1104. X          (void) fprintf(stderr,"Visibility Notify: 0x%lx\n",
  1105. X             event.xvisibility.window);
  1106. X        if (event.xvisibility.window == window->pan.id)
  1107. X          {
  1108. X            XRaiseWindow(display,window->pan.id);
  1109. X            XDrawPanRectangle(display,window);
  1110. X            break;
  1111. X          }
  1112. X        break;
  1113. X      }
  1114. X      default:
  1115. X      {
  1116. X        if (resource_info->debug)
  1117. X          (void) fprintf(stderr,"Event type: %d\n",event.type);
  1118. X        break;
  1119. X      }
  1120. X    }
  1121. X  if (*state & UpdateColormapState)
  1122. X    {
  1123. X      /*
  1124. X        Update window colormap and graphic context.
  1125. X      */
  1126. X      if (resource_info->debug)
  1127. X        (void) fprintf(stderr,"Update Colormap\n");
  1128. X      for (i=0; i < number_windows; i++)
  1129. X      {
  1130. X        XSetWindowColormap(display,magick_windows[i]->id,map_info->colormap);
  1131. X        XSetBackground(display,magick_windows[i]->graphic_context,
  1132. X          pixel_info.background_color.pixel);
  1133. X        XSetForeground(display,magick_windows[i]->graphic_context,
  1134. X          pixel_info.foreground_color.pixel);
  1135. X        XSetBackground(display,magick_windows[i]->highlight_context,
  1136. X          pixel_info.foreground_color.pixel);
  1137. X        XSetForeground(display,magick_windows[i]->highlight_context,
  1138. X          pixel_info.background_color.pixel);
  1139. X      }
  1140. X      *state&=(~UpdateColormapState);
  1141. X    }
  1142. X  if (*state & UpdateConfigurationState)
  1143. X    {
  1144. X      XWindowChanges
  1145. X        window_changes;
  1146. X
  1147. X      if (resource_info->debug)
  1148. X        (void) fprintf(stderr,"Update Configuration\n");
  1149. X      if ((window->image.width < window->image.ximage->width) ||
  1150. X          (window->image.height < window->image.ximage->height))
  1151. X        {
  1152. X          /*
  1153. X            Update panning icon configuration.
  1154. X          */
  1155. X          window->image.x=window->image.ximage->width/2-window->image.width/2;
  1156. X          window->image.y=window->image.ximage->height/2-window->image.height/2;
  1157. X          window->pan.clip_geometry=window->image.clip_geometry;
  1158. X          scale_factor=UpShift(MaxPanSize)/displayed_image->columns;
  1159. X          if (scale_factor > (UpShift(MaxPanSize)/displayed_image->rows))
  1160. X            scale_factor=UpShift(MaxPanSize)/displayed_image->rows;
  1161. X          window_changes.width=DownShift(displayed_image->columns*scale_factor);
  1162. X          window_changes.height=DownShift(displayed_image->rows*scale_factor);
  1163. X          XReconfigureWMWindow(display,window->pan.id,window->pan.screen,
  1164. X            CWWidth | CWHeight,&window_changes);
  1165. X          XMapRaised(display,window->pan.id);
  1166. X          if (*state & PanMappedState)
  1167. X            XMakePanImage(display,resource_info,window,displayed_image);
  1168. X        }
  1169. X      else
  1170. X        if (*state & PanMappedState)
  1171. X          XWithdrawWindow(display,window->pan.id,window->pan.screen);
  1172. X      /*
  1173. X        Update magnifier configuration.
  1174. X      */
  1175. X      window->magnify.x=window->image.width >> 1;
  1176. X      window->magnify.y=window->image.height >> 1;
  1177. X      if (*state & MagnifyMappedState)
  1178. X        XMakeMagnifyImage(display,resource_info,window);
  1179. X      /*
  1180. X        Update icon configuration.
  1181. X      */
  1182. X      window->icon.clip_geometry=window->image.clip_geometry;
  1183. X      XBestIconSize(display,&window->icon,displayed_image);
  1184. X      window_changes.width=window->icon.width;
  1185. X      window_changes.height=window->icon.height;
  1186. X      XReconfigureWMWindow(display,window->icon.id,window->icon.screen,CWWidth |
  1187. X        CWHeight,&window_changes);
  1188. X      /*
  1189. X        Update font configuration.
  1190. X      */
  1191. X      (void) sprintf(text," [%u] %s %ux%u %s ",displayed_image->scene,
  1192. X        displayed_image->filename,displayed_image->columns,
  1193. X        displayed_image->rows,XVisualClassName(visual_info));
  1194. X      if (displayed_image->colors != 0)
  1195. X        (void) sprintf(text,"%s%uc ",text,displayed_image->colors);
  1196. X      XFreeFont(display,font_info);
  1197. X      font_info=XBestFont(display,resource_info,text,window->image.width);
  1198. X      if (font_info == (XFontStruct *) NULL)
  1199. X        Error("unable to load font",resource_info->font);
  1200. X      for (i=0; i < number_windows; i++)
  1201. X      {
  1202. X        magick_windows[i]->font_info=font_info;
  1203. X        XSetFont(display,magick_windows[i]->graphic_context,font_info->fid);
  1204. X        XSetFont(display,magick_windows[i]->highlight_context,font_info->fid);
  1205. X      }
  1206. X      /*
  1207. X        Update image window configuration.
  1208. X      */
  1209. X      XSetWindowBackground(display,window->image.id,
  1210. X        window->image.pixel_info->background_color.pixel);
  1211. X      XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1212. X      *state&=(~UpdateConfigurationState);
  1213. X    }
  1214. X  }
  1215. X  while (!(*state & ExitState));
  1216. X  if ((*state & LastImageState) || (*state & NextImageState))
  1217. X    *state&=(~ExitState);
  1218. X  /*
  1219. X    Alert user we are busy.
  1220. X  */
  1221. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1222. X  XFlush(display);
  1223. X  if (resource_info->write_filename != (char *) NULL)
  1224. X    {
  1225. X      /*
  1226. X        Update image with user transforms.
  1227. X      */
  1228. X      if ((window->image.clip_geometry != (char *) NULL) ||
  1229. X          (displayed_image->columns != window->image.ximage->width) ||
  1230. X          (displayed_image->rows != window->image.ximage->height))
  1231. X        {
  1232. X          char
  1233. X            image_geometry[2048];
  1234. X
  1235. X          /*
  1236. X            Clip and/or scale displayed_image.
  1237. X          */
  1238. X          (void) sprintf(image_geometry,"%dx%d",window->image.ximage->width,
  1239. X            window->image.ximage->height);
  1240. X          TransformImage(&displayed_image,window->image.clip_geometry,
  1241. X            image_geometry,(char *) NULL);
  1242. X        }
  1243. X      if (resource_info->colorspace == GRAYColorspace)
  1244. X        QuantizeImage(displayed_image,256,8,resource_info->dither,
  1245. X          GRAYColorspace,True);
  1246. X      if (resource_info->monochrome)
  1247. X        QuantizeImage(displayed_image,2,8,resource_info->dither,GRAYColorspace,
  1248. X          True);
  1249. X      if (resource_info->number_colors != 0)
  1250. X        if ((displayed_image->class == DirectClass) ||
  1251. X            (displayed_image->colors > resource_info->number_colors))
  1252. X          {
  1253. X            QuantizeImage(displayed_image,resource_info->number_colors,
  1254. X              resource_info->tree_depth,resource_info->dither,
  1255. X              resource_info->colorspace,True);
  1256. X            SyncImage(displayed_image);
  1257. X          }
  1258. X    }
  1259. X  /*
  1260. X    Withdraw pan and magnify window.
  1261. X  */
  1262. X  if (*state & PanMappedState)
  1263. X    XWithdrawWindow(display,window->pan.id,window->pan.screen);
  1264. X  if (*state & MagnifyMappedState)
  1265. X    XWithdrawWindow(display,window->magnify.id,window->magnify.screen);
  1266. X  XSync(display,False);
  1267. X  while (XCheckTypedWindowEvent(display,window->image.id,Expose,&event))
  1268. X    XRefreshWindow(display,&window->image,&event);
  1269. X  if (*state & ExitState)
  1270. X    {
  1271. X      /*
  1272. X        Destroy X windows.
  1273. X      */
  1274. X      for (i=0; i < number_windows; i++)
  1275. X      {
  1276. X        if (magick_windows[i]->id != (Window) NULL)
  1277. X          XDestroyWindow(display,magick_windows[i]->id);
  1278. X        if (magick_windows[i]->ximage != (XImage *) NULL)
  1279. X          XDestroyImage(magick_windows[i]->ximage);
  1280. X        if (magick_windows[i]->pixmap != (Pixmap) NULL)
  1281. X          XFreePixmap(display,magick_windows[i]->pixmap);
  1282. X      }
  1283. X      /*
  1284. X        Free Standard Colormap.
  1285. X      */
  1286. X      if (resource_info->map_type == (char *) NULL)
  1287. X        XFreeStandardColormap(display,visual_info,&pixel_info,map_info);
  1288. X      (void) free((void *) window);
  1289. X      XFree((void *) class_hint);
  1290. X      XFree((void *) manager_hints);
  1291. X      XFree((void *) map_info);
  1292. X      XFree((void *) visual_info);
  1293. X      visual_info=(XVisualInfo *) NULL;
  1294. X    }
  1295. X  /*
  1296. X    Free X resources.
  1297. X  */
  1298. X  (void) free((char *) window->magnify.name);
  1299. X  (void) free((char *) window->image.name);
  1300. X  (void) free((char *) window->image.icon_name);
  1301. X  for (i=0; i < number_windows; i++)
  1302. X  {
  1303. X    XFreeCursor(display,magick_windows[i]->cursor);
  1304. X    XFreeCursor(display,magick_windows[i]->busy_cursor);
  1305. X  }
  1306. X  XFreeGC(display,pixel_info.graphic_context);
  1307. X  XFreeGC(display,pixel_info.highlight_context);
  1308. X  XFreeFont(display,font_info);
  1309. X  XFlush(display);
  1310. X  *image=displayed_image;
  1311. X  return(loaded_image);
  1312. }
  1313. X
  1314. /*
  1315. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1316. %                                                                             %
  1317. %                                                                             %
  1318. %                                                                             %
  1319. %   X D r a w P a n R e c t a n g l e                                         %
  1320. %                                                                             %
  1321. %                                                                             %
  1322. %                                                                             %
  1323. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1324. %
  1325. %  Function XDrawPanRectangle draws a rectangle in the pan window.  The pan
  1326. %  window displays a scaled image and the rectangle shows which portion of
  1327. %  the image is displayed in the image window.
  1328. %
  1329. %  The format of the XDrawPanRectangle routine is:
  1330. %
  1331. %    XDrawPanRectangle(display,window)
  1332. %
  1333. %  A description of each parameter follows:
  1334. %
  1335. %    o display: Specifies a connection to an X server;  returned from
  1336. %      XOpenDisplay.
  1337. %
  1338. %    o window: Specifies a pointer to a XWindows structure.
  1339. %
  1340. %
  1341. */
  1342. static void XDrawPanRectangle(display,window)
  1343. Display
  1344. X  *display;
  1345. X
  1346. XXWindows
  1347. X  *window;
  1348. {
  1349. X  unsigned long
  1350. X    scale_factor;
  1351. X
  1352. X  int
  1353. X    x,
  1354. X    y;
  1355. X
  1356. X  unsigned int
  1357. X    height,
  1358. X    width;
  1359. X
  1360. X  /*
  1361. X    Determine dimensions of the panning rectangle.
  1362. X  */
  1363. X  scale_factor=(unsigned long)
  1364. X    (UpShift(window->pan.width)/window->image.ximage->width);
  1365. X  x=DownShift(window->image.x*scale_factor);
  1366. X  width=DownShift(window->image.width*scale_factor);
  1367. X  scale_factor=(unsigned long)
  1368. X    (UpShift(window->pan.height)/window->image.ximage->height);
  1369. X  y=DownShift(window->image.y*scale_factor);
  1370. X  height=DownShift(window->image.height*scale_factor);
  1371. X  /*
  1372. X    Display the panning rectangle.
  1373. X  */
  1374. X  XClearWindow(display,window->pan.id);
  1375. X  XSetForeground(display,window->pan.graphic_context,
  1376. X    window->image.pixel_info->background_color.pixel);
  1377. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x+1,y+1,
  1378. X    width-2,height-2);
  1379. X  XSetForeground(display,window->pan.graphic_context,
  1380. X    window->image.pixel_info->foreground_color.pixel);
  1381. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x,y,
  1382. X    width,height);
  1383. }
  1384. X
  1385. /*
  1386. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1387. %                                                                             %
  1388. %                                                                             %
  1389. %                                                                             %
  1390. %   X I m a g e W i n d o w C o m m a n d                                     %
  1391. SHAR_EOF
  1392. true || echo 'restore of ImageMagick/display.c failed'
  1393. fi
  1394. echo 'End of ImageMagick part 23'
  1395. echo 'File ImageMagick/display.c is continued in part 24'
  1396. echo 24 > _shar_seq_.tmp
  1397. exit 0
  1398.  
  1399. exit 0 # Just in case...
  1400. -- 
  1401.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1402. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1403.  "It's intuitively obvious to the |
  1404.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1405.