PageRenderTime 108ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 2ms

/MagickCore/xwindow.c

https://gitlab.com/ImageMagick/ImageMagick
C | 10049 lines | 6708 code | 410 blank | 2931 comment | 1675 complexity | e4692268bb93fb48f1137ff880e30934 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % %
  4. % %
  5. % %
  6. % X X W W IIIII N N DDDD OOO W W %
  7. % X X W W I NN N D D O O W W %
  8. % X W W I N N N D D O O W W %
  9. % X X W W W I N NN D D O O W W W %
  10. % X X W W IIIII N N DDDD OOO W W %
  11. % %
  12. % %
  13. % MagickCore X11 Utility Methods %
  14. % %
  15. % Software Design %
  16. % Cristy %
  17. % July 1992 %
  18. % %
  19. % %
  20. % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
  21. % dedicated to making software imaging solutions freely available. %
  22. % %
  23. % You may not use this file except in compliance with the License. You may %
  24. % obtain a copy of the License at %
  25. % %
  26. % https://imagemagick.org/script/license.php %
  27. % %
  28. % Unless required by applicable law or agreed to in writing, software %
  29. % distributed under the License is distributed on an "AS IS" BASIS, %
  30. % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
  31. % See the License for the specific language governing permissions and %
  32. % limitations under the License. %
  33. % %
  34. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  35. %
  36. %
  37. */
  38. /*
  39. Include declarations.
  40. */
  41. #include "MagickCore/studio.h"
  42. #include "MagickCore/animate.h"
  43. #include "MagickCore/artifact.h"
  44. #include "MagickCore/blob.h"
  45. #include "MagickCore/cache.h"
  46. #include "MagickCore/client.h"
  47. #include "MagickCore/color.h"
  48. #include "MagickCore/color-private.h"
  49. #include "MagickCore/colormap.h"
  50. #include "MagickCore/composite.h"
  51. #include "MagickCore/constitute.h"
  52. #include "MagickCore/display.h"
  53. #include "MagickCore/distort.h"
  54. #include "MagickCore/exception.h"
  55. #include "MagickCore/exception-private.h"
  56. #include "MagickCore/geometry.h"
  57. #include "MagickCore/identify.h"
  58. #include "MagickCore/image.h"
  59. #include "MagickCore/image-private.h"
  60. #include "MagickCore/list.h"
  61. #include "MagickCore/locale_.h"
  62. #include "MagickCore/log.h"
  63. #include "MagickCore/magick.h"
  64. #include "MagickCore/memory_.h"
  65. #include "MagickCore/memory-private.h"
  66. #include "MagickCore/monitor.h"
  67. #include "MagickCore/nt-base-private.h"
  68. #include "MagickCore/option.h"
  69. #include "MagickCore/pixel-accessor.h"
  70. #include "MagickCore/quantize.h"
  71. #include "MagickCore/quantum.h"
  72. #include "MagickCore/quantum-private.h"
  73. #include "MagickCore/resource_.h"
  74. #include "MagickCore/resize.h"
  75. #include "MagickCore/statistic.h"
  76. #include "MagickCore/string_.h"
  77. #include "MagickCore/string-private.h"
  78. #include "MagickCore/transform.h"
  79. #include "MagickCore/transform-private.h"
  80. #include "MagickCore/token.h"
  81. #include "MagickCore/utility.h"
  82. #include "MagickCore/utility-private.h"
  83. #include "MagickCore/widget.h"
  84. #include "MagickCore/widget-private.h"
  85. #include "MagickCore/xwindow.h"
  86. #include "MagickCore/xwindow-private.h"
  87. #include "MagickCore/version.h"
  88. #if defined(__BEOS__)
  89. #include <OS.h>
  90. #endif
  91. #if defined(MAGICKCORE_X11_DELEGATE)
  92. #include <X11/Xproto.h>
  93. #include <X11/Xlocale.h>
  94. #if defined(MAGICK_HAVE_POLL)
  95. # include <sys/poll.h>
  96. #endif
  97. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  98. #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
  99. # include <machine/param.h>
  100. #endif
  101. #include <sys/ipc.h>
  102. #include <sys/shm.h>
  103. #include <X11/extensions/XShm.h>
  104. #endif
  105. #if defined(MAGICKCORE_HAVE_SHAPE)
  106. #include <X11/extensions/shape.h>
  107. #endif
  108. /*
  109. X defines.
  110. */
  111. #define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
  112. (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
  113. QuantumRange)))
  114. #define XGammaPacket(map,color) (size_t) (map->base_pixel+ \
  115. ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
  116. map->red_mult)+ \
  117. ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
  118. map->green_mult)+ \
  119. ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
  120. map->blue_mult))
  121. #define XGammaPixel(image,map,color) (size_t) (map->base_pixel+ \
  122. ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \
  123. map->red_mult)+ \
  124. ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \
  125. map->green_mult)+ \
  126. ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \
  127. map->blue_mult))
  128. #define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \
  129. (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
  130. QuantumRange)))
  131. #define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
  132. (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
  133. QuantumRange)))
  134. #define XStandardPixel(map,color) (size_t) (map->base_pixel+ \
  135. (((color)->red*map->red_max/65535L)*map->red_mult)+ \
  136. (((color)->green*map->green_max/65535L)*map->green_mult)+ \
  137. (((color)->blue*map->blue_max/65535L)*map->blue_mult))
  138. #define AccentuateModulate ScaleCharToQuantum(80)
  139. #define HighlightModulate ScaleCharToQuantum(125)
  140. #define ShadowModulate ScaleCharToQuantum(135)
  141. #define DepthModulate ScaleCharToQuantum(185)
  142. #define TroughModulate ScaleCharToQuantum(110)
  143. #define XLIB_ILLEGAL_ACCESS 1
  144. #undef ForgetGravity
  145. #undef NorthWestGravity
  146. #undef NorthGravity
  147. #undef NorthEastGravity
  148. #undef WestGravity
  149. #undef CenterGravity
  150. #undef EastGravity
  151. #undef SouthWestGravity
  152. #undef SouthGravity
  153. #undef SouthEastGravity
  154. #undef StaticGravity
  155. #undef index
  156. #if defined(hpux9)
  157. #define XFD_SET int
  158. #else
  159. #define XFD_SET fd_set
  160. #endif
  161. /*
  162. Enumeration declarations.
  163. */
  164. typedef enum
  165. {
  166. #undef DoRed
  167. DoRed = 0x0001,
  168. #undef DoGreen
  169. DoGreen = 0x0002,
  170. #undef DoBlue
  171. DoBlue = 0x0004,
  172. DoMatte = 0x0008
  173. } XColorFlags;
  174. /*
  175. Typedef declarations.
  176. */
  177. typedef struct _DiversityPacket
  178. {
  179. Quantum
  180. red,
  181. green,
  182. blue;
  183. unsigned short
  184. index;
  185. size_t
  186. count;
  187. } DiversityPacket;
  188. /*
  189. Constant declaractions.
  190. */
  191. static MagickBooleanType
  192. xerror_alert = MagickFalse;
  193. /*
  194. Method prototypes.
  195. */
  196. static const char
  197. *XVisualClassName(const int);
  198. static double
  199. blue_gamma = 1.0,
  200. green_gamma = 1.0,
  201. red_gamma = 1.0;
  202. static MagickBooleanType
  203. XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
  204. static void
  205. XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
  206. XImage *,XImage *,ExceptionInfo *),
  207. XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
  208. XImage *,XImage *,ExceptionInfo *);
  209. static Window
  210. XSelectWindow(Display *,RectangleInfo *);
  211. /*
  212. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  213. % %
  214. % %
  215. % %
  216. % D e s t r o y X R e s o u r c e s %
  217. % %
  218. % %
  219. % %
  220. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  221. %
  222. % DestroyXResources() destroys any X resources.
  223. %
  224. % The format of the DestroyXResources method is:
  225. %
  226. % void DestroyXResources()
  227. %
  228. % A description of each parameter follows:
  229. %
  230. */
  231. MagickExport void DestroyXResources(void)
  232. {
  233. register int
  234. i;
  235. unsigned int
  236. number_windows;
  237. XWindowInfo
  238. *magick_windows[MaxXWindows];
  239. XWindows
  240. *windows;
  241. DestroyXWidget();
  242. windows=XSetWindows((XWindows *) ~0);
  243. if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
  244. return;
  245. number_windows=0;
  246. magick_windows[number_windows++]=(&windows->context);
  247. magick_windows[number_windows++]=(&windows->group_leader);
  248. magick_windows[number_windows++]=(&windows->backdrop);
  249. magick_windows[number_windows++]=(&windows->icon);
  250. magick_windows[number_windows++]=(&windows->image);
  251. magick_windows[number_windows++]=(&windows->info);
  252. magick_windows[number_windows++]=(&windows->magnify);
  253. magick_windows[number_windows++]=(&windows->pan);
  254. magick_windows[number_windows++]=(&windows->command);
  255. magick_windows[number_windows++]=(&windows->widget);
  256. magick_windows[number_windows++]=(&windows->popup);
  257. for (i=0; i < (int) number_windows; i++)
  258. {
  259. if (magick_windows[i]->mapped != MagickFalse)
  260. {
  261. (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
  262. magick_windows[i]->screen);
  263. magick_windows[i]->mapped=MagickFalse;
  264. }
  265. if (magick_windows[i]->name != (char *) NULL)
  266. magick_windows[i]->name=(char *)
  267. RelinquishMagickMemory(magick_windows[i]->name);
  268. if (magick_windows[i]->icon_name != (char *) NULL)
  269. magick_windows[i]->icon_name=(char *)
  270. RelinquishMagickMemory(magick_windows[i]->icon_name);
  271. if (magick_windows[i]->cursor != (Cursor) NULL)
  272. {
  273. (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
  274. magick_windows[i]->cursor=(Cursor) NULL;
  275. }
  276. if (magick_windows[i]->busy_cursor != (Cursor) NULL)
  277. {
  278. (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
  279. magick_windows[i]->busy_cursor=(Cursor) NULL;
  280. }
  281. if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
  282. {
  283. (void) XFreePixmap(windows->display,
  284. magick_windows[i]->highlight_stipple);
  285. magick_windows[i]->highlight_stipple=(Pixmap) NULL;
  286. }
  287. if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
  288. {
  289. (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
  290. magick_windows[i]->shadow_stipple=(Pixmap) NULL;
  291. }
  292. if (magick_windows[i]->matte_image != (XImage *) NULL)
  293. {
  294. XDestroyImage(magick_windows[i]->matte_image);
  295. magick_windows[i]->matte_image=(XImage *) NULL;
  296. }
  297. if (magick_windows[i]->ximage != (XImage *) NULL)
  298. {
  299. XDestroyImage(magick_windows[i]->ximage);
  300. magick_windows[i]->ximage=(XImage *) NULL;
  301. }
  302. if (magick_windows[i]->pixmap != (Pixmap) NULL)
  303. {
  304. (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
  305. magick_windows[i]->pixmap=(Pixmap) NULL;
  306. }
  307. if (magick_windows[i]->id != (Window) NULL)
  308. {
  309. (void) XDestroyWindow(windows->display,magick_windows[i]->id);
  310. magick_windows[i]->id=(Window) NULL;
  311. }
  312. if (magick_windows[i]->destroy != MagickFalse)
  313. {
  314. if (magick_windows[i]->image != (Image *) NULL)
  315. {
  316. magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
  317. magick_windows[i]->image=NewImageList();
  318. }
  319. if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
  320. {
  321. (void) XFreePixmap(windows->display,
  322. magick_windows[i]->matte_pixmap);
  323. magick_windows[i]->matte_pixmap=(Pixmap) NULL;
  324. }
  325. }
  326. if (magick_windows[i]->segment_info != (void *) NULL)
  327. {
  328. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  329. XShmSegmentInfo
  330. *segment_info;
  331. segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
  332. if (segment_info != (XShmSegmentInfo *) NULL)
  333. if (segment_info[0].shmid >= 0)
  334. {
  335. if (segment_info[0].shmaddr != NULL)
  336. (void) shmdt(segment_info[0].shmaddr);
  337. (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
  338. segment_info[0].shmaddr=NULL;
  339. segment_info[0].shmid=(-1);
  340. }
  341. #endif
  342. magick_windows[i]->segment_info=(void *)
  343. RelinquishMagickMemory(magick_windows[i]->segment_info);
  344. }
  345. }
  346. windows->icon_resources=(XResourceInfo *)
  347. RelinquishMagickMemory(windows->icon_resources);
  348. if (windows->icon_pixel != (XPixelInfo *) NULL)
  349. {
  350. if (windows->icon_pixel->pixels != (unsigned long *) NULL)
  351. windows->icon_pixel->pixels=(unsigned long *)
  352. RelinquishMagickMemory(windows->icon_pixel->pixels);
  353. if (windows->icon_pixel->annotate_context != (GC) NULL)
  354. XFreeGC(windows->display,windows->icon_pixel->annotate_context);
  355. windows->icon_pixel=(XPixelInfo *)
  356. RelinquishMagickMemory(windows->icon_pixel);
  357. }
  358. if (windows->pixel_info != (XPixelInfo *) NULL)
  359. {
  360. if (windows->pixel_info->pixels != (unsigned long *) NULL)
  361. windows->pixel_info->pixels=(unsigned long *)
  362. RelinquishMagickMemory(windows->pixel_info->pixels);
  363. if (windows->pixel_info->annotate_context != (GC) NULL)
  364. XFreeGC(windows->display,windows->pixel_info->annotate_context);
  365. if (windows->pixel_info->widget_context != (GC) NULL)
  366. XFreeGC(windows->display,windows->pixel_info->widget_context);
  367. if (windows->pixel_info->highlight_context != (GC) NULL)
  368. XFreeGC(windows->display,windows->pixel_info->highlight_context);
  369. windows->pixel_info=(XPixelInfo *)
  370. RelinquishMagickMemory(windows->pixel_info);
  371. }
  372. if (windows->font_info != (XFontStruct *) NULL)
  373. {
  374. XFreeFont(windows->display,windows->font_info);
  375. windows->font_info=(XFontStruct *) NULL;
  376. }
  377. if (windows->class_hints != (XClassHint *) NULL)
  378. {
  379. if (windows->class_hints->res_name != (char *) NULL)
  380. windows->class_hints->res_name=DestroyString(
  381. windows->class_hints->res_name);
  382. if (windows->class_hints->res_class != (char *) NULL)
  383. windows->class_hints->res_class=DestroyString(
  384. windows->class_hints->res_class);
  385. XFree(windows->class_hints);
  386. windows->class_hints=(XClassHint *) NULL;
  387. }
  388. if (windows->manager_hints != (XWMHints *) NULL)
  389. {
  390. XFree(windows->manager_hints);
  391. windows->manager_hints=(XWMHints *) NULL;
  392. }
  393. if (windows->map_info != (XStandardColormap *) NULL)
  394. {
  395. XFree(windows->map_info);
  396. windows->map_info=(XStandardColormap *) NULL;
  397. }
  398. if (windows->icon_map != (XStandardColormap *) NULL)
  399. {
  400. XFree(windows->icon_map);
  401. windows->icon_map=(XStandardColormap *) NULL;
  402. }
  403. if (windows->visual_info != (XVisualInfo *) NULL)
  404. {
  405. XFree(windows->visual_info);
  406. windows->visual_info=(XVisualInfo *) NULL;
  407. }
  408. if (windows->icon_visual != (XVisualInfo *) NULL)
  409. {
  410. XFree(windows->icon_visual);
  411. windows->icon_visual=(XVisualInfo *) NULL;
  412. }
  413. (void) XSetWindows((XWindows *) NULL);
  414. }
  415. /*
  416. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  417. % %
  418. % %
  419. % %
  420. % X A n n o t a t e I m a g e %
  421. % %
  422. % %
  423. % %
  424. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  425. %
  426. % XAnnotateImage() annotates the image with text.
  427. %
  428. % The format of the XAnnotateImage method is:
  429. %
  430. % MagickBooleanType XAnnotateImage(Display *display,
  431. % const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
  432. % ExceptionInfo *exception)
  433. %
  434. % A description of each parameter follows:
  435. %
  436. % o display: Specifies a connection to an X server; returned from
  437. % XOpenDisplay.
  438. %
  439. % o pixel: Specifies a pointer to a XPixelInfo structure.
  440. %
  441. % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
  442. %
  443. % o image: the image.
  444. %
  445. % o exception: return any errors or warnings in this structure.
  446. %
  447. */
  448. MagickPrivate MagickBooleanType XAnnotateImage(Display *display,
  449. const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
  450. ExceptionInfo *exception)
  451. {
  452. CacheView
  453. *annotate_view;
  454. GC
  455. annotate_context;
  456. Image
  457. *annotate_image;
  458. int
  459. x,
  460. y;
  461. PixelTrait
  462. alpha_trait;
  463. Pixmap
  464. annotate_pixmap;
  465. unsigned int
  466. depth,
  467. height,
  468. width;
  469. Window
  470. root_window;
  471. XGCValues
  472. context_values;
  473. XImage
  474. *annotate_ximage;
  475. /*
  476. Initialize annotated image.
  477. */
  478. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  479. assert(display != (Display *) NULL);
  480. assert(pixel != (XPixelInfo *) NULL);
  481. assert(annotate_info != (XAnnotateInfo *) NULL);
  482. assert(image != (Image *) NULL);
  483. /*
  484. Initialize annotated pixmap.
  485. */
  486. root_window=XRootWindow(display,XDefaultScreen(display));
  487. depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
  488. annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
  489. annotate_info->height,depth);
  490. if (annotate_pixmap == (Pixmap) NULL)
  491. return(MagickFalse);
  492. /*
  493. Initialize graphics info.
  494. */
  495. context_values.background=0;
  496. context_values.foreground=(size_t) (~0);
  497. context_values.font=annotate_info->font_info->fid;
  498. annotate_context=XCreateGC(display,root_window,(unsigned long)
  499. (GCBackground | GCFont | GCForeground),&context_values);
  500. if (annotate_context == (GC) NULL)
  501. return(MagickFalse);
  502. /*
  503. Draw text to pixmap.
  504. */
  505. (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
  506. (int) annotate_info->font_info->ascent,annotate_info->text,
  507. (int) strlen(annotate_info->text));
  508. (void) XFreeGC(display,annotate_context);
  509. /*
  510. Initialize annotated X image.
  511. */
  512. annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
  513. annotate_info->height,AllPlanes,ZPixmap);
  514. if (annotate_ximage == (XImage *) NULL)
  515. return(MagickFalse);
  516. (void) XFreePixmap(display,annotate_pixmap);
  517. /*
  518. Initialize annotated image.
  519. */
  520. annotate_image=AcquireImage((ImageInfo *) NULL,exception);
  521. if (annotate_image == (Image *) NULL)
  522. return(MagickFalse);
  523. annotate_image->columns=annotate_info->width;
  524. annotate_image->rows=annotate_info->height;
  525. /*
  526. Transfer annotated X image to image.
  527. */
  528. width=(unsigned int) image->columns;
  529. height=(unsigned int) image->rows;
  530. x=0;
  531. y=0;
  532. (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
  533. (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
  534. (ssize_t) y,&annotate_image->background_color,exception);
  535. if (annotate_info->stencil == ForegroundStencil)
  536. annotate_image->alpha_trait=BlendPixelTrait;
  537. annotate_view=AcquireAuthenticCacheView(annotate_image,exception);
  538. for (y=0; y < (int) annotate_image->rows; y++)
  539. {
  540. register int
  541. x;
  542. register Quantum
  543. *magick_restrict q;
  544. q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
  545. annotate_image->columns,1,exception);
  546. if (q == (Quantum *) NULL)
  547. break;
  548. for (x=0; x < (int) annotate_image->columns; x++)
  549. {
  550. SetPixelAlpha(annotate_image,OpaqueAlpha,q);
  551. if (XGetPixel(annotate_ximage,x,y) == 0)
  552. {
  553. /*
  554. Set this pixel to the background color.
  555. */
  556. SetPixelRed(annotate_image,ScaleShortToQuantum(
  557. pixel->box_color.red),q);
  558. SetPixelGreen(annotate_image,ScaleShortToQuantum(
  559. pixel->box_color.green),q);
  560. SetPixelBlue(annotate_image,ScaleShortToQuantum(
  561. pixel->box_color.blue),q);
  562. if ((annotate_info->stencil == ForegroundStencil) ||
  563. (annotate_info->stencil == OpaqueStencil))
  564. SetPixelAlpha(annotate_image,TransparentAlpha,q);
  565. }
  566. else
  567. {
  568. /*
  569. Set this pixel to the pen color.
  570. */
  571. SetPixelRed(annotate_image,ScaleShortToQuantum(
  572. pixel->pen_color.red),q);
  573. SetPixelGreen(annotate_image,ScaleShortToQuantum(
  574. pixel->pen_color.green),q);
  575. SetPixelBlue(annotate_image,ScaleShortToQuantum(
  576. pixel->pen_color.blue),q);
  577. if (annotate_info->stencil == BackgroundStencil)
  578. SetPixelAlpha(annotate_image,TransparentAlpha,q);
  579. }
  580. q+=GetPixelChannels(annotate_image);
  581. }
  582. if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
  583. break;
  584. }
  585. annotate_view=DestroyCacheView(annotate_view);
  586. XDestroyImage(annotate_ximage);
  587. /*
  588. Determine annotate geometry.
  589. */
  590. (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
  591. if ((width != (unsigned int) annotate_image->columns) ||
  592. (height != (unsigned int) annotate_image->rows))
  593. {
  594. char
  595. image_geometry[MagickPathExtent];
  596. /*
  597. Scale image.
  598. */
  599. (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u",
  600. width,height);
  601. (void) TransformImage(&annotate_image,(char *) NULL,image_geometry,
  602. exception);
  603. }
  604. if (annotate_info->degrees != 0.0)
  605. {
  606. Image
  607. *rotate_image;
  608. int
  609. rotations;
  610. double
  611. normalized_degrees;
  612. /*
  613. Rotate image.
  614. */
  615. rotate_image=RotateImage(annotate_image,annotate_info->degrees,exception);
  616. if (rotate_image == (Image *) NULL)
  617. return(MagickFalse);
  618. annotate_image=DestroyImage(annotate_image);
  619. annotate_image=rotate_image;
  620. /*
  621. Annotation is relative to the degree of rotation.
  622. */
  623. normalized_degrees=annotate_info->degrees;
  624. while (normalized_degrees < -45.0)
  625. normalized_degrees+=360.0;
  626. for (rotations=0; normalized_degrees > 45.0; rotations++)
  627. normalized_degrees-=90.0;
  628. switch (rotations % 4)
  629. {
  630. default:
  631. case 0:
  632. break;
  633. case 1:
  634. {
  635. /*
  636. Rotate 90 degrees.
  637. */
  638. x-=(int) annotate_image->columns/2;
  639. y+=(int) annotate_image->columns/2;
  640. break;
  641. }
  642. case 2:
  643. {
  644. /*
  645. Rotate 180 degrees.
  646. */
  647. x=x-(int) annotate_image->columns;
  648. break;
  649. }
  650. case 3:
  651. {
  652. /*
  653. Rotate 270 degrees.
  654. */
  655. x=x-(int) annotate_image->columns/2;
  656. y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
  657. break;
  658. }
  659. }
  660. }
  661. /*
  662. Composite text onto the image.
  663. */
  664. (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
  665. alpha_trait=image->alpha_trait;
  666. (void) CompositeImage(image,annotate_image,
  667. annotate_image->alpha_trait != UndefinedPixelTrait ? OverCompositeOp :
  668. CopyCompositeOp,MagickTrue,(ssize_t) x,(ssize_t) y,exception);
  669. image->alpha_trait=alpha_trait;
  670. annotate_image=DestroyImage(annotate_image);
  671. return(MagickTrue);
  672. }
  673. /*
  674. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  675. % %
  676. % %
  677. % %
  678. % X B e s t F o n t %
  679. % %
  680. % %
  681. % %
  682. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  683. %
  684. % XBestFont() returns the "best" font. "Best" is defined as a font specified
  685. % in the X resource database or a font such that the text width displayed
  686. % with the font does not exceed the specified maximum width.
  687. %
  688. % The format of the XBestFont method is:
  689. %
  690. % XFontStruct *XBestFont(Display *display,
  691. % const XResourceInfo *resource_info,const MagickBooleanType text_font)
  692. %
  693. % A description of each parameter follows:
  694. %
  695. % o font: XBestFont returns a pointer to a XFontStruct structure.
  696. %
  697. % o display: Specifies a connection to an X server; returned from
  698. % XOpenDisplay.
  699. %
  700. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  701. %
  702. % o text_font: True is font should be mono-spaced (typewriter style).
  703. %
  704. */
  705. static char **FontToList(char *font)
  706. {
  707. char
  708. **fontlist;
  709. register char
  710. *p,
  711. *q;
  712. register int
  713. i;
  714. unsigned int
  715. fonts;
  716. if (font == (char *) NULL)
  717. return((char **) NULL);
  718. /*
  719. Convert string to an ASCII list.
  720. */
  721. fonts=1U;
  722. for (p=font; *p != '\0'; p++)
  723. if ((*p == ':') || (*p == ';') || (*p == ','))
  724. fonts++;
  725. fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
  726. if (fontlist == (char **) NULL)
  727. {
  728. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font);
  729. return((char **) NULL);
  730. }
  731. p=font;
  732. for (i=0; i < (int) fonts; i++)
  733. {
  734. for (q=p; *q != '\0'; q++)
  735. if ((*q == ':') || (*q == ';') || (*q == ','))
  736. break;
  737. fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
  738. sizeof(*fontlist[i]));
  739. if (fontlist[i] == (char *) NULL)
  740. {
  741. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font);
  742. return((char **) NULL);
  743. }
  744. (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
  745. p=q+1;
  746. }
  747. fontlist[i]=(char *) NULL;
  748. return(fontlist);
  749. }
  750. MagickPrivate XFontStruct *XBestFont(Display *display,
  751. const XResourceInfo *resource_info,const MagickBooleanType text_font)
  752. {
  753. static const char
  754. *Fonts[]=
  755. {
  756. "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
  757. "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
  758. "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
  759. "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
  760. "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
  761. "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
  762. "variable",
  763. "fixed",
  764. (char *) NULL
  765. },
  766. *TextFonts[]=
  767. {
  768. "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
  769. "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
  770. "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
  771. "fixed",
  772. (char *) NULL
  773. };
  774. char
  775. *font_name;
  776. register const char
  777. **p;
  778. XFontStruct
  779. *font_info;
  780. font_info=(XFontStruct *) NULL;
  781. font_name=resource_info->font;
  782. if (text_font != MagickFalse)
  783. font_name=resource_info->text_font;
  784. if ((font_name != (char *) NULL) && (*font_name != '\0'))
  785. {
  786. char
  787. **fontlist;
  788. register int
  789. i;
  790. /*
  791. Load preferred font specified in the X resource database.
  792. */
  793. fontlist=FontToList(font_name);
  794. if (fontlist != (char **) NULL)
  795. {
  796. for (i=0; fontlist[i] != (char *) NULL; i++)
  797. {
  798. if (font_info == (XFontStruct *) NULL)
  799. font_info=XLoadQueryFont(display,fontlist[i]);
  800. fontlist[i]=DestroyString(fontlist[i]);
  801. }
  802. fontlist=(char **) RelinquishMagickMemory(fontlist);
  803. }
  804. if (font_info == (XFontStruct *) NULL)
  805. ThrowXWindowException(XServerError,"UnableToLoadFont",font_name);
  806. }
  807. /*
  808. Load fonts from list of fonts until one is found.
  809. */
  810. p=Fonts;
  811. if (text_font != MagickFalse)
  812. p=TextFonts;
  813. if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
  814. p++;
  815. while (*p != (char *) NULL)
  816. {
  817. if (font_info != (XFontStruct *) NULL)
  818. break;
  819. font_info=XLoadQueryFont(display,(char *) *p);
  820. p++;
  821. }
  822. return(font_info);
  823. }
  824. /*
  825. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  826. % %
  827. % %
  828. % %
  829. % X B e s t I c o n S i z e %
  830. % %
  831. % %
  832. % %
  833. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  834. %
  835. % XBestIconSize() returns the "best" icon size. "Best" is defined as an icon
  836. % size that maintains the aspect ratio of the image. If the window manager
  837. % has preferred icon sizes, one of the preferred sizes is used.
  838. %
  839. % The format of the XBestIconSize method is:
  840. %
  841. % void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
  842. %
  843. % A description of each parameter follows:
  844. %
  845. % o display: Specifies a connection to an X server; returned from
  846. % XOpenDisplay.
  847. %
  848. % o image: the image.
  849. %
  850. */
  851. MagickPrivate void XBestIconSize(Display *display,XWindowInfo *window,
  852. Image *image)
  853. {
  854. int
  855. i,
  856. number_sizes;
  857. double
  858. scale_factor;
  859. unsigned int
  860. height,
  861. icon_height,
  862. icon_width,
  863. width;
  864. Window
  865. root_window;
  866. XIconSize
  867. *icon_size,
  868. *size_list;
  869. /*
  870. Determine if the window manager has specified preferred icon sizes.
  871. */
  872. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  873. assert(display != (Display *) NULL);
  874. assert(window != (XWindowInfo *) NULL);
  875. assert(image != (Image *) NULL);
  876. window->width=MaxIconSize;
  877. window->height=MaxIconSize;
  878. icon_size=(XIconSize *) NULL;
  879. number_sizes=0;
  880. root_window=XRootWindow(display,window->screen);
  881. if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
  882. if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
  883. icon_size=size_list;
  884. if (icon_size == (XIconSize *) NULL)
  885. {
  886. /*
  887. Window manager does not restrict icon size.
  888. */
  889. icon_size=XAllocIconSize();
  890. if (icon_size == (XIconSize *) NULL)
  891. {
  892. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
  893. image->filename);
  894. return;
  895. }
  896. icon_size->min_width=1;
  897. icon_size->max_width=MaxIconSize;
  898. icon_size->min_height=1;
  899. icon_size->max_height=MaxIconSize;
  900. icon_size->width_inc=1;
  901. icon_size->height_inc=1;
  902. }
  903. /*
  904. Determine aspect ratio of image.
  905. */
  906. width=(unsigned int) image->columns;
  907. height=(unsigned int) image->rows;
  908. i=0;
  909. if (window->crop_geometry)
  910. (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
  911. /*
  912. Look for an icon size that maintains the aspect ratio of image.
  913. */
  914. scale_factor=(double) icon_size->max_width/width;
  915. if (scale_factor > ((double) icon_size->max_height/height))
  916. scale_factor=(double) icon_size->max_height/height;
  917. icon_width=(unsigned int) icon_size->min_width;
  918. while ((int) icon_width < icon_size->max_width)
  919. {
  920. if (icon_width >= (unsigned int) (scale_factor*width+0.5))
  921. break;
  922. icon_width+=icon_size->width_inc;
  923. }
  924. icon_height=(unsigned int) icon_size->min_height;
  925. while ((int) icon_height < icon_size->max_height)
  926. {
  927. if (icon_height >= (unsigned int) (scale_factor*height+0.5))
  928. break;
  929. icon_height+=icon_size->height_inc;
  930. }
  931. (void) XFree((void *) icon_size);
  932. window->width=icon_width;
  933. window->height=icon_height;
  934. }
  935. /*
  936. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  937. % %
  938. % %
  939. % %
  940. % X B e s t P i x e l %
  941. % %
  942. % %
  943. % %
  944. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  945. %
  946. % XBestPixel() returns a pixel from an array of pixels that is closest to the
  947. % requested color. If the color array is NULL, the colors are obtained from
  948. % the X server.
  949. %
  950. % The format of the XBestPixel method is:
  951. %
  952. % void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
  953. % unsigned int number_colors,XColor *color)
  954. %
  955. % A description of each parameter follows:
  956. %
  957. % o pixel: XBestPixel returns the pixel value closest to the requested
  958. % color.
  959. %
  960. % o display: Specifies a connection to an X server; returned from
  961. % XOpenDisplay.
  962. %
  963. % o colormap: Specifies the ID of the X server colormap.
  964. %
  965. % o colors: Specifies an array of XColor structures.
  966. %
  967. % o number_colors: Specifies the number of XColor structures in the
  968. % color definition array.
  969. %
  970. % o color: Specifies the desired RGB value to find in the colors array.
  971. %
  972. */
  973. MagickPrivate void XBestPixel(Display *display,const Colormap colormap,
  974. XColor *colors,unsigned int number_colors,XColor *color)
  975. {
  976. MagickBooleanType
  977. query_server;
  978. PixelInfo
  979. pixel;
  980. double
  981. min_distance;
  982. register double
  983. distance;
  984. register int
  985. i,
  986. j;
  987. Status
  988. status;
  989. /*
  990. Find closest representation for the requested RGB color.
  991. */
  992. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  993. assert(display != (Display *) NULL);
  994. assert(color != (XColor *) NULL);
  995. status=XAllocColor(display,colormap,color);
  996. if (status != False)
  997. return;
  998. query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
  999. if (query_server != MagickFalse)
  1000. {
  1001. /*
  1002. Read X server colormap.
  1003. */
  1004. colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
  1005. if (colors == (XColor *) NULL)
  1006. {
  1007. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
  1008. "...");
  1009. return;
  1010. }
  1011. for (i=0; i < (int) number_colors; i++)
  1012. colors[i].pixel=(size_t) i;
  1013. if (number_colors > 256)
  1014. number_colors=256;
  1015. (void) XQueryColors(display,colormap,colors,(int) number_colors);
  1016. }
  1017. min_distance=3.0*((double) QuantumRange+1.0)*((double)
  1018. QuantumRange+1.0);
  1019. j=0;
  1020. for (i=0; i < (int) number_colors; i++)
  1021. {
  1022. pixel.red=colors[i].red-(double) color->red;
  1023. distance=pixel.red*pixel.red;
  1024. if (distance > min_distance)
  1025. continue;
  1026. pixel.green=colors[i].green-(double) color->green;
  1027. distance+=pixel.green*pixel.green;
  1028. if (distance > min_distance)
  1029. continue;
  1030. pixel.blue=colors[i].blue-(double) color->blue;
  1031. distance+=pixel.blue*pixel.blue;
  1032. if (distance > min_distance)
  1033. continue;
  1034. min_distance=distance;
  1035. color->pixel=colors[i].pixel;
  1036. j=i;
  1037. }
  1038. (void) XAllocColor(display,colormap,&colors[j]);
  1039. if (query_server != MagickFalse)
  1040. colors=(XColor *) RelinquishMagickMemory(colors);
  1041. }
  1042. /*
  1043. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1044. % %
  1045. % %
  1046. % %
  1047. % X B e s t V i s u a l I n f o %
  1048. % %
  1049. % %
  1050. % %
  1051. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1052. %
  1053. % XBestVisualInfo() returns visual information for a visual that is the "best"
  1054. % the server supports. "Best" is defined as:
  1055. %
  1056. % 1. Restrict the visual list to those supported by the default screen.
  1057. %
  1058. % 2. If a visual type is specified, restrict the visual list to those of
  1059. % that type.
  1060. %
  1061. % 3. If a map type is specified, choose the visual that matches the id
  1062. % specified by the Standard Colormap.
  1063. %
  1064. % 4 From the list of visuals, choose one that can display the most
  1065. % simultaneous colors. If more than one visual can display the same
  1066. % number of simultaneous colors, one is chosen based on a rank.
  1067. %
  1068. % The format of the XBestVisualInfo method is:
  1069. %
  1070. % XVisualInfo *XBestVisualInfo(Display *display,
  1071. % XStandardColormap *map_info,XResourceInfo *resource_info)
  1072. %
  1073. % A description of each parameter follows:
  1074. %
  1075. % o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
  1076. % structure.
  1077. %
  1078. % o display: Specifies a connection to an X server; returned from
  1079. % XOpenDisplay.
  1080. %
  1081. % o map_info: If map_type is specified, this structure is initialized
  1082. % with info from the Standard Colormap.
  1083. %
  1084. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1085. %
  1086. */
  1087. MagickPrivate XVisualInfo *XBestVisualInfo(Display *display,
  1088. XStandardColormap *map_info,XResourceInfo *resource_info)
  1089. {
  1090. #define MaxStandardColormaps 7
  1091. #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
  1092. (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
  1093. visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
  1094. (unsigned long) visual_info->colormap_size),1UL << visual_info->depth)
  1095. char
  1096. *map_type,
  1097. *visual_type;
  1098. int
  1099. visual_mask;
  1100. register int
  1101. i;
  1102. size_t
  1103. one;
  1104. static int
  1105. number_visuals;
  1106. static XVisualInfo
  1107. visual_template;
  1108. XVisualInfo
  1109. *visual_info,
  1110. *visual_list;
  1111. /*
  1112. Restrict visual search by screen number.
  1113. */
  1114. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1115. assert(display != (Display *) NULL);
  1116. assert(map_info != (XStandardColormap *) NULL);
  1117. assert(resource_info != (XResourceInfo *) NULL);
  1118. map_type=resource_info->map_type;
  1119. visual_type=resource_info->visual_type;
  1120. visual_mask=VisualScreenMask;
  1121. visual_template.screen=XDefaultScreen(display);
  1122. visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
  1123. one=1;
  1124. if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
  1125. if (resource_info->colors <= (one << (size_t) visual_template.depth))
  1126. visual_mask|=VisualDepthMask;
  1127. if (visual_type != (char *) NULL)
  1128. {
  1129. /*
  1130. Restrict visual search by class or visual id.
  1131. */
  1132. if (LocaleCompare("staticgray",visual_type) == 0)
  1133. {
  1134. visual_mask|=VisualClassMask;
  1135. visual_template.klass=StaticGray;
  1136. }
  1137. else
  1138. if (LocaleCompare("grayscale",visual_type) == 0)
  1139. {
  1140. visual_mask|=VisualClassMask;
  1141. visual_template.klass=GrayScale;
  1142. }
  1143. else
  1144. if (LocaleCompare("staticcolor",visual_type) == 0)
  1145. {
  1146. visual_mask|=VisualClassMask;
  1147. visual_template.klass=StaticColor;
  1148. }
  1149. else
  1150. if (LocaleCompare("pseudocolor",visual_type) == 0)
  1151. {
  1152. visual_mask|=VisualClassMask;
  1153. visual_template.klass=PseudoColor;
  1154. }
  1155. else
  1156. if (LocaleCompare("truecolor",visual_type) == 0)
  1157. {
  1158. visual_mask|=VisualClassMask;
  1159. visual_template.klass=TrueColor;
  1160. }
  1161. else
  1162. if (LocaleCompare("directcolor",visual_type) == 0)
  1163. {
  1164. visual_mask|=VisualClassMask;
  1165. visual_template.klass=DirectColor;
  1166. }
  1167. else
  1168. if (LocaleCompare("default",visual_type) == 0)
  1169. {
  1170. visual_mask|=VisualIDMask;
  1171. visual_template.visualid=XVisualIDFromVisual(
  1172. XDefaultVisual(display,XDefaultScreen(display)));
  1173. }
  1174. else
  1175. if (isdigit((int) ((unsigned char) *visual_type)) != 0)
  1176. {
  1177. visual_mask|=VisualIDMask;
  1178. visual_template.visualid=
  1179. strtol(visual_type,(char **) NULL,0);
  1180. }
  1181. else
  1182. ThrowXWindowException(XServerError,
  1183. "UnrecognizedVisualSpecifier",visual_type);
  1184. }
  1185. /*
  1186. Get all visuals that meet our criteria so far.
  1187. */
  1188. number_visuals=0;
  1189. visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
  1190. &number_visuals);
  1191. visual_mask=VisualScreenMask | VisualIDMask;
  1192. if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
  1193. {
  1194. /*
  1195. Failed to get visual; try using the default visual.
  1196. */
  1197. ThrowXWindowException(XServerWarning,"UnableToGetVisual",visual_type);
  1198. visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
  1199. XDefaultScreen(display)));
  1200. visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
  1201. &number_visuals);
  1202. if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
  1203. return((XVisualInfo *) NULL);
  1204. ThrowXWindowException(XServerWarning,"UsingDefaultVisual",
  1205. XVisualClassName(visual_list->klass));
  1206. }
  1207. resource_info->color_recovery=MagickFalse;
  1208. if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
  1209. {
  1210. Atom
  1211. map_property;
  1212. char
  1213. map_name[MagickPathExtent];
  1214. int
  1215. j,
  1216. number_maps;
  1217. Status
  1218. status;
  1219. Window
  1220. root_window;
  1221. XStandardColormap
  1222. *map_list;
  1223. /*
  1224. Choose a visual associated with a standard colormap.
  1225. */
  1226. root_window=XRootWindow(display,XDefaultScreen(display));
  1227. status=False;
  1228. number_maps=0;
  1229. if (LocaleCompare(map_type,"list") != 0)
  1230. {
  1231. /*
  1232. User specified Standard Colormap.
  1233. */
  1234. (void) FormatLocaleString((char *) map_name,MagickPathExtent,
  1235. "RGB_%s_MAP",map_type);
  1236. LocaleUpper(map_name);
  1237. map_property=XInternAtom(display,(char *) map_name,MagickTrue);
  1238. if (map_property != (Atom) NULL)
  1239. status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
  1240. map_property);
  1241. }
  1242. else
  1243. {
  1244. static const char
  1245. *colormap[MaxStandardColormaps]=
  1246. {
  1247. "_HP_RGB_SMOOTH_MAP_LIST",
  1248. "RGB_BEST_MAP",
  1249. "RGB_DEFAULT_MAP",
  1250. "RGB_GRAY_MAP",
  1251. "RGB_RED_MAP",
  1252. "RGB_GREEN_MAP",
  1253. "RGB_BLUE_MAP",
  1254. };
  1255. /*
  1256. Choose a standard colormap from a list.
  1257. */
  1258. for (i=0; i < MaxStandardColormaps; i++)
  1259. {
  1260. map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
  1261. if (map_property == (Atom) NULL)
  1262. continue;
  1263. status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
  1264. map_property);
  1265. if (status != False)
  1266. break;
  1267. }
  1268. resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
  1269. }
  1270. if (status == False)
  1271. {
  1272. ThrowXWindowException(XServerError,"UnableToGetStandardColormap",
  1273. map_type);
  1274. return((XVisualInfo *) NULL);
  1275. }
  1276. /*
  1277. Search all Standard Colormaps and visuals for ids that match.
  1278. */
  1279. *map_info=map_list[0];
  1280. #if !defined(PRE_R4_ICCCM)
  1281. visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
  1282. for (i=0; i < number_maps; i++)
  1283. for (j=0; j < number_visuals; j++)
  1284. if (map_list[i].visualid ==
  1285. XVisualIDFromVisual(visual_list[j].visual))
  1286. {
  1287. *map_info=map_list[i];
  1288. visual_template.visualid=XVisualIDFromVisual(
  1289. visual_list[j].visual);
  1290. break;
  1291. }
  1292. if (map_info->visualid != visual_template.visualid)
  1293. {
  1294. ThrowXWindowException(XServerError,
  1295. "UnableToMatchVisualToStandardColormap",map_type);
  1296. return((XVisualInfo *) NULL);
  1297. }
  1298. #endif
  1299. if (map_info->colormap == (Colormap) NULL)
  1300. {
  1301. ThrowXWindowException(XServerError,"StandardColormapIsNotInitialized",
  1302. map_type);
  1303. return((XVisualInfo *) NULL);
  1304. }
  1305. (void) XFree((void *) map_list);
  1306. }
  1307. else
  1308. {
  1309. static const unsigned int
  1310. rank[]=
  1311. {
  1312. StaticGray,
  1313. GrayScale,
  1314. StaticColor,
  1315. DirectColor,
  1316. TrueColor,
  1317. PseudoColor
  1318. };
  1319. XVisualInfo
  1320. *p;
  1321. /*
  1322. Pick one visual that displays the most simultaneous colors.
  1323. */
  1324. visual_info=visual_list;
  1325. p=visual_list;
  1326. for (i=1; i < number_visuals; i++)
  1327. {
  1328. p++;
  1329. if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
  1330. visual_info=p;
  1331. else
  1332. if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
  1333. if (rank[p->klass] > rank[visual_info->klass])
  1334. visual_info=p;
  1335. }
  1336. visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
  1337. }
  1338. (void) XFree((void *) visual_list);
  1339. /*
  1340. Retrieve only one visual by its screen & id number.
  1341. */
  1342. visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
  1343. &number_visuals);
  1344. if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
  1345. return((XVisualInfo *) NULL);
  1346. return(visual_info);
  1347. }
  1348. /*
  1349. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1350. % %
  1351. % %
  1352. % %
  1353. % X C h e c k D e f i n e C u r s o r %
  1354. % %
  1355. % %
  1356. % %
  1357. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1358. %
  1359. % XCheckDefineCursor() prevents cursor changes on the root window.
  1360. %
  1361. % The format of the XXCheckDefineCursor method is:
  1362. %
  1363. % XCheckDefineCursor(display,window,cursor)
  1364. %
  1365. % A description of each parameter follows:
  1366. %
  1367. % o display: Specifies a connection to an X server; returned from
  1368. % XOpenDisplay.
  1369. %
  1370. % o window: the window.
  1371. %
  1372. % o cursor: the cursor.
  1373. %
  1374. */
  1375. MagickPrivate int XCheckDefineCursor(Display *display,Window window,
  1376. Cursor cursor)
  1377. {
  1378. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1379. assert(display != (Display *) NULL);
  1380. if (window == XRootWindow(display,XDefaultScreen(display)))
  1381. return(0);
  1382. return(XDefineCursor(display,window,cursor));
  1383. }
  1384. /*
  1385. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1386. % %
  1387. % %
  1388. % %
  1389. % X C h e c k R e f r e s h W i n d o w s %
  1390. % %
  1391. % %
  1392. % %
  1393. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1394. %
  1395. % XCheckRefreshWindows() checks the X server for exposure events for a
  1396. % particular window and updates the areassociated with the exposure event.
  1397. %
  1398. % The format of the XCheckRefreshWindows method is:
  1399. %
  1400. % void XCheckRefreshWindows(Display *display,XWindows *windows)
  1401. %
  1402. % A description of each parameter follows:
  1403. %
  1404. % o display: Specifies a connection to an X server; returned from
  1405. % XOpenDisplay.
  1406. %
  1407. % o windows: Specifies a pointer to a XWindows structure.
  1408. %
  1409. */
  1410. MagickPrivate void XCheckRefreshWindows(Display *display,XWindows *windows)
  1411. {
  1412. Window
  1413. id;
  1414. XEvent
  1415. event;
  1416. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1417. assert(display != (Display *) NULL);
  1418. assert(windows != (XWindows *) NULL);
  1419. XDelay(display,SuspendTime);
  1420. id=windows->command.id;
  1421. while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
  1422. (void) XCommandWidget(display,windows,(char const **) NULL,&event);
  1423. id=windows->image.id;
  1424. while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
  1425. XRefreshWindow(display,&windows->image,&event);
  1426. XDelay(display,SuspendTime << 1);
  1427. id=windows->command.id;
  1428. while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
  1429. (void) XCommandWidget(display,windows,(char const **) NULL,&event);
  1430. id=windows->image.id;
  1431. while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
  1432. XRefreshWindow(display,&windows->image,&event);
  1433. }
  1434. /*
  1435. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1436. % %
  1437. % %
  1438. % %
  1439. % X C l i e n t M e s s a g e %
  1440. % %
  1441. % %
  1442. % %
  1443. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1444. %
  1445. % XClientMessage() sends a reason to a window with XSendEvent. The reason is
  1446. % initialized with a particular protocol type and atom.
  1447. %
  1448. % The format of the XClientMessage function is:
  1449. %
  1450. % XClientMessage(display,window,protocol,reason,timestamp)
  1451. %
  1452. % A description of each parameter follows:
  1453. %
  1454. % o display: Specifies a pointer to the Display structure; returned from
  1455. % XOpenDisplay.
  1456. %
  1457. % o window: Specifies a pointer to a Window structure.
  1458. %
  1459. % o protocol: Specifies an atom value.
  1460. %
  1461. % o reason: Specifies an atom value which is the reason to send.
  1462. %
  1463. % o timestamp: Specifies a value of type Time.
  1464. %
  1465. */
  1466. MagickPrivate void XClientMessage(Display *display,const Window window,
  1467. const Atom protocol,const Atom reason,const Time timestamp)
  1468. {
  1469. XClientMessageEvent
  1470. client_event;
  1471. assert(display != (Display *) NULL);
  1472. (void) memset(&client_event,0,sizeof(client_event));
  1473. client_event.type=ClientMessage;
  1474. client_event.window=window;
  1475. client_event.message_type=protocol;
  1476. client_event.format=32;
  1477. client_event.data.l[0]=(long) reason;
  1478. client_event.data.l[1]=(long) timestamp;
  1479. (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *)
  1480. &client_event);
  1481. }
  1482. /*
  1483. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1484. % %
  1485. % %
  1486. % %
  1487. + X C l i e n t W i n d o w %
  1488. % %
  1489. % %
  1490. % %
  1491. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1492. %
  1493. % XClientWindow() finds a window, at or below the specified window, which has
  1494. % a WM_STATE property. If such a window is found, it is returned, otherwise
  1495. % the argument window is returned.
  1496. %
  1497. % The format of the XClientWindow function is:
  1498. %
  1499. % client_window=XClientWindow(display,target_window)
  1500. %
  1501. % A description of each parameter follows:
  1502. %
  1503. % o client_window: XClientWindow returns a window, at or below the specified
  1504. % window, which has a WM_STATE property otherwise the argument
  1505. % target_window is returned.
  1506. %
  1507. % o display: Specifies a pointer to the Display structure; returned from
  1508. % XOpenDisplay.
  1509. %
  1510. % o target_window: Specifies the window to find a WM_STATE property.
  1511. %
  1512. */
  1513. static Window XClientWindow(Display *display,Window target_window)
  1514. {
  1515. Atom
  1516. state,
  1517. type;
  1518. int
  1519. format;
  1520. Status
  1521. status;
  1522. unsigned char
  1523. *data;
  1524. unsigned long
  1525. after,
  1526. number_items;
  1527. Window
  1528. client_window;
  1529. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1530. assert(display != (Display *) NULL);
  1531. state=XInternAtom(display,"WM_STATE",MagickTrue);
  1532. if (state == (Atom) NULL)
  1533. return(target_window);
  1534. type=(Atom) NULL;
  1535. status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse,
  1536. (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
  1537. if ((status == Success) && (type != (Atom) NULL))
  1538. return(target_window);
  1539. client_window=XWindowByProperty(display,target_window,state);
  1540. if (client_window == (Window) NULL)
  1541. return(target_window);
  1542. return(client_window);
  1543. }
  1544. /*
  1545. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1546. % %
  1547. % %
  1548. % %
  1549. + X C o m p o n e n t T e r m i n u s %
  1550. % %
  1551. % %
  1552. % %
  1553. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1554. %
  1555. % XComponentTerminus() destroys the module component.
  1556. %
  1557. % The format of the XComponentTerminus method is:
  1558. %
  1559. % XComponentTerminus(void)
  1560. %
  1561. */
  1562. MagickPrivate void XComponentTerminus(void)
  1563. {
  1564. DestroyXResources();
  1565. }
  1566. /*
  1567. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1568. % %
  1569. % %
  1570. % %
  1571. % X C o n f i g u r e I m a g e C o l o r m a p %
  1572. % %
  1573. % %
  1574. % %
  1575. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1576. %
  1577. % XConfigureImageColormap() creates a new X colormap.
  1578. %
  1579. % The format of the XConfigureImageColormap method is:
  1580. %
  1581. % void XConfigureImageColormap(Display *display,
  1582. % XResourceInfo *resource_info,XWindows *windows,Image *image,
  1583. % ExceptionInfo *exception)
  1584. %
  1585. % A description of each parameter follows:
  1586. %
  1587. % o display: Specifies a connection to an X server; returned from
  1588. % XOpenDisplay.
  1589. %
  1590. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1591. %
  1592. % o windows: Specifies a pointer to a XWindows structure.
  1593. %
  1594. % o image: the image.
  1595. %
  1596. % o exception: return any errors or warnings in this structure.
  1597. %
  1598. */
  1599. MagickPrivate void XConfigureImageColormap(Display *display,
  1600. XResourceInfo *resource_info,XWindows *windows,Image *image,
  1601. ExceptionInfo *exception)
  1602. {
  1603. Colormap
  1604. colormap;
  1605. /*
  1606. Make standard colormap.
  1607. */
  1608. XSetCursorState(display,windows,MagickTrue);
  1609. XCheckRefreshWindows(display,windows);
  1610. XMakeStandardColormap(display,windows->visual_info,resource_info,image,
  1611. windows->map_info,windows->pixel_info,exception);
  1612. colormap=windows->map_info->colormap;
  1613. (void) XSetWindowColormap(display,windows->image.id,colormap);
  1614. (void) XSetWindowColormap(display,windows->command.id,colormap);
  1615. (void) XSetWindowColormap(display,windows->widget.id,colormap);
  1616. if (windows->magnify.mapped != MagickFalse)
  1617. (void) XSetWindowColormap(display,windows->magnify.id,colormap);
  1618. if (windows->pan.mapped != MagickFalse)
  1619. (void) XSetWindowColormap(display,windows->pan.id,colormap);
  1620. XSetCursorState(display,windows,MagickFalse);
  1621. XClientMessage(display,windows->image.id,windows->im_protocols,
  1622. windows->im_update_colormap,CurrentTime);
  1623. }
  1624. /*
  1625. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1626. % %
  1627. % %
  1628. % %
  1629. % X C o n s t r a i n W i n d o w P o s i t i o n %
  1630. % %
  1631. % %
  1632. % %
  1633. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1634. %
  1635. % XConstrainWindowPosition() assures a window is positioned within the X
  1636. % server boundaries.
  1637. %
  1638. % The format of the XConstrainWindowPosition method is:
  1639. %
  1640. % void XConstrainWindowPosition(Display *display,XWindowInfo *window_info)
  1641. %
  1642. % A description of each parameter follows:
  1643. %
  1644. % o display: Specifies a pointer to the Display structure; returned from
  1645. % XOpenDisplay.
  1646. %
  1647. % o window_info: Specifies a pointer to a XWindowInfo structure.
  1648. %
  1649. */
  1650. MagickPrivate void XConstrainWindowPosition(Display *display,
  1651. XWindowInfo *window_info)
  1652. {
  1653. int
  1654. limit;
  1655. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1656. assert(display != (Display *) NULL);
  1657. assert(window_info != (XWindowInfo *) NULL);
  1658. limit=XDisplayWidth(display,window_info->screen)-window_info->width;
  1659. if (window_info->x < 0)
  1660. window_info->x=0;
  1661. else
  1662. if (window_info->x > (int) limit)
  1663. window_info->x=(int) limit;
  1664. limit=XDisplayHeight(display,window_info->screen)-window_info->height;
  1665. if (window_info->y < 0)
  1666. window_info->y=0;
  1667. else
  1668. if (window_info->y > limit)
  1669. window_info->y=limit;
  1670. }
  1671. /*
  1672. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1673. % %
  1674. % %
  1675. % %
  1676. % X D e l a y %
  1677. % %
  1678. % %
  1679. % %
  1680. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1681. %
  1682. % XDelay() suspends program execution for the number of milliseconds
  1683. % specified.
  1684. %
  1685. % The format of the Delay method is:
  1686. %
  1687. % void XDelay(Display *display,const size_t milliseconds)
  1688. %
  1689. % A description of each parameter follows:
  1690. %
  1691. % o display: Specifies a pointer to the Display structure; returned from
  1692. % XOpenDisplay.
  1693. %
  1694. % o milliseconds: Specifies the number of milliseconds to delay before
  1695. % returning.
  1696. %
  1697. */
  1698. MagickPrivate void XDelay(Display *display,const size_t milliseconds)
  1699. {
  1700. assert(display != (Display *) NULL);
  1701. (void) XFlush(display);
  1702. MagickDelay(milliseconds);
  1703. }
  1704. /*
  1705. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1706. % %
  1707. % %
  1708. % %
  1709. % X D e s t r o y R e s o u r c e I n f o %
  1710. % %
  1711. % %
  1712. % %
  1713. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1714. %
  1715. % XDestroyResourceInfo() frees memory associated with the XResourceInfo
  1716. % structure.
  1717. %
  1718. % The format of the XDestroyResourceInfo method is:
  1719. %
  1720. % void XDestroyResourceInfo(XResourceInfo *resource_info)
  1721. %
  1722. % A description of each parameter follows:
  1723. %
  1724. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1725. %
  1726. */
  1727. MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info)
  1728. {
  1729. if (resource_info->image_geometry != (char *) NULL)
  1730. resource_info->image_geometry=(char *)
  1731. RelinquishMagickMemory(resource_info->image_geometry);
  1732. if (resource_info->quantize_info != (QuantizeInfo *) NULL)
  1733. resource_info->quantize_info=DestroyQuantizeInfo(
  1734. resource_info->quantize_info);
  1735. if (resource_info->client_name != (char *) NULL)
  1736. resource_info->client_name=(char *)
  1737. RelinquishMagickMemory(resource_info->client_name);
  1738. if (resource_info->name != (char *) NULL)
  1739. resource_info->name=DestroyString(resource_info->name);
  1740. (void) memset(resource_info,0,sizeof(*resource_info));
  1741. }
  1742. /*
  1743. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1744. % %
  1745. % %
  1746. % %
  1747. % X D e s t r o y W i n d o w C o l o r s %
  1748. % %
  1749. % %
  1750. % %
  1751. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1752. %
  1753. % XDestroyWindowColors() frees X11 color resources previously saved on a
  1754. % window by XRetainWindowColors or programs like xsetroot.
  1755. %
  1756. % The format of the XDestroyWindowColors method is:
  1757. %
  1758. % void XDestroyWindowColors(Display *display,Window window)
  1759. %
  1760. % A description of each parameter follows:
  1761. %
  1762. % o display: Specifies a connection to an X server; returned from
  1763. % XOpenDisplay.
  1764. %
  1765. % o window: Specifies a pointer to a Window structure.
  1766. %
  1767. */
  1768. MagickPrivate void XDestroyWindowColors(Display *display,Window window)
  1769. {
  1770. Atom
  1771. property,
  1772. type;
  1773. int
  1774. format;
  1775. Status
  1776. status;
  1777. unsigned char
  1778. *data;
  1779. unsigned long
  1780. after,
  1781. length;
  1782. /*
  1783. If there are previous resources on the root window, destroy them.
  1784. */
  1785. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1786. assert(display != (Display *) NULL);
  1787. property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
  1788. if (property == (Atom) NULL)
  1789. {
  1790. ThrowXWindowException(XServerError,"UnableToCreateProperty",
  1791. "_XSETROOT_ID");
  1792. return;
  1793. }
  1794. status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue,
  1795. (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
  1796. if (status != Success)
  1797. return;
  1798. if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
  1799. {
  1800. (void) XKillClient(display,(XID) (*((Pixmap *) data)));
  1801. (void) XDeleteProperty(display,window,property);
  1802. }
  1803. if (type != None)
  1804. (void) XFree((void *) data);
  1805. }
  1806. /*
  1807. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1808. % %
  1809. % %
  1810. % %
  1811. % X D i s p l a y I m a g e I n f o %
  1812. % %
  1813. % %
  1814. % %
  1815. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1816. %
  1817. % XDisplayImageInfo() displays information about an X image.
  1818. %
  1819. % The format of the XDisplayImageInfo method is:
  1820. %
  1821. % void XDisplayImageInfo(Display *display,
  1822. % const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
  1823. % Image *image,ExceptionInfo *exception)
  1824. %
  1825. % A description of each parameter follows:
  1826. %
  1827. % o display: Specifies a connection to an X server; returned from
  1828. % XOpenDisplay.
  1829. %
  1830. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1831. %
  1832. % o windows: Specifies a pointer to a XWindows structure.
  1833. %
  1834. % o undo_image: the undo image.
  1835. %
  1836. % o image: the image.
  1837. %
  1838. % o exception: return any errors or warnings in this structure.
  1839. %
  1840. */
  1841. MagickPrivate void XDisplayImageInfo(Display *display,
  1842. const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
  1843. Image *image,ExceptionInfo *exception)
  1844. {
  1845. char
  1846. filename[MagickPathExtent],
  1847. *text,
  1848. **textlist;
  1849. FILE
  1850. *file;
  1851. int
  1852. unique_file;
  1853. register ssize_t
  1854. i;
  1855. size_t
  1856. number_pixels;
  1857. ssize_t
  1858. bytes;
  1859. unsigned int
  1860. levels;
  1861. /*
  1862. Write info about the X server to a file.
  1863. */
  1864. assert(display != (Display *) NULL);
  1865. assert(resource_info != (XResourceInfo *) NULL);
  1866. assert(windows != (XWindows *) NULL);
  1867. assert(image != (Image *) NULL);
  1868. if (image->debug)
  1869. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  1870. file=(FILE *) NULL;
  1871. unique_file=AcquireUniqueFileResource(filename);
  1872. if (unique_file != -1)
  1873. file=fdopen(unique_file,"w");
  1874. if ((unique_file == -1) || (file == (FILE *) NULL))
  1875. {
  1876. XNoticeWidget(display,windows,"Unable to display image info",filename);
  1877. return;
  1878. }
  1879. if (resource_info->gamma_correct != MagickFalse)
  1880. if (resource_info->display_gamma != (char *) NULL)
  1881. (void) FormatLocaleFile(file,"Display\n gamma: %s\n\n",
  1882. resource_info->display_gamma);
  1883. /*
  1884. Write info about the X image to a file.
  1885. */
  1886. (void) FormatLocaleFile(file,"X\n visual: %s\n",
  1887. XVisualClassName((int) windows->image.storage_class));
  1888. (void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth);
  1889. if (windows->visual_info->colormap_size != 0)
  1890. (void) FormatLocaleFile(file," colormap size: %d\n",
  1891. windows->visual_info->colormap_size);
  1892. if (resource_info->colormap== SharedColormap)
  1893. (void) FormatLocaleFile(file," colormap type: Shared\n");
  1894. else
  1895. (void) FormatLocaleFile(file," colormap type: Private\n");
  1896. (void) FormatLocaleFile(file," geometry: %dx%d\n",
  1897. windows->image.ximage->width,windows->image.ximage->height);
  1898. if (windows->image.crop_geometry != (char *) NULL)
  1899. (void) FormatLocaleFile(file," crop geometry: %s\n",
  1900. windows->image.crop_geometry);
  1901. if (windows->image.pixmap == (Pixmap) NULL)
  1902. (void) FormatLocaleFile(file," type: X Image\n");
  1903. else
  1904. (void) FormatLocaleFile(file," type: Pixmap\n");
  1905. if (windows->image.shape != MagickFalse)
  1906. (void) FormatLocaleFile(file," non-rectangular shape: True\n");
  1907. else
  1908. (void) FormatLocaleFile(file," non-rectangular shape: False\n");
  1909. if (windows->image.shared_memory != MagickFalse)
  1910. (void) FormatLocaleFile(file," shared memory: True\n");
  1911. else
  1912. (void) FormatLocaleFile(file," shared memory: False\n");
  1913. (void) FormatLocaleFile(file,"\n");
  1914. if (resource_info->font != (char *) NULL)
  1915. (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
  1916. if (resource_info->text_font != (char *) NULL)
  1917. (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font);
  1918. /*
  1919. Write info about the undo cache to a file.
  1920. */
  1921. bytes=0;
  1922. for (levels=0; undo_image != (Image *) NULL; levels++)
  1923. {
  1924. number_pixels=undo_image->list->columns*undo_image->list->rows;
  1925. bytes+=number_pixels*sizeof(PixelInfo);
  1926. undo_image=GetPreviousImageInList(undo_image);
  1927. }
  1928. (void) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels);
  1929. (void) FormatLocaleFile(file," bytes: %.20gmb\n",(double)
  1930. ((bytes+(1 << 19)) >> 20));
  1931. (void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double)
  1932. resource_info->undo_cache);
  1933. /*
  1934. Write info about the image to a file.
  1935. */
  1936. (void) IdentifyImage(image,file,MagickTrue,exception);
  1937. (void) fclose(file);
  1938. text=FileToString(filename,~0UL,exception);
  1939. (void) RelinquishUniqueFileResource(filename);
  1940. if (text == (char *) NULL)
  1941. {
  1942. XNoticeWidget(display,windows,"MemoryAllocationFailed",
  1943. "UnableToDisplayImageInfo");
  1944. return;
  1945. }
  1946. textlist=StringToList(text);
  1947. if (textlist != (char **) NULL)
  1948. {
  1949. char
  1950. title[MagickPathExtent];
  1951. /*
  1952. Display information about the image in the Text View widget.
  1953. */
  1954. (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  1955. (void) FormatLocaleString(title,MagickPathExtent,"Image Info: %s",
  1956. image->filename);
  1957. XTextViewWidget(display,resource_info,windows,MagickTrue,title,
  1958. (char const **) textlist);
  1959. for (i=0; textlist[i] != (char *) NULL; i++)
  1960. textlist[i]=DestroyString(textlist[i]);
  1961. textlist=(char **) RelinquishMagickMemory(textlist);
  1962. }
  1963. text=DestroyString(text);
  1964. }
  1965. /*
  1966. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1967. % %
  1968. % %
  1969. % %
  1970. + X D i t h e r I m a g e %
  1971. % %
  1972. % %
  1973. % %
  1974. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1975. %
  1976. % XDitherImage() dithers the reference image as required by the HP Color
  1977. % Recovery algorithm. The color values are quantized to 3 bits of red and
  1978. % green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X
  1979. % standard colormap.
  1980. %
  1981. % The format of the XDitherImage method is:
  1982. %
  1983. % void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
  1984. %
  1985. % A description of each parameter follows:
  1986. %
  1987. % o image: the image.
  1988. %
  1989. % o ximage: Specifies a pointer to a XImage structure; returned from
  1990. % XCreateImage.
  1991. %
  1992. % o exception: return any errors or warnings in this structure.
  1993. %
  1994. */
  1995. static void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
  1996. {
  1997. static const short int
  1998. dither_red[2][16]=
  1999. {
  2000. {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
  2001. { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
  2002. },
  2003. dither_green[2][16]=
  2004. {
  2005. { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
  2006. {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
  2007. },
  2008. dither_blue[2][16]=
  2009. {
  2010. { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
  2011. { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
  2012. };
  2013. CacheView
  2014. *image_view;
  2015. int
  2016. value,
  2017. y;
  2018. PixelInfo
  2019. color;
  2020. register char
  2021. *q;
  2022. register const Quantum
  2023. *p;
  2024. register int
  2025. i,
  2026. j,
  2027. x;
  2028. unsigned int
  2029. scanline_pad;
  2030. register size_t
  2031. pixel;
  2032. unsigned char
  2033. *blue_map[2][16],
  2034. *green_map[2][16],
  2035. *red_map[2][16];
  2036. /*
  2037. Allocate and initialize dither maps.
  2038. */
  2039. for (i=0; i < 2; i++)
  2040. for (j=0; j < 16; j++)
  2041. {
  2042. red_map[i][j]=(unsigned char *) AcquireCriticalMemory(256UL*
  2043. sizeof(*red_map));
  2044. green_map[i][j]=(unsigned char *) AcquireCriticalMemory(256UL*
  2045. sizeof(*green_map));
  2046. blue_map[i][j]=(unsigned char *) AcquireCriticalMemory(256UL*
  2047. sizeof(*blue_map));
  2048. }
  2049. /*
  2050. Initialize dither tables.
  2051. */
  2052. for (i=0; i < 2; i++)
  2053. for (j=0; j < 16; j++)
  2054. for (x=0; x < 256; x++)
  2055. {
  2056. value=x-16;
  2057. if (x < 48)
  2058. value=x/2+8;
  2059. value+=dither_red[i][j];
  2060. red_map[i][j][x]=(unsigned char)
  2061. ((value < 0) ? 0 : (value > 255) ? 255 : value);
  2062. value=x-16;
  2063. if (x < 48)
  2064. value=x/2+8;
  2065. value+=dither_green[i][j];
  2066. green_map[i][j][x]=(unsigned char)
  2067. ((value < 0) ? 0 : (value > 255) ? 255 : value);
  2068. value=x-32;
  2069. if (x < 112)
  2070. value=x/2+24;
  2071. value+=((size_t) dither_blue[i][j] << 1);
  2072. blue_map[i][j][x]=(unsigned char)
  2073. ((value < 0) ? 0 : (value > 255) ? 255 : value);
  2074. }
  2075. /*
  2076. Dither image.
  2077. */
  2078. scanline_pad=(unsigned int) (ximage->bytes_per_line-
  2079. ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
  2080. i=0;
  2081. j=0;
  2082. q=ximage->data;
  2083. image_view=AcquireVirtualCacheView(image,exception);
  2084. for (y=0; y < (int) image->rows; y++)
  2085. {
  2086. p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
  2087. exception);
  2088. if (p == (const Quantum *) NULL)
  2089. break;
  2090. for (x=0; x < (int) image->columns; x++)
  2091. {
  2092. color.red=(double) ClampToQuantum((double) (red_map[i][j][
  2093. (int) ScaleQuantumToChar(GetPixelRed(image,p))] << 8));
  2094. color.green=(double) ClampToQuantum((double) (green_map[i][j][
  2095. (int) ScaleQuantumToChar(GetPixelGreen(image,p))] << 8));
  2096. color.blue=(double) ClampToQuantum((double) (blue_map[i][j][
  2097. (int) ScaleQuantumToChar(GetPixelBlue(image,p))] << 8));
  2098. pixel=(size_t) (((size_t) color.red & 0xe0) |
  2099. (((size_t) color.green & 0xe0) >> 3) |
  2100. (((size_t) color.blue & 0xc0) >> 6));
  2101. *q++=(char) pixel;
  2102. p+=GetPixelChannels(image);
  2103. j++;
  2104. if (j == 16)
  2105. j=0;
  2106. }
  2107. q+=scanline_pad;
  2108. i++;
  2109. if (i == 2)
  2110. i=0;
  2111. }
  2112. image_view=DestroyCacheView(image_view);
  2113. /*
  2114. Free allocated memory.
  2115. */
  2116. for (i=0; i < 2; i++)
  2117. for (j=0; j < 16; j++)
  2118. {
  2119. green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]);
  2120. blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]);
  2121. red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]);
  2122. }
  2123. }
  2124. /*
  2125. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2126. % %
  2127. % %
  2128. % %
  2129. % X D r a w I m a g e %
  2130. % %
  2131. % %
  2132. % %
  2133. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2134. %
  2135. % XDrawImage() draws a line on the image.
  2136. %
  2137. % The format of the XDrawImage method is:
  2138. %
  2139. % MagickBooleanType XDrawImage(Display *display,const XPixelInfo *pixel,
  2140. % XDrawInfo *draw_info,Image *image,ExceptionInfo *exception)
  2141. %
  2142. % A description of each parameter follows:
  2143. %
  2144. % o display: Specifies a connection to an X server; returned from
  2145. % XOpenDisplay.
  2146. %
  2147. % o pixel: Specifies a pointer to a XPixelInfo structure.
  2148. %
  2149. % o draw_info: Specifies a pointer to a XDrawInfo structure.
  2150. %
  2151. % o image: the image.
  2152. %
  2153. % o exception: return any errors or warnings in this structure.
  2154. %
  2155. */
  2156. MagickPrivate MagickBooleanType XDrawImage(Display *display,
  2157. const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image,
  2158. ExceptionInfo *exception)
  2159. {
  2160. CacheView
  2161. *draw_view;
  2162. GC
  2163. draw_context;
  2164. Image
  2165. *draw_image;
  2166. int
  2167. x,
  2168. y;
  2169. PixelTrait
  2170. alpha_trait;
  2171. Pixmap
  2172. draw_pixmap;
  2173. unsigned int
  2174. depth,
  2175. height,
  2176. width;
  2177. Window
  2178. root_window;
  2179. XGCValues
  2180. context_values;
  2181. XImage
  2182. *draw_ximage;
  2183. /*
  2184. Initialize drawd image.
  2185. */
  2186. assert(display != (Display *) NULL);
  2187. assert(pixel != (XPixelInfo *) NULL);
  2188. assert(draw_info != (XDrawInfo *) NULL);
  2189. assert(image != (Image *) NULL);
  2190. if (image->debug != MagickFalse)
  2191. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2192. /*
  2193. Initialize drawd pixmap.
  2194. */
  2195. root_window=XRootWindow(display,XDefaultScreen(display));
  2196. depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
  2197. draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
  2198. draw_info->height,depth);
  2199. if (draw_pixmap == (Pixmap) NULL)
  2200. return(MagickFalse);
  2201. /*
  2202. Initialize graphics info.
  2203. */
  2204. context_values.background=(size_t) (~0);
  2205. context_values.foreground=0;
  2206. context_values.line_width=(int) draw_info->line_width;
  2207. draw_context=XCreateGC(display,root_window,(size_t)
  2208. (GCBackground | GCForeground | GCLineWidth),&context_values);
  2209. if (draw_context == (GC) NULL)
  2210. return(MagickFalse);
  2211. /*
  2212. Clear pixmap.
  2213. */
  2214. (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
  2215. draw_info->height);
  2216. /*
  2217. Draw line to pixmap.
  2218. */
  2219. (void) XSetBackground(display,draw_context,0);
  2220. (void) XSetForeground(display,draw_context,(size_t) (~0));
  2221. if (draw_info->stipple != (Pixmap) NULL)
  2222. {
  2223. (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
  2224. (void) XSetStipple(display,draw_context,draw_info->stipple);
  2225. }
  2226. switch (draw_info->element)
  2227. {
  2228. case PointElement:
  2229. default:
  2230. {
  2231. (void) XDrawLines(display,draw_pixmap,draw_context,
  2232. draw_info->coordinate_info,(int) draw_info->number_coordinates,
  2233. CoordModeOrigin);
  2234. break;
  2235. }
  2236. case LineElement:
  2237. {
  2238. (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
  2239. draw_info->line_info.y1,draw_info->line_info.x2,
  2240. draw_info->line_info.y2);
  2241. break;
  2242. }
  2243. case RectangleElement:
  2244. {
  2245. (void) XDrawRectangle(display,draw_pixmap,draw_context,
  2246. (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
  2247. (unsigned int) draw_info->rectangle_info.width,
  2248. (unsigned int) draw_info->rectangle_info.height);
  2249. break;
  2250. }
  2251. case FillRectangleElement:
  2252. {
  2253. (void) XFillRectangle(display,draw_pixmap,draw_context,
  2254. (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
  2255. (unsigned int) draw_info->rectangle_info.width,
  2256. (unsigned int) draw_info->rectangle_info.height);
  2257. break;
  2258. }
  2259. case CircleElement:
  2260. case EllipseElement:
  2261. {
  2262. (void) XDrawArc(display,draw_pixmap,draw_context,
  2263. (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
  2264. (unsigned int) draw_info->rectangle_info.width,
  2265. (unsigned int) draw_info->rectangle_info.height,0,360*64);
  2266. break;
  2267. }
  2268. case FillCircleElement:
  2269. case FillEllipseElement:
  2270. {
  2271. (void) XFillArc(display,draw_pixmap,draw_context,
  2272. (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
  2273. (unsigned int) draw_info->rectangle_info.width,
  2274. (unsigned int) draw_info->rectangle_info.height,0,360*64);
  2275. break;
  2276. }
  2277. case PolygonElement:
  2278. {
  2279. XPoint
  2280. *coordinate_info;
  2281. coordinate_info=draw_info->coordinate_info;
  2282. (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
  2283. (int) draw_info->number_coordinates,CoordModeOrigin);
  2284. (void) XDrawLine(display,draw_pixmap,draw_context,
  2285. coordinate_info[draw_info->number_coordinates-1].x,
  2286. coordinate_info[draw_info->number_coordinates-1].y,
  2287. coordinate_info[0].x,coordinate_info[0].y);
  2288. break;
  2289. }
  2290. case FillPolygonElement:
  2291. {
  2292. (void) XFillPolygon(display,draw_pixmap,draw_context,
  2293. draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex,
  2294. CoordModeOrigin);
  2295. break;
  2296. }
  2297. }
  2298. (void) XFreeGC(display,draw_context);
  2299. /*
  2300. Initialize X image.
  2301. */
  2302. draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
  2303. draw_info->height,AllPlanes,ZPixmap);
  2304. if (draw_ximage == (XImage *) NULL)
  2305. return(MagickFalse);
  2306. (void) XFreePixmap(display,draw_pixmap);
  2307. /*
  2308. Initialize draw image.
  2309. */
  2310. draw_image=AcquireImage((ImageInfo *) NULL,exception);
  2311. if (draw_image == (Image *) NULL)
  2312. return(MagickFalse);
  2313. draw_image->columns=draw_info->width;
  2314. draw_image->rows=draw_info->height;
  2315. /*
  2316. Transfer drawn X image to image.
  2317. */
  2318. width=(unsigned int) image->columns;
  2319. height=(unsigned int) image->rows;
  2320. x=0;
  2321. y=0;
  2322. (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
  2323. (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
  2324. (ssize_t) y,&draw_image->background_color,exception);
  2325. if (SetImageStorageClass(draw_image,DirectClass,exception) == MagickFalse)
  2326. return(MagickFalse);
  2327. draw_image->alpha_trait=BlendPixelTrait;
  2328. draw_view=AcquireAuthenticCacheView(draw_image,exception);
  2329. for (y=0; y < (int) draw_image->rows; y++)
  2330. {
  2331. register int
  2332. x;
  2333. register Quantum
  2334. *magick_restrict q;
  2335. q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
  2336. 1,exception);
  2337. if (q == (Quantum *) NULL)
  2338. break;
  2339. for (x=0; x < (int) draw_image->columns; x++)
  2340. {
  2341. if (XGetPixel(draw_ximage,x,y) == 0)
  2342. {
  2343. /*
  2344. Set this pixel to the background color.
  2345. */
  2346. SetPixelViaPixelInfo(draw_image,&draw_image->background_color,q);
  2347. SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
  2348. OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q);
  2349. }
  2350. else
  2351. {
  2352. /*
  2353. Set this pixel to the pen color.
  2354. */
  2355. SetPixelRed(draw_image,ScaleShortToQuantum(
  2356. pixel->pen_color.red),q);
  2357. SetPixelGreen(draw_image,ScaleShortToQuantum(
  2358. pixel->pen_color.green),q);
  2359. SetPixelBlue(draw_image,ScaleShortToQuantum(
  2360. pixel->pen_color.blue),q);
  2361. SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
  2362. OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q);
  2363. }
  2364. q+=GetPixelChannels(draw_image);
  2365. }
  2366. if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
  2367. break;
  2368. }
  2369. draw_view=DestroyCacheView(draw_view);
  2370. XDestroyImage(draw_ximage);
  2371. /*
  2372. Determine draw geometry.
  2373. */
  2374. (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
  2375. if ((width != (unsigned int) draw_image->columns) ||
  2376. (height != (unsigned int) draw_image->rows))
  2377. {
  2378. char
  2379. image_geometry[MagickPathExtent];
  2380. /*
  2381. Scale image.
  2382. */
  2383. (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u",
  2384. width,height);
  2385. (void) TransformImage(&draw_image,(char *) NULL,image_geometry,
  2386. exception);
  2387. }
  2388. if (draw_info->degrees != 0.0)
  2389. {
  2390. Image
  2391. *rotate_image;
  2392. int
  2393. rotations;
  2394. double
  2395. normalized_degrees;
  2396. /*
  2397. Rotate image.
  2398. */
  2399. rotate_image=RotateImage(draw_image,draw_info->degrees,exception);
  2400. if (rotate_image == (Image *) NULL)
  2401. return(MagickFalse);
  2402. draw_image=DestroyImage(draw_image);
  2403. draw_image=rotate_image;
  2404. /*
  2405. Annotation is relative to the degree of rotation.
  2406. */
  2407. normalized_degrees=draw_info->degrees;
  2408. while (normalized_degrees < -45.0)
  2409. normalized_degrees+=360.0;
  2410. for (rotations=0; normalized_degrees > 45.0; rotations++)
  2411. normalized_degrees-=90.0;
  2412. switch (rotations % 4)
  2413. {
  2414. default:
  2415. case 0:
  2416. break;
  2417. case 1:
  2418. {
  2419. /*
  2420. Rotate 90 degrees.
  2421. */
  2422. x=x-(int) draw_image->columns/2;
  2423. y=y+(int) draw_image->columns/2;
  2424. break;
  2425. }
  2426. case 2:
  2427. {
  2428. /*
  2429. Rotate 180 degrees.
  2430. */
  2431. x=x-(int) draw_image->columns;
  2432. break;
  2433. }
  2434. case 3:
  2435. {
  2436. /*
  2437. Rotate 270 degrees.
  2438. */
  2439. x=x-(int) draw_image->columns/2;
  2440. y=y-(int) (draw_image->rows-(draw_image->columns/2));
  2441. break;
  2442. }
  2443. }
  2444. }
  2445. /*
  2446. Composite text onto the image.
  2447. */
  2448. draw_view=AcquireAuthenticCacheView(draw_image,exception);
  2449. for (y=0; y < (int) draw_image->rows; y++)
  2450. {
  2451. register int
  2452. x;
  2453. register Quantum
  2454. *magick_restrict q;
  2455. q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
  2456. exception);
  2457. if (q == (Quantum *) NULL)
  2458. break;
  2459. for (x=0; x < (int) draw_image->columns; x++)
  2460. {
  2461. if (GetPixelAlpha(image,q) != TransparentAlpha)
  2462. SetPixelAlpha(draw_image,OpaqueAlpha,q);
  2463. q+=GetPixelChannels(draw_image);
  2464. }
  2465. if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
  2466. break;
  2467. }
  2468. draw_view=DestroyCacheView(draw_view);
  2469. (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
  2470. if (draw_info->stencil == TransparentStencil)
  2471. (void) CompositeImage(image,draw_image,CopyAlphaCompositeOp,MagickTrue,
  2472. (ssize_t) x,(ssize_t) y,exception);
  2473. else
  2474. {
  2475. alpha_trait=image->alpha_trait;
  2476. (void) CompositeImage(image,draw_image,OverCompositeOp,MagickTrue,
  2477. (ssize_t) x,(ssize_t) y,exception);
  2478. image->alpha_trait=alpha_trait;
  2479. }
  2480. draw_image=DestroyImage(draw_image);
  2481. return(MagickTrue);
  2482. }
  2483. /*
  2484. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2485. % %
  2486. % %
  2487. % %
  2488. % X E r r o r %
  2489. % %
  2490. % %
  2491. % %
  2492. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2493. %
  2494. % XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes,
  2495. % and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors
  2496. % for XQueryColor. It returns MagickFalse in those cases. Otherwise it
  2497. % returns True.
  2498. %
  2499. % The format of the XError function is:
  2500. %
  2501. % int XError(display,error)
  2502. %
  2503. % A description of each parameter follows:
  2504. %
  2505. % o display: Specifies a pointer to the Display structure; returned from
  2506. % XOpenDisplay.
  2507. %
  2508. % o error: Specifies the error event.
  2509. %
  2510. */
  2511. #if defined(__cplusplus) || defined(c_plusplus)
  2512. extern "C" {
  2513. #endif
  2514. MagickExport int XError(Display *display,XErrorEvent *error)
  2515. {
  2516. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2517. assert(display != (Display *) NULL);
  2518. assert(error != (XErrorEvent *) NULL);
  2519. xerror_alert=MagickTrue;
  2520. switch (error->request_code)
  2521. {
  2522. case X_GetGeometry:
  2523. {
  2524. if ((int) error->error_code == BadDrawable)
  2525. return(MagickFalse);
  2526. break;
  2527. }
  2528. case X_GetWindowAttributes:
  2529. case X_QueryTree:
  2530. {
  2531. if ((int) error->error_code == BadWindow)
  2532. return(MagickFalse);
  2533. break;
  2534. }
  2535. case X_QueryColors:
  2536. {
  2537. if ((int) error->error_code == BadValue)
  2538. return(MagickFalse);
  2539. break;
  2540. }
  2541. }
  2542. return(MagickTrue);
  2543. }
  2544. #if defined(__cplusplus) || defined(c_plusplus)
  2545. }
  2546. #endif
  2547. /*
  2548. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2549. % %
  2550. % %
  2551. % %
  2552. % X F r e e R e s o u r c e s %
  2553. % %
  2554. % %
  2555. % %
  2556. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2557. %
  2558. % XFreeResources() frees X11 resources.
  2559. %
  2560. % The format of the XFreeResources method is:
  2561. %
  2562. % void XFreeResources(Display *display,XVisualInfo *visual_info,
  2563. % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
  2564. % XResourceInfo *resource_info,XWindowInfo *window_info)
  2565. % resource_info,window_info)
  2566. %
  2567. % A description of each parameter follows:
  2568. %
  2569. % o display: Specifies a connection to an X server; returned from
  2570. % XOpenDisplay.
  2571. %
  2572. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  2573. % returned from XGetVisualInfo.
  2574. %
  2575. % o map_info: If map_type is specified, this structure is initialized
  2576. % with info from the Standard Colormap.
  2577. %
  2578. % o pixel: Specifies a pointer to a XPixelInfo structure.
  2579. %
  2580. % o font_info: Specifies a pointer to a XFontStruct structure.
  2581. %
  2582. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  2583. %
  2584. % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
  2585. %
  2586. */
  2587. MagickPrivate void XFreeResources(Display *display,XVisualInfo *visual_info,
  2588. XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
  2589. XResourceInfo *resource_info,XWindowInfo *window_info)
  2590. {
  2591. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2592. assert(display != (Display *) NULL);
  2593. assert(resource_info != (XResourceInfo *) NULL);
  2594. if (window_info != (XWindowInfo *) NULL)
  2595. {
  2596. /*
  2597. Free X image.
  2598. */
  2599. if (window_info->ximage != (XImage *) NULL)
  2600. XDestroyImage(window_info->ximage);
  2601. if (window_info->id != (Window) NULL)
  2602. {
  2603. /*
  2604. Free destroy window and free cursors.
  2605. */
  2606. if (window_info->id != XRootWindow(display,visual_info->screen))
  2607. (void) XDestroyWindow(display,window_info->id);
  2608. if (window_info->annotate_context != (GC) NULL)
  2609. (void) XFreeGC(display,window_info->annotate_context);
  2610. if (window_info->highlight_context != (GC) NULL)
  2611. (void) XFreeGC(display,window_info->highlight_context);
  2612. if (window_info->widget_context != (GC) NULL)
  2613. (void) XFreeGC(display,window_info->widget_context);
  2614. if (window_info->cursor != (Cursor) NULL)
  2615. (void) XFreeCursor(display,window_info->cursor);
  2616. window_info->cursor=(Cursor) NULL;
  2617. if (window_info->busy_cursor != (Cursor) NULL)
  2618. (void) XFreeCursor(display,window_info->busy_cursor);
  2619. window_info->busy_cursor=(Cursor) NULL;
  2620. }
  2621. }
  2622. /*
  2623. Free font.
  2624. */
  2625. if (font_info != (XFontStruct *) NULL)
  2626. {
  2627. (void) XFreeFont(display,font_info);
  2628. font_info=(XFontStruct *) NULL;
  2629. }
  2630. if (map_info != (XStandardColormap *) NULL)
  2631. {
  2632. /*
  2633. Free X Standard Colormap.
  2634. */
  2635. if (resource_info->map_type == (char *) NULL)
  2636. (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
  2637. (void) XFree((void *) map_info);
  2638. }
  2639. /*
  2640. Free X visual info.
  2641. */
  2642. if (visual_info != (XVisualInfo *) NULL)
  2643. (void) XFree((void *) visual_info);
  2644. if (resource_info->close_server != MagickFalse)
  2645. (void) XCloseDisplay(display);
  2646. }
  2647. /*
  2648. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2649. % %
  2650. % %
  2651. % %
  2652. % X F r e e S t a n d a r d C o l o r m a p %
  2653. % %
  2654. % %
  2655. % %
  2656. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2657. %
  2658. % XFreeStandardColormap() frees an X11 colormap.
  2659. %
  2660. % The format of the XFreeStandardColormap method is:
  2661. %
  2662. % void XFreeStandardColormap(Display *display,
  2663. % const XVisualInfo *visual_info,XStandardColormap *map_info,
  2664. % XPixelInfo *pixel)
  2665. %
  2666. % A description of each parameter follows:
  2667. %
  2668. % o display: Specifies a connection to an X server; returned from
  2669. % XOpenDisplay.
  2670. %
  2671. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  2672. % returned from XGetVisualInfo.
  2673. %
  2674. % o map_info: If map_type is specified, this structure is initialized
  2675. % with info from the Standard Colormap.
  2676. %
  2677. % o pixel: Specifies a pointer to a XPixelInfo structure.
  2678. %
  2679. */
  2680. MagickPrivate void XFreeStandardColormap(Display *display,
  2681. const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel)
  2682. {
  2683. /*
  2684. Free colormap.
  2685. */
  2686. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2687. assert(display != (Display *) NULL);
  2688. assert(visual_info != (XVisualInfo *) NULL);
  2689. assert(map_info != (XStandardColormap *) NULL);
  2690. (void) XFlush(display);
  2691. if (map_info->colormap != (Colormap) NULL)
  2692. {
  2693. if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  2694. (void) XFreeColormap(display,map_info->colormap);
  2695. else
  2696. if (pixel != (XPixelInfo *) NULL)
  2697. if ((visual_info->klass != TrueColor) &&
  2698. (visual_info->klass != DirectColor))
  2699. (void) XFreeColors(display,map_info->colormap,pixel->pixels,
  2700. (int) pixel->colors,0);
  2701. }
  2702. map_info->colormap=(Colormap) NULL;
  2703. if (pixel != (XPixelInfo *) NULL)
  2704. {
  2705. if (pixel->pixels != (unsigned long *) NULL)
  2706. pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
  2707. pixel->pixels=(unsigned long *) NULL;
  2708. }
  2709. }
  2710. /*
  2711. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2712. % %
  2713. % %
  2714. % %
  2715. % X G e t A n n o t a t e I n f o %
  2716. % %
  2717. % %
  2718. % %
  2719. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2720. %
  2721. % XGetAnnotateInfo() initializes the AnnotateInfo structure.
  2722. %
  2723. % The format of the XGetAnnotateInfo method is:
  2724. %
  2725. % void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
  2726. %
  2727. % A description of each parameter follows:
  2728. %
  2729. % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
  2730. %
  2731. */
  2732. MagickPrivate void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
  2733. {
  2734. /*
  2735. Initialize annotate structure.
  2736. */
  2737. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2738. assert(annotate_info != (XAnnotateInfo *) NULL);
  2739. annotate_info->x=0;
  2740. annotate_info->y=0;
  2741. annotate_info->width=0;
  2742. annotate_info->height=0;
  2743. annotate_info->stencil=ForegroundStencil;
  2744. annotate_info->degrees=0.0;
  2745. annotate_info->font_info=(XFontStruct *) NULL;
  2746. annotate_info->text=(char *) NULL;
  2747. *annotate_info->geometry='\0';
  2748. annotate_info->previous=(XAnnotateInfo *) NULL;
  2749. annotate_info->next=(XAnnotateInfo *) NULL;
  2750. (void) XSupportsLocale();
  2751. (void) XSetLocaleModifiers("");
  2752. }
  2753. /*
  2754. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2755. % %
  2756. % %
  2757. % %
  2758. % X G e t M a p I n f o %
  2759. % %
  2760. % %
  2761. % %
  2762. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2763. %
  2764. % XGetMapInfo() initializes the XStandardColormap structure.
  2765. %
  2766. % The format of the XStandardColormap method is:
  2767. %
  2768. % void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap,
  2769. % XStandardColormap *map_info)
  2770. %
  2771. % A description of each parameter follows:
  2772. %
  2773. % o colormap: Specifies the ID of the X server colormap.
  2774. %
  2775. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  2776. % returned from XGetVisualInfo.
  2777. %
  2778. % o map_info: Specifies a pointer to a X11 XStandardColormap structure.
  2779. %
  2780. */
  2781. MagickPrivate void XGetMapInfo(const XVisualInfo *visual_info,
  2782. const Colormap colormap,XStandardColormap *map_info)
  2783. {
  2784. /*
  2785. Initialize map info.
  2786. */
  2787. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2788. assert(visual_info != (XVisualInfo *) NULL);
  2789. assert(map_info != (XStandardColormap *) NULL);
  2790. map_info->colormap=colormap;
  2791. map_info->red_max=visual_info->red_mask;
  2792. map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0);
  2793. if (map_info->red_max != 0)
  2794. while ((map_info->red_max & 0x01) == 0)
  2795. {
  2796. map_info->red_max>>=1;
  2797. map_info->red_mult<<=1;
  2798. }
  2799. map_info->green_max=visual_info->green_mask;
  2800. map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0);
  2801. if (map_info->green_max != 0)
  2802. while ((map_info->green_max & 0x01) == 0)
  2803. {
  2804. map_info->green_max>>=1;
  2805. map_info->green_mult<<=1;
  2806. }
  2807. map_info->blue_max=visual_info->blue_mask;
  2808. map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0);
  2809. if (map_info->blue_max != 0)
  2810. while ((map_info->blue_max & 0x01) == 0)
  2811. {
  2812. map_info->blue_max>>=1;
  2813. map_info->blue_mult<<=1;
  2814. }
  2815. map_info->base_pixel=0;
  2816. }
  2817. /*
  2818. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2819. % %
  2820. % %
  2821. % %
  2822. % X G e t P i x e l I n f o %
  2823. % %
  2824. % %
  2825. % %
  2826. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2827. %
  2828. % XGetPixelInfo() initializes the PixelInfo structure.
  2829. %
  2830. % The format of the XGetPixelInfo method is:
  2831. %
  2832. % void XGetPixelInfo(Display *display,const XVisualInfo *visual_info,
  2833. % const XStandardColormap *map_info,const XResourceInfo *resource_info,
  2834. % Image *image,XPixelInfo *pixel)
  2835. % pixel)
  2836. %
  2837. % A description of each parameter follows:
  2838. %
  2839. % o display: Specifies a connection to an X server; returned from
  2840. % XOpenDisplay.
  2841. %
  2842. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  2843. % returned from XGetVisualInfo.
  2844. %
  2845. % o map_info: If map_type is specified, this structure is initialized
  2846. % with info from the Standard Colormap.
  2847. %
  2848. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  2849. %
  2850. % o image: the image.
  2851. %
  2852. % o pixel: Specifies a pointer to a XPixelInfo structure.
  2853. %
  2854. */
  2855. MagickPrivate void XGetPixelInfo(Display *display,
  2856. const XVisualInfo *visual_info,const XStandardColormap *map_info,
  2857. const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel)
  2858. {
  2859. static const char
  2860. *PenColors[MaxNumberPens]=
  2861. {
  2862. "#000000000000", /* black */
  2863. "#00000000ffff", /* blue */
  2864. "#0000ffffffff", /* cyan */
  2865. "#0000ffff0000", /* green */
  2866. "#bdbdbdbdbdbd", /* gray */
  2867. "#ffff00000000", /* red */
  2868. "#ffff0000ffff", /* magenta */
  2869. "#ffffffff0000", /* yellow */
  2870. "#ffffffffffff", /* white */
  2871. "#bdbdbdbdbdbd", /* gray */
  2872. "#bdbdbdbdbdbd" /* gray */
  2873. };
  2874. Colormap
  2875. colormap;
  2876. extern const char
  2877. BorderColor[],
  2878. ForegroundColor[];
  2879. register ssize_t
  2880. i;
  2881. Status
  2882. status;
  2883. unsigned int
  2884. packets;
  2885. /*
  2886. Initialize pixel info.
  2887. */
  2888. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  2889. assert(display != (Display *) NULL);
  2890. assert(visual_info != (XVisualInfo *) NULL);
  2891. assert(map_info != (XStandardColormap *) NULL);
  2892. assert(resource_info != (XResourceInfo *) NULL);
  2893. assert(pixel != (XPixelInfo *) NULL);
  2894. pixel->colors=0;
  2895. if (image != (Image *) NULL)
  2896. if (image->storage_class == PseudoClass)
  2897. pixel->colors=(ssize_t) image->colors;
  2898. packets=(unsigned int)
  2899. MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
  2900. if (pixel->pixels != (unsigned long *) NULL)
  2901. pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
  2902. pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets,
  2903. sizeof(*pixel->pixels));
  2904. if (pixel->pixels == (unsigned long *) NULL)
  2905. ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo",
  2906. image->filename);
  2907. /*
  2908. Set foreground color.
  2909. */
  2910. colormap=map_info->colormap;
  2911. (void) XParseColor(display,colormap,(char *) ForegroundColor,
  2912. &pixel->foreground_color);
  2913. status=XParseColor(display,colormap,resource_info->foreground_color,
  2914. &pixel->foreground_color);
  2915. if (status == False)
  2916. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
  2917. resource_info->foreground_color);
  2918. pixel->foreground_color.pixel=
  2919. XStandardPixel(map_info,&pixel->foreground_color);
  2920. pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2921. /*
  2922. Set background color.
  2923. */
  2924. (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color);
  2925. status=XParseColor(display,colormap,resource_info->background_color,
  2926. &pixel->background_color);
  2927. if (status == False)
  2928. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
  2929. resource_info->background_color);
  2930. pixel->background_color.pixel=
  2931. XStandardPixel(map_info,&pixel->background_color);
  2932. pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2933. /*
  2934. Set border color.
  2935. */
  2936. (void) XParseColor(display,colormap,(char *) BorderColor,
  2937. &pixel->border_color);
  2938. status=XParseColor(display,colormap,resource_info->border_color,
  2939. &pixel->border_color);
  2940. if (status == False)
  2941. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
  2942. resource_info->border_color);
  2943. pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color);
  2944. pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2945. /*
  2946. Set matte color.
  2947. */
  2948. pixel->matte_color=pixel->background_color;
  2949. if (resource_info->matte_color != (char *) NULL)
  2950. {
  2951. /*
  2952. Matte color is specified as a X resource or command line argument.
  2953. */
  2954. status=XParseColor(display,colormap,resource_info->matte_color,
  2955. &pixel->matte_color);
  2956. if (status == False)
  2957. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
  2958. resource_info->matte_color);
  2959. pixel->matte_color.pixel=XStandardPixel(map_info,&pixel->matte_color);
  2960. pixel->matte_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2961. }
  2962. /*
  2963. Set highlight color.
  2964. */
  2965. pixel->highlight_color.red=(unsigned short) (((double)
  2966. pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
  2967. (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
  2968. pixel->highlight_color.green=(unsigned short) (((double)
  2969. pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
  2970. (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
  2971. pixel->highlight_color.blue=(unsigned short) (((double)
  2972. pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
  2973. (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
  2974. pixel->highlight_color.pixel=XStandardPixel(map_info,&pixel->highlight_color);
  2975. pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2976. /*
  2977. Set shadow color.
  2978. */
  2979. pixel->shadow_color.red=(unsigned short) (((double)
  2980. pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
  2981. pixel->shadow_color.green=(unsigned short) (((double)
  2982. pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
  2983. pixel->shadow_color.blue=(unsigned short) (((double)
  2984. pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
  2985. pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color);
  2986. pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2987. /*
  2988. Set depth color.
  2989. */
  2990. pixel->depth_color.red=(unsigned short) (((double)
  2991. pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
  2992. pixel->depth_color.green=(unsigned short) (((double)
  2993. pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
  2994. pixel->depth_color.blue=(unsigned short) (((double)
  2995. pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
  2996. pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color);
  2997. pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue);
  2998. /*
  2999. Set trough color.
  3000. */
  3001. pixel->trough_color.red=(unsigned short) (((double)
  3002. pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
  3003. pixel->trough_color.green=(unsigned short) (((double)
  3004. pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
  3005. pixel->trough_color.blue=(unsigned short) (((double)
  3006. pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
  3007. pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color);
  3008. pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue);
  3009. /*
  3010. Set pen color.
  3011. */
  3012. for (i=0; i < MaxNumberPens; i++)
  3013. {
  3014. (void) XParseColor(display,colormap,(char *) PenColors[i],
  3015. &pixel->pen_colors[i]);
  3016. status=XParseColor(display,colormap,resource_info->pen_colors[i],
  3017. &pixel->pen_colors[i]);
  3018. if (status == False)
  3019. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
  3020. resource_info->pen_colors[i]);
  3021. pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]);
  3022. pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue);
  3023. }
  3024. pixel->box_color=pixel->background_color;
  3025. pixel->pen_color=pixel->foreground_color;
  3026. pixel->box_index=0;
  3027. pixel->pen_index=1;
  3028. if (image != (Image *) NULL)
  3029. {
  3030. if ((resource_info->gamma_correct != MagickFalse) &&
  3031. (image->gamma != 0.0))
  3032. {
  3033. GeometryInfo
  3034. geometry_info;
  3035. MagickStatusType
  3036. flags;
  3037. /*
  3038. Initialize map relative to display and image gamma.
  3039. */
  3040. flags=ParseGeometry(resource_info->display_gamma,&geometry_info);
  3041. red_gamma=geometry_info.rho;
  3042. green_gamma=geometry_info.sigma;
  3043. if ((flags & SigmaValue) == 0)
  3044. green_gamma=red_gamma;
  3045. blue_gamma=geometry_info.xi;
  3046. if ((flags & XiValue) == 0)
  3047. blue_gamma=red_gamma;
  3048. red_gamma*=image->gamma;
  3049. green_gamma*=image->gamma;
  3050. blue_gamma*=image->gamma;
  3051. }
  3052. if (image->storage_class == PseudoClass)
  3053. {
  3054. /*
  3055. Initialize pixel array for images of type PseudoClass.
  3056. */
  3057. for (i=0; i < (ssize_t) image->colors; i++)
  3058. pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i);
  3059. for (i=0; i < MaxNumberPens; i++)
  3060. pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
  3061. pixel->colors+=MaxNumberPens;
  3062. }
  3063. }
  3064. }
  3065. /*
  3066. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3067. % %
  3068. % %
  3069. % %
  3070. % X G e t R e s o u r c e C l a s s %
  3071. % %
  3072. % %
  3073. % %
  3074. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3075. %
  3076. % XGetResourceClass() queries the X server for the specified resource name or
  3077. % class. If the resource name or class is not defined in the database, the
  3078. % supplied default value is returned.
  3079. %
  3080. % The format of the XGetResourceClass method is:
  3081. %
  3082. % char *XGetResourceClass(XrmDatabase database,const char *client_name,
  3083. % const char *keyword,char *resource_default)
  3084. %
  3085. % A description of each parameter follows:
  3086. %
  3087. % o database: Specifies a resource database; returned from
  3088. % XrmGetStringDatabase.
  3089. %
  3090. % o client_name: Specifies the application name used to retrieve resource
  3091. % info from the X server database.
  3092. %
  3093. % o keyword: Specifies the keyword of the value being retrieved.
  3094. %
  3095. % o resource_default: Specifies the default value to return if the query
  3096. % fails to find the specified keyword/class.
  3097. %
  3098. */
  3099. MagickExport char *XGetResourceClass(XrmDatabase database,
  3100. const char *client_name,const char *keyword,char *resource_default)
  3101. {
  3102. char
  3103. resource_class[MagickPathExtent],
  3104. resource_name[MagickPathExtent];
  3105. static char
  3106. *resource_type;
  3107. Status
  3108. status;
  3109. XrmValue
  3110. resource_value;
  3111. if (database == (XrmDatabase) NULL)
  3112. return(resource_default);
  3113. *resource_name='\0';
  3114. *resource_class='\0';
  3115. if (keyword != (char *) NULL)
  3116. {
  3117. int
  3118. c,
  3119. k;
  3120. /*
  3121. Initialize resource keyword and class.
  3122. */
  3123. (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s",
  3124. client_name,keyword);
  3125. c=(int) (*client_name);
  3126. if ((c >= XK_a) && (c <= XK_z))
  3127. c-=(XK_a-XK_A);
  3128. else
  3129. if ((c >= XK_agrave) && (c <= XK_odiaeresis))
  3130. c-=(XK_agrave-XK_Agrave);
  3131. else
  3132. if ((c >= XK_oslash) && (c <= XK_thorn))
  3133. c-=(XK_oslash-XK_Ooblique);
  3134. k=(int) (*keyword);
  3135. if ((k >= XK_a) && (k <= XK_z))
  3136. k-=(XK_a-XK_A);
  3137. else
  3138. if ((k >= XK_agrave) && (k <= XK_odiaeresis))
  3139. k-=(XK_agrave-XK_Agrave);
  3140. else
  3141. if ((k >= XK_oslash) && (k <= XK_thorn))
  3142. k-=(XK_oslash-XK_Ooblique);
  3143. (void) FormatLocaleString(resource_class,MagickPathExtent,"%c%s.%c%s",c,
  3144. client_name+1,k,keyword+1);
  3145. }
  3146. status=XrmGetResource(database,resource_name,resource_class,&resource_type,
  3147. &resource_value);
  3148. if (status == False)
  3149. return(resource_default);
  3150. return(resource_value.addr);
  3151. }
  3152. /*
  3153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3154. % %
  3155. % %
  3156. % %
  3157. % X G e t R e s o u r c e D a t a b a s e %
  3158. % %
  3159. % %
  3160. % %
  3161. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3162. %
  3163. % XGetResourceDatabase() creates a new resource database and initializes it.
  3164. %
  3165. % The format of the XGetResourceDatabase method is:
  3166. %
  3167. % XrmDatabase XGetResourceDatabase(Display *display,
  3168. % const char *client_name)
  3169. %
  3170. % A description of each parameter follows:
  3171. %
  3172. % o database: XGetResourceDatabase() returns the database after it is
  3173. % initialized.
  3174. %
  3175. % o display: Specifies a connection to an X server; returned from
  3176. % XOpenDisplay.
  3177. %
  3178. % o client_name: Specifies the application name used to retrieve resource
  3179. % info from the X server database.
  3180. %
  3181. */
  3182. MagickExport XrmDatabase XGetResourceDatabase(Display *display,
  3183. const char *client_name)
  3184. {
  3185. char
  3186. filename[MagickPathExtent];
  3187. int
  3188. c;
  3189. register const char
  3190. *p;
  3191. XrmDatabase
  3192. resource_database,
  3193. server_database;
  3194. if (display == (Display *) NULL)
  3195. return((XrmDatabase) NULL);
  3196. assert(client_name != (char *) NULL);
  3197. /*
  3198. Initialize resource database.
  3199. */
  3200. XrmInitialize();
  3201. (void) XGetDefault(display,(char *) client_name,"dummy");
  3202. resource_database=XrmGetDatabase(display);
  3203. /*
  3204. Combine application database.
  3205. */
  3206. p=client_name+(strlen(client_name)-1);
  3207. while ((p > client_name) && (*p != '/'))
  3208. p--;
  3209. if (*p == '/')
  3210. client_name=p+1;
  3211. c=(int) (*client_name);
  3212. if ((c >= XK_a) && (c <= XK_z))
  3213. c-=(XK_a-XK_A);
  3214. else
  3215. if ((c >= XK_agrave) && (c <= XK_odiaeresis))
  3216. c-=(XK_agrave-XK_Agrave);
  3217. else
  3218. if ((c >= XK_oslash) && (c <= XK_thorn))
  3219. c-=(XK_oslash-XK_Ooblique);
  3220. #if defined(X11_APPLICATION_PATH)
  3221. (void) FormatLocaleString(filename,MagickPathExtent,"%s%c%s",
  3222. X11_APPLICATION_PATH,c,client_name+1);
  3223. (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
  3224. #endif
  3225. if (XResourceManagerString(display) != (char *) NULL)
  3226. {
  3227. /*
  3228. Combine server database.
  3229. */
  3230. server_database=XrmGetStringDatabase(XResourceManagerString(display));
  3231. XrmCombineDatabase(server_database,&resource_database,MagickFalse);
  3232. }
  3233. /*
  3234. Merge user preferences database.
  3235. */
  3236. #if defined(X11_PREFERENCES_PATH)
  3237. (void) FormatLocaleString(filename,MagickPathExtent,"%s%src",
  3238. X11_PREFERENCES_PATH,client_name);
  3239. ExpandFilename(filename);
  3240. (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
  3241. #endif
  3242. return(resource_database);
  3243. }
  3244. /*
  3245. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3246. % %
  3247. % %
  3248. % %
  3249. % X G e t R e s o u r c e I n f o %
  3250. % %
  3251. % %
  3252. % %
  3253. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3254. %
  3255. % XGetResourceInfo(image_info,) initializes the ResourceInfo structure.
  3256. %
  3257. % The format of the XGetResourceInfo method is:
  3258. %
  3259. % void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
  3260. % const char *client_name,XResourceInfo *resource_info)
  3261. %
  3262. % A description of each parameter follows:
  3263. %
  3264. % o image_info: the image info.
  3265. %
  3266. % o database: Specifies a resource database; returned from
  3267. % XrmGetStringDatabase.
  3268. %
  3269. % o client_name: Specifies the application name used to retrieve
  3270. % resource info from the X server database.
  3271. %
  3272. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  3273. %
  3274. */
  3275. MagickExport void XGetResourceInfo(const ImageInfo *image_info,
  3276. XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
  3277. {
  3278. char
  3279. *directory,
  3280. *resource_value;
  3281. extern const char
  3282. BorderColor[],
  3283. ForegroundColor[];
  3284. /*
  3285. Initialize resource info fields.
  3286. */
  3287. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  3288. assert(resource_info != (XResourceInfo *) NULL);
  3289. (void) memset(resource_info,0,sizeof(*resource_info));
  3290. resource_info->resource_database=database;
  3291. resource_info->image_info=(ImageInfo *) image_info;
  3292. (void) SetImageInfoProgressMonitor(resource_info->image_info,
  3293. XMagickProgressMonitor,(void *) NULL);
  3294. resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
  3295. resource_info->close_server=MagickTrue;
  3296. resource_info->client_name=AcquireString(client_name);
  3297. resource_value=XGetResourceClass(database,client_name,"backdrop",
  3298. (char *) "False");
  3299. resource_info->backdrop=IsStringTrue(resource_value);
  3300. resource_info->background_color=XGetResourceInstance(database,client_name,
  3301. "background",(char *) "#d6d6d6d6d6d6");
  3302. resource_info->border_color=XGetResourceInstance(database,client_name,
  3303. "borderColor",BorderColor);
  3304. resource_value=XGetResourceClass(database,client_name,"borderWidth",
  3305. (char *) "2");
  3306. resource_info->border_width=(unsigned int) StringToUnsignedLong(
  3307. resource_value);
  3308. resource_value=XGetResourceClass(database,client_name,"colormap",
  3309. (char *) "shared");
  3310. resource_info->colormap=UndefinedColormap;
  3311. if (LocaleCompare("private",resource_value) == 0)
  3312. resource_info->colormap=PrivateColormap;
  3313. if (LocaleCompare("shared",resource_value) == 0)
  3314. resource_info->colormap=SharedColormap;
  3315. if (resource_info->colormap == UndefinedColormap)
  3316. ThrowXWindowException(OptionError,"UnrecognizedColormapType",
  3317. resource_value);
  3318. resource_value=XGetResourceClass(database,client_name,
  3319. "colorRecovery",(char *) "False");
  3320. resource_info->color_recovery=IsStringTrue(resource_value);
  3321. resource_value=XGetResourceClass(database,client_name,"confirmExit",
  3322. (char *) "False");
  3323. resource_info->confirm_exit=IsStringTrue(resource_value);
  3324. resource_value=XGetResourceClass(database,client_name,"confirmEdit",
  3325. (char *) "False");
  3326. resource_info->confirm_edit=IsStringTrue(resource_value);
  3327. resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1");
  3328. resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value);
  3329. resource_info->display_gamma=XGetResourceClass(database,client_name,
  3330. "displayGamma",(char *) "2.2");
  3331. resource_value=XGetResourceClass(database,client_name,"displayWarnings",
  3332. (char *) "True");
  3333. resource_info->display_warnings=IsStringTrue(resource_value);
  3334. resource_info->font=XGetResourceClass(database,client_name,"font",
  3335. (char *) NULL);
  3336. resource_info->font=XGetResourceClass(database,client_name,"fontList",
  3337. resource_info->font);
  3338. resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1",
  3339. (char *) "fixed");
  3340. resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2",
  3341. (char *) "variable");
  3342. resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3",
  3343. (char *) "5x8");
  3344. resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4",
  3345. (char *) "6x10");
  3346. resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5",
  3347. (char *) "7x13bold");
  3348. resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6",
  3349. (char *) "8x13bold");
  3350. resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7",
  3351. (char *) "9x15bold");
  3352. resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8",
  3353. (char *) "10x20");
  3354. resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9",
  3355. (char *) "12x24");
  3356. resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0",
  3357. (char *) "fixed");
  3358. resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0",
  3359. (char *) "fixed");
  3360. resource_info->foreground_color=XGetResourceInstance(database,client_name,
  3361. "foreground",ForegroundColor);
  3362. resource_value=XGetResourceClass(database,client_name,"gammaCorrect",
  3363. (char *) "False");
  3364. resource_info->gamma_correct=IsStringTrue(resource_value);
  3365. resource_info->image_geometry=ConstantString(XGetResourceClass(database,
  3366. client_name,"geometry",(char *) NULL));
  3367. resource_value=XGetResourceClass(database,client_name,"gravity",
  3368. (char *) "Center");
  3369. resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
  3370. MagickFalse,resource_value);
  3371. directory=getcwd(resource_info->home_directory,MagickPathExtent);
  3372. (void) directory;
  3373. resource_info->icon_geometry=XGetResourceClass(database,client_name,
  3374. "iconGeometry",(char *) NULL);
  3375. resource_value=XGetResourceClass(database,client_name,"iconic",
  3376. (char *) "False");
  3377. resource_info->iconic=IsStringTrue(resource_value);
  3378. resource_value=XGetResourceClass(database,client_name,"immutable",
  3379. LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" :
  3380. (char *) "False");
  3381. resource_info->immutable=IsStringTrue(resource_value);
  3382. resource_value=XGetResourceClass(database,client_name,"magnify",
  3383. (char *) "3");
  3384. resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value);
  3385. resource_info->map_type=XGetResourceClass(database,client_name,"map",
  3386. (char *) NULL);
  3387. resource_info->matte_color=XGetResourceInstance(database,client_name,
  3388. "mattecolor",(char *) NULL);
  3389. resource_info->name=ConstantString(XGetResourceClass(database,client_name,
  3390. "name",(char *) NULL));
  3391. resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1",
  3392. (char *) "black");
  3393. resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2",
  3394. (char *) "blue");
  3395. resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3",
  3396. (char *) "cyan");
  3397. resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4",
  3398. (char *) "green");
  3399. resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5",
  3400. (char *) "gray");
  3401. resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6",
  3402. (char *) "red");
  3403. resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7",
  3404. (char *) "magenta");
  3405. resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8",
  3406. (char *) "yellow");
  3407. resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9",
  3408. (char *) "white");
  3409. resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0",
  3410. (char *) "gray");
  3411. resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0",
  3412. (char *) "gray");
  3413. resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0");
  3414. resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value);
  3415. resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
  3416. resource_info->quantum=StringToLong(resource_value);
  3417. resource_info->text_font=XGetResourceClass(database,client_name,(char *)
  3418. "font",(char *) "fixed");
  3419. resource_info->text_font=XGetResourceClass(database,client_name,
  3420. "textFontList",resource_info->text_font);
  3421. resource_info->title=XGetResourceClass(database,client_name,"title",
  3422. (char *) NULL);
  3423. resource_value=XGetResourceClass(database,client_name,"undoCache",
  3424. (char *) "256");
  3425. resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value);
  3426. resource_value=XGetResourceClass(database,client_name,"update",
  3427. (char *) "False");
  3428. resource_info->update=IsStringTrue(resource_value);
  3429. resource_value=XGetResourceClass(database,client_name,"usePixmap",
  3430. (char *) "True");
  3431. resource_info->use_pixmap=IsStringTrue(resource_value);
  3432. resource_value=XGetResourceClass(database,client_name,"sharedMemory",
  3433. (char *) "True");
  3434. resource_info->use_shared_memory=IsStringTrue(resource_value);
  3435. resource_info->visual_type=XGetResourceClass(database,client_name,"visual",
  3436. (char *) NULL);
  3437. resource_info->window_group=XGetResourceClass(database,client_name,
  3438. "windowGroup",(char *) NULL);
  3439. resource_info->window_id=XGetResourceClass(database,client_name,"window",
  3440. (char *) NULL);
  3441. resource_info->write_filename=XGetResourceClass(database,client_name,
  3442. "writeFilename",(char *) NULL);
  3443. }
  3444. /*
  3445. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3446. % %
  3447. % %
  3448. % %
  3449. % X G e t R e s o u r c e I n s t a n c e %
  3450. % %
  3451. % %
  3452. % %
  3453. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3454. %
  3455. % XGetResourceInstance() queries the X server for the specified resource name.
  3456. % If the resource name is not defined in the database, the supplied default
  3457. % value is returned.
  3458. %
  3459. % The format of the XGetResourceInstance method is:
  3460. %
  3461. % char *XGetResourceInstance(XrmDatabase database,const char *client_name,
  3462. % const char *keyword,const char *resource_default)
  3463. %
  3464. % A description of each parameter follows:
  3465. %
  3466. % o database: Specifies a resource database; returned from
  3467. % XrmGetStringDatabase.
  3468. %
  3469. % o client_name: Specifies the application name used to retrieve
  3470. % resource info from the X server database.
  3471. %
  3472. % o keyword: Specifies the keyword of the value being retrieved.
  3473. %
  3474. % o resource_default: Specifies the default value to return if the query
  3475. % fails to find the specified keyword/class.
  3476. %
  3477. */
  3478. MagickExport char *XGetResourceInstance(XrmDatabase database,
  3479. const char *client_name,const char *keyword,const char *resource_default)
  3480. {
  3481. char
  3482. *resource_type,
  3483. resource_name[MagickPathExtent];
  3484. Status
  3485. status;
  3486. XrmValue
  3487. resource_value;
  3488. if (database == (XrmDatabase) NULL)
  3489. return((char *) resource_default);
  3490. *resource_name='\0';
  3491. if (keyword != (char *) NULL)
  3492. (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s",client_name,
  3493. keyword);
  3494. status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type,
  3495. &resource_value);
  3496. if (status == False)
  3497. return((char *) resource_default);
  3498. return(resource_value.addr);
  3499. }
  3500. /*
  3501. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3502. % %
  3503. % %
  3504. % %
  3505. % X G e t S c r e e n D e n s i t y %
  3506. % %
  3507. % %
  3508. % %
  3509. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3510. %
  3511. % XGetScreenDensity() returns the density of the X server screen in
  3512. % dots-per-inch.
  3513. %
  3514. % The format of the XGetScreenDensity method is:
  3515. %
  3516. % char *XGetScreenDensity(Display *display)
  3517. %
  3518. % A description of each parameter follows:
  3519. %
  3520. % o density: XGetScreenDensity() returns the density of the X screen in
  3521. % dots-per-inch.
  3522. %
  3523. % o display: Specifies a connection to an X server; returned from
  3524. % XOpenDisplay.
  3525. %
  3526. */
  3527. MagickExport char *XGetScreenDensity(Display *display)
  3528. {
  3529. char
  3530. density[MagickPathExtent];
  3531. double
  3532. x_density,
  3533. y_density;
  3534. /*
  3535. Set density as determined by screen size.
  3536. */
  3537. x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
  3538. ((double) DisplayWidthMM(display,XDefaultScreen(display))));
  3539. y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
  3540. ((double) DisplayHeightMM(display,XDefaultScreen(display))));
  3541. (void) FormatLocaleString(density,MagickPathExtent,"%gx%g",x_density,
  3542. y_density);
  3543. return(GetPageGeometry(density));
  3544. }
  3545. /*
  3546. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3547. % %
  3548. % %
  3549. % %
  3550. + X G e t S u b w i n d o w %
  3551. % %
  3552. % %
  3553. % %
  3554. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3555. %
  3556. % XGetSubwindow() returns the subwindow of a window chosen the user with the
  3557. % pointer and a button press.
  3558. %
  3559. % The format of the XGetSubwindow method is:
  3560. %
  3561. % Window XGetSubwindow(Display *display,Window window,int x,int y)
  3562. %
  3563. % A description of each parameter follows:
  3564. %
  3565. % o subwindow: XGetSubwindow() returns NULL if no subwindow is found
  3566. % otherwise the subwindow is returned.
  3567. %
  3568. % o display: Specifies a connection to an X server; returned from
  3569. % XOpenDisplay.
  3570. %
  3571. % o window: Specifies a pointer to a Window.
  3572. %
  3573. % o x: the x coordinate of the pointer relative to the origin of the
  3574. % window.
  3575. %
  3576. % o y: the y coordinate of the pointer relative to the origin of the
  3577. % window.
  3578. %
  3579. */
  3580. static Window XGetSubwindow(Display *display,Window window,int x,int y)
  3581. {
  3582. int
  3583. x_offset,
  3584. y_offset;
  3585. Status
  3586. status;
  3587. Window
  3588. source_window,
  3589. target_window;
  3590. assert(display != (Display *) NULL);
  3591. source_window=XRootWindow(display,XDefaultScreen(display));
  3592. if (window == (Window) NULL)
  3593. return(source_window);
  3594. target_window=window;
  3595. for ( ; ; )
  3596. {
  3597. status=XTranslateCoordinates(display,source_window,window,x,y,
  3598. &x_offset,&y_offset,&target_window);
  3599. if (status != True)
  3600. break;
  3601. if (target_window == (Window) NULL)
  3602. break;
  3603. source_window=window;
  3604. window=target_window;
  3605. x=x_offset;
  3606. y=y_offset;
  3607. }
  3608. if (target_window == (Window) NULL)
  3609. target_window=window;
  3610. return(target_window);
  3611. }
  3612. /*
  3613. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3614. % %
  3615. % %
  3616. % %
  3617. % X G e t W i n d o w C o l o r %
  3618. % %
  3619. % %
  3620. % %
  3621. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3622. %
  3623. % XGetWindowColor() returns the color of a pixel interactively chosen from the
  3624. % X server.
  3625. %
  3626. % The format of the XGetWindowColor method is:
  3627. %
  3628. % MagickBooleanType XGetWindowColor(Display *display,XWindows *windows,
  3629. % char *name,ExceptionInfo *exception)
  3630. %
  3631. % A description of each parameter follows:
  3632. %
  3633. % o display: Specifies a connection to an X server; returned from
  3634. % XOpenDisplay.
  3635. %
  3636. % o windows: Specifies a pointer to a XWindows structure.
  3637. %
  3638. % o name: the name of the color if found in the X Color Database is
  3639. % returned in this character string.
  3640. %
  3641. % o exception: return any errors or warnings in this structure.
  3642. %
  3643. */
  3644. MagickPrivate MagickBooleanType XGetWindowColor(Display *display,
  3645. XWindows *windows,char *name,ExceptionInfo *exception)
  3646. {
  3647. int
  3648. x,
  3649. y;
  3650. PixelInfo
  3651. pixel;
  3652. RectangleInfo
  3653. crop_info;
  3654. Status
  3655. status;
  3656. Window
  3657. child,
  3658. client_window,
  3659. root_window,
  3660. target_window;
  3661. XColor
  3662. color;
  3663. XImage
  3664. *ximage;
  3665. XWindowAttributes
  3666. window_attributes;
  3667. /*
  3668. Choose a pixel from the X server.
  3669. */
  3670. assert(display != (Display *) NULL);
  3671. assert(name != (char *) NULL);
  3672. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
  3673. *name='\0';
  3674. target_window=XSelectWindow(display,&crop_info);
  3675. if (target_window == (Window) NULL)
  3676. return(MagickFalse);
  3677. root_window=XRootWindow(display,XDefaultScreen(display));
  3678. client_window=target_window;
  3679. if (target_window != root_window)
  3680. {
  3681. unsigned int
  3682. d;
  3683. /*
  3684. Get client window.
  3685. */
  3686. status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
  3687. if (status != False)
  3688. {
  3689. client_window=XClientWindow(display,target_window);
  3690. target_window=client_window;
  3691. }
  3692. }
  3693. /*
  3694. Verify window is viewable.
  3695. */
  3696. status=XGetWindowAttributes(display,target_window,&window_attributes);
  3697. if ((status == False) || (window_attributes.map_state != IsViewable))
  3698. return(MagickFalse);
  3699. /*
  3700. Get window X image.
  3701. */
  3702. (void) XTranslateCoordinates(display,root_window,target_window,
  3703. (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
  3704. ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
  3705. if (ximage == (XImage *) NULL)
  3706. return(MagickFalse);
  3707. color.pixel=XGetPixel(ximage,0,0);
  3708. XDestroyImage(ximage);
  3709. /*
  3710. Match color against the color database.
  3711. */
  3712. (void) XQueryColor(display,window_attributes.colormap,&color);
  3713. pixel.red=(double) ScaleShortToQuantum(color.red);
  3714. pixel.green=(double) ScaleShortToQuantum(color.green);
  3715. pixel.blue=(double) ScaleShortToQuantum(color.blue);
  3716. pixel.alpha=(MagickRealType) OpaqueAlpha;
  3717. (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
  3718. exception);
  3719. return(MagickTrue);
  3720. }
  3721. /*
  3722. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3723. % %
  3724. % %
  3725. % %
  3726. + X G e t W i n d o w I m a g e %
  3727. % %
  3728. % %
  3729. % %
  3730. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3731. %
  3732. % XGetWindowImage() reads an image from the target X window and returns it.
  3733. % XGetWindowImage() optionally descends the window hierarchy and overlays the
  3734. % target image with each child image in an optimized fashion. Any child
  3735. % window that have the same visual, colormap, and are contained by its parent
  3736. % are exempted.
  3737. %
  3738. % The format of the XGetWindowImage method is:
  3739. %
  3740. % Image *XGetWindowImage(Display *display,const Window window,
  3741. % const unsigned int borders,const unsigned int level,
  3742. % ExceptionInfo *exception)
  3743. %
  3744. % A description of each parameter follows:
  3745. %
  3746. % o display: Specifies a connection to an X server; returned from
  3747. % XOpenDisplay.
  3748. %
  3749. % o window: Specifies the window to obtain the image from.
  3750. %
  3751. % o borders: Specifies whether borders pixels are to be saved with
  3752. % the image.
  3753. %
  3754. % o level: Specifies an unsigned integer representing the level of
  3755. % decent in the window hierarchy. This value must be zero or one on
  3756. % the initial call to XGetWindowImage. A value of zero returns after
  3757. % one call. A value of one causes the function to descend the window
  3758. % hierarchy and overlay the target image with each subwindow image.
  3759. %
  3760. % o exception: return any errors or warnings in this structure.
  3761. %
  3762. */
  3763. static Image *XGetWindowImage(Display *display,const Window window,
  3764. const unsigned int borders,const unsigned int level,ExceptionInfo *exception)
  3765. {
  3766. typedef struct _ColormapInfo
  3767. {
  3768. Colormap
  3769. colormap;
  3770. XColor
  3771. *colors;
  3772. struct _ColormapInfo
  3773. *next;
  3774. } ColormapInfo;
  3775. typedef struct _WindowInfo
  3776. {
  3777. Window
  3778. window,
  3779. parent;
  3780. Visual
  3781. *visual;
  3782. Colormap
  3783. colormap;
  3784. XSegment
  3785. bounds;
  3786. RectangleInfo
  3787. crop_info;
  3788. } WindowInfo;
  3789. int
  3790. display_height,
  3791. display_width,
  3792. id,
  3793. x_offset,
  3794. y_offset;
  3795. Quantum
  3796. index;
  3797. RectangleInfo
  3798. crop_info;
  3799. register int
  3800. i;
  3801. static ColormapInfo
  3802. *colormap_info = (ColormapInfo *) NULL;
  3803. static int
  3804. max_windows = 0,
  3805. number_windows = 0;
  3806. static WindowInfo
  3807. *window_info;
  3808. Status
  3809. status;
  3810. Window
  3811. child,
  3812. root_window;
  3813. XWindowAttributes
  3814. window_attributes;
  3815. /*
  3816. Verify window is viewable.
  3817. */
  3818. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  3819. assert(display != (Display *) NULL);
  3820. status=XGetWindowAttributes(display,window,&window_attributes);
  3821. if ((status == False) || (window_attributes.map_state != IsViewable))
  3822. return((Image *) NULL);
  3823. /*
  3824. Cropping rectangle is relative to root window.
  3825. */
  3826. root_window=XRootWindow(display,XDefaultScreen(display));
  3827. (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
  3828. &y_offset,&child);
  3829. crop_info.x=(ssize_t) x_offset;
  3830. crop_info.y=(ssize_t) y_offset;
  3831. crop_info.width=(size_t) window_attributes.width;
  3832. crop_info.height=(size_t) window_attributes.height;
  3833. if (borders != MagickFalse)
  3834. {
  3835. /*
  3836. Include border in image.
  3837. */
  3838. crop_info.x-=(ssize_t) window_attributes.border_width;
  3839. crop_info.y-=(ssize_t) window_attributes.border_width;
  3840. crop_info.width+=(size_t) (window_attributes.border_width << 1);
  3841. crop_info.height+=(size_t) (window_attributes.border_width << 1);
  3842. }
  3843. /*
  3844. Crop to root window.
  3845. */
  3846. if (crop_info.x < 0)
  3847. {
  3848. crop_info.width+=crop_info.x;
  3849. crop_info.x=0;
  3850. }
  3851. if (crop_info.y < 0)
  3852. {
  3853. crop_info.height+=crop_info.y;
  3854. crop_info.y=0;
  3855. }
  3856. display_width=XDisplayWidth(display,XDefaultScreen(display));
  3857. if ((int) (crop_info.x+crop_info.width) > display_width)
  3858. crop_info.width=(size_t) (display_width-crop_info.x);
  3859. display_height=XDisplayHeight(display,XDefaultScreen(display));
  3860. if ((int) (crop_info.y+crop_info.height) > display_height)
  3861. crop_info.height=(size_t) (display_height-crop_info.y);
  3862. /*
  3863. Initialize window info attributes.
  3864. */
  3865. if (number_windows >= max_windows)
  3866. {
  3867. /*
  3868. Allocate or resize window info buffer.
  3869. */
  3870. max_windows+=1024;
  3871. if (window_info == (WindowInfo *) NULL)
  3872. window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows,
  3873. sizeof(*window_info));
  3874. else
  3875. window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t)
  3876. max_windows,sizeof(*window_info));
  3877. }
  3878. if (window_info == (WindowInfo *) NULL)
  3879. {
  3880. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed","...");
  3881. return((Image *) NULL);
  3882. }
  3883. id=number_windows++;
  3884. window_info[id].window=window;
  3885. window_info[id].visual=window_attributes.visual;
  3886. window_info[id].colormap=window_attributes.colormap;
  3887. window_info[id].bounds.x1=(short) crop_info.x;
  3888. window_info[id].bounds.y1=(short) crop_info.y;
  3889. window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
  3890. window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
  3891. crop_info.x-=x_offset;
  3892. crop_info.y-=y_offset;
  3893. window_info[id].crop_info=crop_info;
  3894. if (level != 0)
  3895. {
  3896. unsigned int
  3897. number_children;
  3898. Window
  3899. *children;
  3900. /*
  3901. Descend the window hierarchy.
  3902. */
  3903. status=XQueryTree(display,window,&root_window,&window_info[id].parent,
  3904. &children,&number_children);
  3905. for (i=0; i < id; i++)
  3906. if ((window_info[i].window == window_info[id].parent) &&
  3907. (window_info[i].visual == window_info[id].visual) &&
  3908. (window_info[i].colormap == window_info[id].colormap))
  3909. {
  3910. if ((window_info[id].bounds.x1 < window_info[i].bounds.x1) ||
  3911. (window_info[id].bounds.x2 > window_info[i].bounds.x2) ||
  3912. (window_info[id].bounds.y1 < window_info[i].bounds.y1) ||
  3913. (window_info[id].bounds.y2 > window_info[i].bounds.y2))
  3914. {
  3915. /*
  3916. Eliminate windows not circumscribed by their parent.
  3917. */
  3918. number_windows--;
  3919. break;
  3920. }
  3921. }
  3922. if ((status == True) && (number_children != 0))
  3923. {
  3924. for (i=0; i < (int) number_children; i++)
  3925. (void) XGetWindowImage(display,children[i],MagickFalse,level+1,
  3926. exception);
  3927. (void) XFree((void *) children);
  3928. }
  3929. }
  3930. if (level <= 1)
  3931. {
  3932. CacheView
  3933. *composite_view;
  3934. ColormapInfo
  3935. *next;
  3936. Image
  3937. *composite_image,
  3938. *image;
  3939. int
  3940. y;
  3941. MagickBooleanType
  3942. import;
  3943. register int
  3944. j,
  3945. x;
  3946. register Quantum
  3947. *magick_restrict q;
  3948. register size_t
  3949. pixel;
  3950. unsigned int
  3951. number_colors;
  3952. XColor
  3953. *colors;
  3954. XImage
  3955. *ximage;
  3956. /*
  3957. Get X image for each window in the list.
  3958. */
  3959. image=NewImageList();
  3960. for (id=0; id < number_windows; id++)
  3961. {
  3962. /*
  3963. Does target window intersect top level window?
  3964. */
  3965. import=((window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
  3966. (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
  3967. (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
  3968. (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ?
  3969. MagickTrue : MagickFalse;
  3970. /*
  3971. Is target window contained by another window with the same colormap?
  3972. */
  3973. for (j=0; j < id; j++)
  3974. if ((window_info[id].visual == window_info[j].visual) &&
  3975. (window_info[id].colormap == window_info[j].colormap))
  3976. {
  3977. if ((window_info[id].bounds.x1 >= window_info[j].bounds.x1) &&
  3978. (window_info[id].bounds.x2 <= window_info[j].bounds.x2) &&
  3979. (window_info[id].bounds.y1 >= window_info[j].bounds.y1) &&
  3980. (window_info[id].bounds.y2 <= window_info[j].bounds.y2))
  3981. import=MagickFalse;
  3982. }
  3983. if (import == MagickFalse)
  3984. continue;
  3985. /*
  3986. Get X image.
  3987. */
  3988. ximage=XGetImage(display,window_info[id].window,(int)
  3989. window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
  3990. (unsigned int) window_info[id].crop_info.width,(unsigned int)
  3991. window_info[id].crop_info.height,AllPlanes,ZPixmap);
  3992. if (ximage == (XImage *) NULL)
  3993. continue;
  3994. /*
  3995. Initialize window colormap.
  3996. */
  3997. number_colors=0;
  3998. colors=(XColor *) NULL;
  3999. if (window_info[id].colormap != (Colormap) NULL)
  4000. {
  4001. ColormapInfo
  4002. *p;
  4003. /*
  4004. Search colormap list for window colormap.
  4005. */
  4006. number_colors=(unsigned int) window_info[id].visual->map_entries;
  4007. for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
  4008. if (p->colormap == window_info[id].colormap)
  4009. break;
  4010. if (p == (ColormapInfo *) NULL)
  4011. {
  4012. /*
  4013. Get the window colormap.
  4014. */
  4015. colors=(XColor *) AcquireQuantumMemory(number_colors,
  4016. sizeof(*colors));
  4017. if (colors == (XColor *) NULL)
  4018. {
  4019. XDestroyImage(ximage);
  4020. return((Image *) NULL);
  4021. }
  4022. if ((window_info[id].visual->klass != DirectColor) &&
  4023. (window_info[id].visual->klass != TrueColor))
  4024. for (i=0; i < (int) number_colors; i++)
  4025. {
  4026. colors[i].pixel=(size_t) i;
  4027. colors[i].pad='\0';
  4028. }
  4029. else
  4030. {
  4031. size_t
  4032. blue,
  4033. blue_bit,
  4034. green,
  4035. green_bit,
  4036. red,
  4037. red_bit;
  4038. /*
  4039. DirectColor or TrueColor visual.
  4040. */
  4041. red=0;
  4042. green=0;
  4043. blue=0;
  4044. red_bit=window_info[id].visual->red_mask &
  4045. (~(window_info[id].visual->red_mask)+1);
  4046. green_bit=window_info[id].visual->green_mask &
  4047. (~(window_info[id].visual->green_mask)+1);
  4048. blue_bit=window_info[id].visual->blue_mask &
  4049. (~(window_info[id].visual->blue_mask)+1);
  4050. for (i=0; i < (int) number_colors; i++)
  4051. {
  4052. colors[i].pixel=(unsigned long) (red | green | blue);
  4053. colors[i].pad='\0';
  4054. red+=red_bit;
  4055. if (red > window_info[id].visual->red_mask)
  4056. red=0;
  4057. green+=green_bit;
  4058. if (green > window_info[id].visual->green_mask)
  4059. green=0;
  4060. blue+=blue_bit;
  4061. if (blue > window_info[id].visual->blue_mask)
  4062. blue=0;
  4063. }
  4064. }
  4065. (void) XQueryColors(display,window_info[id].colormap,colors,
  4066. (int) number_colors);
  4067. /*
  4068. Append colormap to colormap list.
  4069. */
  4070. p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p));
  4071. if (p == (ColormapInfo *) NULL)
  4072. return((Image *) NULL);
  4073. p->colormap=window_info[id].colormap;
  4074. p->colors=colors;
  4075. p->next=colormap_info;
  4076. colormap_info=p;
  4077. }
  4078. colors=p->colors;
  4079. }
  4080. /*
  4081. Allocate image structure.
  4082. */
  4083. composite_image=AcquireImage((ImageInfo *) NULL,exception);
  4084. if (composite_image == (Image *) NULL)
  4085. {
  4086. XDestroyImage(ximage);
  4087. return((Image *) NULL);
  4088. }
  4089. /*
  4090. Convert X image to MIFF format.
  4091. */
  4092. if ((window_info[id].visual->klass != TrueColor) &&
  4093. (window_info[id].visual->klass != DirectColor))
  4094. composite_image->storage_class=PseudoClass;
  4095. composite_image->columns=(size_t) ximage->width;
  4096. composite_image->rows=(size_t) ximage->height;
  4097. composite_view=AcquireAuthenticCacheView(composite_image,exception);
  4098. switch (composite_image->storage_class)
  4099. {
  4100. case DirectClass:
  4101. default:
  4102. {
  4103. register size_t
  4104. color,
  4105. index;
  4106. size_t
  4107. blue_mask,
  4108. blue_shift,
  4109. green_mask,
  4110. green_shift,
  4111. red_mask,
  4112. red_shift;
  4113. /*
  4114. Determine shift and mask for red, green, and blue.
  4115. */
  4116. red_mask=window_info[id].visual->red_mask;
  4117. red_shift=0;
  4118. while ((red_mask != 0) && ((red_mask & 0x01) == 0))
  4119. {
  4120. red_mask>>=1;
  4121. red_shift++;
  4122. }
  4123. green_mask=window_info[id].visual->green_mask;
  4124. green_shift=0;
  4125. while ((green_mask != 0) && ((green_mask & 0x01) == 0))
  4126. {
  4127. green_mask>>=1;
  4128. green_shift++;
  4129. }
  4130. blue_mask=window_info[id].visual->blue_mask;
  4131. blue_shift=0;
  4132. while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
  4133. {
  4134. blue_mask>>=1;
  4135. blue_shift++;
  4136. }
  4137. /*
  4138. Convert X image to DirectClass packets.
  4139. */
  4140. if ((number_colors != 0) &&
  4141. (window_info[id].visual->klass == DirectColor))
  4142. for (y=0; y < (int) composite_image->rows; y++)
  4143. {
  4144. q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
  4145. composite_image->columns,1,exception);
  4146. if (q == (Quantum *) NULL)
  4147. break;
  4148. for (x=0; x < (int) composite_image->columns; x++)
  4149. {
  4150. pixel=XGetPixel(ximage,x,y);
  4151. index=(pixel >> red_shift) & red_mask;
  4152. SetPixelRed(composite_image,
  4153. ScaleShortToQuantum(colors[index].red),q);
  4154. index=(pixel >> green_shift) & green_mask;
  4155. SetPixelGreen(composite_image,
  4156. ScaleShortToQuantum(colors[index].green),q);
  4157. index=(pixel >> blue_shift) & blue_mask;
  4158. SetPixelBlue(composite_image,
  4159. ScaleShortToQuantum(colors[index].blue),q);
  4160. q+=GetPixelChannels(composite_image);
  4161. }
  4162. status=SyncCacheViewAuthenticPixels(composite_view,exception);
  4163. if (status == MagickFalse)
  4164. break;
  4165. }
  4166. else
  4167. for (y=0; y < (int) composite_image->rows; y++)
  4168. {
  4169. q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
  4170. composite_image->columns,1,exception);
  4171. if (q == (Quantum *) NULL)
  4172. break;
  4173. for (x=0; x < (int) composite_image->columns; x++)
  4174. {
  4175. pixel=XGetPixel(ximage,x,y);
  4176. color=(pixel >> red_shift) & red_mask;
  4177. if (red_mask != 0)
  4178. color=(65535UL*color)/red_mask;
  4179. SetPixelRed(composite_image,ScaleShortToQuantum(
  4180. (unsigned short) color),q);
  4181. color=(pixel >> green_shift) & green_mask;
  4182. if (green_mask != 0)
  4183. color=(65535UL*color)/green_mask;
  4184. SetPixelGreen(composite_image,ScaleShortToQuantum(
  4185. (unsigned short) color),q);
  4186. color=(pixel >> blue_shift) & blue_mask;
  4187. if (blue_mask != 0)
  4188. color=(65535UL*color)/blue_mask;
  4189. SetPixelBlue(composite_image,ScaleShortToQuantum(
  4190. (unsigned short) color),q);
  4191. q+=GetPixelChannels(composite_image);
  4192. }
  4193. status=SyncCacheViewAuthenticPixels(composite_view,exception);
  4194. if (status == MagickFalse)
  4195. break;
  4196. }
  4197. break;
  4198. }
  4199. case PseudoClass:
  4200. {
  4201. /*
  4202. Create colormap.
  4203. */
  4204. status=AcquireImageColormap(composite_image,number_colors,
  4205. exception);
  4206. if (status == MagickFalse)
  4207. {
  4208. XDestroyImage(ximage);
  4209. composite_image=DestroyImage(composite_image);
  4210. return((Image *) NULL);
  4211. }
  4212. for (i=0; i < (int) composite_image->colors; i++)
  4213. {
  4214. composite_image->colormap[colors[i].pixel].red=(double)
  4215. ScaleShortToQuantum(colors[i].red);
  4216. composite_image->colormap[colors[i].pixel].green=(double)
  4217. ScaleShortToQuantum(colors[i].green);
  4218. composite_image->colormap[colors[i].pixel].blue=(double)
  4219. ScaleShortToQuantum(colors[i].blue);
  4220. }
  4221. /*
  4222. Convert X image to PseudoClass packets.
  4223. */
  4224. for (y=0; y < (int) composite_image->rows; y++)
  4225. {
  4226. q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
  4227. composite_image->columns,1,exception);
  4228. if (q == (Quantum *) NULL)
  4229. break;
  4230. for (x=0; x < (int) composite_image->columns; x++)
  4231. {
  4232. index=(Quantum) XGetPixel(ximage,x,y);
  4233. SetPixelIndex(composite_image,index,q);
  4234. SetPixelViaPixelInfo(composite_image,
  4235. composite_image->colormap+(ssize_t) index,q);
  4236. q+=GetPixelChannels(composite_image);
  4237. }
  4238. status=SyncCacheViewAuthenticPixels(composite_view,exception);
  4239. if (status == MagickFalse)
  4240. break;
  4241. }
  4242. break;
  4243. }
  4244. }
  4245. composite_view=DestroyCacheView(composite_view);
  4246. XDestroyImage(ximage);
  4247. if (image == (Image *) NULL)
  4248. {
  4249. image=composite_image;
  4250. continue;
  4251. }
  4252. /*
  4253. Composite any children in back-to-front order.
  4254. */
  4255. (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
  4256. &x_offset,&y_offset,&child);
  4257. x_offset-=(int) crop_info.x;
  4258. if (x_offset < 0)
  4259. x_offset=0;
  4260. y_offset-=(int) crop_info.y;
  4261. if (y_offset < 0)
  4262. y_offset=0;
  4263. (void) CompositeImage(image,composite_image,CopyCompositeOp,MagickTrue,
  4264. (ssize_t) x_offset,(ssize_t) y_offset,exception);
  4265. composite_image=DestroyImage(composite_image);
  4266. }
  4267. /*
  4268. Relinquish resources.
  4269. */
  4270. while (colormap_info != (ColormapInfo *) NULL)
  4271. {
  4272. next=colormap_info->next;
  4273. colormap_info->colors=(XColor *) RelinquishMagickMemory(
  4274. colormap_info->colors);
  4275. colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info);
  4276. colormap_info=next;
  4277. }
  4278. /*
  4279. Relinquish resources and restore initial state.
  4280. */
  4281. window_info=(WindowInfo *) RelinquishMagickMemory(window_info);
  4282. max_windows=0;
  4283. number_windows=0;
  4284. colormap_info=(ColormapInfo *) NULL;
  4285. return(image);
  4286. }
  4287. return((Image *) NULL);
  4288. }
  4289. /*
  4290. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4291. % %
  4292. % %
  4293. % %
  4294. % X G e t W i n d o w I n f o %
  4295. % %
  4296. % %
  4297. % %
  4298. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4299. %
  4300. % XGetWindowInfo() initializes the XWindowInfo structure.
  4301. %
  4302. % The format of the XGetWindowInfo method is:
  4303. %
  4304. % void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
  4305. % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
  4306. % XResourceInfo *resource_info,XWindowInfo *window)
  4307. % resource_info,window)
  4308. %
  4309. % A description of each parameter follows:
  4310. %
  4311. % o display: Specifies a connection to an X server; returned from
  4312. % XOpenDisplay.
  4313. %
  4314. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  4315. % returned from XGetVisualInfo.
  4316. %
  4317. % o map_info: If map_type is specified, this structure is initialized
  4318. % with info from the Standard Colormap.
  4319. %
  4320. % o pixel: Specifies a pointer to a XPixelInfo structure.
  4321. %
  4322. % o font_info: Specifies a pointer to a XFontStruct structure.
  4323. %
  4324. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  4325. %
  4326. */
  4327. MagickPrivate void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
  4328. XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
  4329. XResourceInfo *resource_info,XWindowInfo *window)
  4330. {
  4331. /*
  4332. Initialize window info.
  4333. */
  4334. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  4335. assert(display != (Display *) NULL);
  4336. assert(visual_info != (XVisualInfo *) NULL);
  4337. assert(map_info != (XStandardColormap *) NULL);
  4338. assert(pixel != (XPixelInfo *) NULL);
  4339. assert(resource_info != (XResourceInfo *) NULL);
  4340. assert(window != (XWindowInfo *) NULL);
  4341. if (window->id != (Window) NULL)
  4342. {
  4343. if (window->cursor != (Cursor) NULL)
  4344. (void) XFreeCursor(display,window->cursor);
  4345. if (window->busy_cursor != (Cursor) NULL)
  4346. (void) XFreeCursor(display,window->busy_cursor);
  4347. if (window->highlight_stipple != (Pixmap) NULL)
  4348. (void) XFreePixmap(display,window->highlight_stipple);
  4349. if (window->shadow_stipple != (Pixmap) NULL)
  4350. (void) XFreePixmap(display,window->shadow_stipple);
  4351. if (window->name == (char *) NULL)
  4352. window->name=AcquireString("");
  4353. if (window->icon_name == (char *) NULL)
  4354. window->icon_name=AcquireString("");
  4355. }
  4356. else
  4357. {
  4358. /*
  4359. Initialize these attributes just once.
  4360. */
  4361. window->id=(Window) NULL;
  4362. if (window->name == (char *) NULL)
  4363. window->name=AcquireString("");
  4364. if (window->icon_name == (char *) NULL)
  4365. window->icon_name=AcquireString("");
  4366. window->x=XDisplayWidth(display,visual_info->screen) >> 1;
  4367. window->y=XDisplayWidth(display,visual_info->screen) >> 1;
  4368. window->ximage=(XImage *) NULL;
  4369. window->matte_image=(XImage *) NULL;
  4370. window->pixmap=(Pixmap) NULL;
  4371. window->matte_pixmap=(Pixmap) NULL;
  4372. window->mapped=MagickFalse;
  4373. window->stasis=MagickFalse;
  4374. window->shared_memory=MagickTrue;
  4375. window->segment_info=(void *) NULL;
  4376. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  4377. {
  4378. XShmSegmentInfo
  4379. *segment_info;
  4380. if (window->segment_info == (void *) NULL)
  4381. window->segment_info=AcquireCriticalMemory(2*sizeof(*segment_info));
  4382. segment_info=(XShmSegmentInfo *) window->segment_info;
  4383. segment_info[0].shmid=(-1);
  4384. segment_info[0].shmaddr=(char *) NULL;
  4385. segment_info[1].shmid=(-1);
  4386. segment_info[1].shmaddr=(char *) NULL;
  4387. }
  4388. #endif
  4389. }
  4390. /*
  4391. Initialize these attributes every time function is called.
  4392. */
  4393. window->screen=visual_info->screen;
  4394. window->root=XRootWindow(display,visual_info->screen);
  4395. window->visual=visual_info->visual;
  4396. window->storage_class=(unsigned int) visual_info->klass;
  4397. window->depth=(unsigned int) visual_info->depth;
  4398. window->visual_info=visual_info;
  4399. window->map_info=map_info;
  4400. window->pixel_info=pixel;
  4401. window->font_info=font_info;
  4402. window->cursor=XCreateFontCursor(display,XC_left_ptr);
  4403. window->busy_cursor=XCreateFontCursor(display,XC_watch);
  4404. window->geometry=(char *) NULL;
  4405. window->icon_geometry=(char *) NULL;
  4406. if (resource_info->icon_geometry != (char *) NULL)
  4407. (void) CloneString(&window->icon_geometry,resource_info->icon_geometry);
  4408. window->crop_geometry=(char *) NULL;
  4409. window->flags=(size_t) PSize;
  4410. window->width=1;
  4411. window->height=1;
  4412. window->min_width=1;
  4413. window->min_height=1;
  4414. window->width_inc=1;
  4415. window->height_inc=1;
  4416. window->border_width=resource_info->border_width;
  4417. window->annotate_context=pixel->annotate_context;
  4418. window->highlight_context=pixel->highlight_context;
  4419. window->widget_context=pixel->widget_context;
  4420. window->shadow_stipple=(Pixmap) NULL;
  4421. window->highlight_stipple=(Pixmap) NULL;
  4422. window->use_pixmap=MagickTrue;
  4423. window->immutable=MagickFalse;
  4424. window->shape=MagickFalse;
  4425. window->data=0;
  4426. window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap |
  4427. CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate |
  4428. CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity);
  4429. window->attributes.background_pixel=pixel->background_color.pixel;
  4430. window->attributes.background_pixmap=(Pixmap) NULL;
  4431. window->attributes.bit_gravity=ForgetGravity;
  4432. window->attributes.backing_store=WhenMapped;
  4433. window->attributes.save_under=MagickTrue;
  4434. window->attributes.border_pixel=pixel->border_color.pixel;
  4435. window->attributes.colormap=map_info->colormap;
  4436. window->attributes.cursor=window->cursor;
  4437. window->attributes.do_not_propagate_mask=NoEventMask;
  4438. window->attributes.event_mask=NoEventMask;
  4439. window->attributes.override_redirect=MagickFalse;
  4440. window->attributes.win_gravity=NorthWestGravity;
  4441. window->orphan=MagickFalse;
  4442. }
  4443. /*
  4444. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4445. % %
  4446. % %
  4447. % %
  4448. % X H i g h l i g h t E l l i p s e %
  4449. % %
  4450. % %
  4451. % %
  4452. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4453. %
  4454. % XHighlightEllipse() puts a border on the X server around a region defined by
  4455. % highlight_info.
  4456. %
  4457. % The format of the XHighlightEllipse method is:
  4458. %
  4459. % void XHighlightEllipse(Display *display,Window window,
  4460. % GC annotate_context,const RectangleInfo *highlight_info)
  4461. %
  4462. % A description of each parameter follows:
  4463. %
  4464. % o display: Specifies a connection to an X server; returned from
  4465. % XOpenDisplay.
  4466. %
  4467. % o window: Specifies a pointer to a Window structure.
  4468. %
  4469. % o annotate_context: Specifies a pointer to a GC structure.
  4470. %
  4471. % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
  4472. % contains the extents of any highlighting rectangle.
  4473. %
  4474. */
  4475. MagickPrivate void XHighlightEllipse(Display *display,Window window,
  4476. GC annotate_context,const RectangleInfo *highlight_info)
  4477. {
  4478. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  4479. assert(display != (Display *) NULL);
  4480. assert(window != (Window) NULL);
  4481. assert(annotate_context != (GC) NULL);
  4482. assert(highlight_info != (RectangleInfo *) NULL);
  4483. if ((highlight_info->width < 4) || (highlight_info->height < 4))
  4484. return;
  4485. (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
  4486. (int) highlight_info->y,(unsigned int) highlight_info->width-1,
  4487. (unsigned int) highlight_info->height-1,0,360*64);
  4488. (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
  4489. (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
  4490. (unsigned int) highlight_info->height-3,0,360*64);
  4491. }
  4492. /*
  4493. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4494. % %
  4495. % %
  4496. % %
  4497. % X H i g h l i g h t L i n e %
  4498. % %
  4499. % %
  4500. % %
  4501. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4502. %
  4503. % XHighlightLine() puts a border on the X server around a region defined by
  4504. % highlight_info.
  4505. %
  4506. % The format of the XHighlightLine method is:
  4507. %
  4508. % void XHighlightLine(Display *display,Window window,GC annotate_context,
  4509. % const XSegment *highlight_info)
  4510. %
  4511. % A description of each parameter follows:
  4512. %
  4513. % o display: Specifies a connection to an X server; returned from
  4514. % XOpenDisplay.
  4515. %
  4516. % o window: Specifies a pointer to a Window structure.
  4517. %
  4518. % o annotate_context: Specifies a pointer to a GC structure.
  4519. %
  4520. % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
  4521. % contains the extents of any highlighting rectangle.
  4522. %
  4523. */
  4524. MagickPrivate void XHighlightLine(Display *display,Window window,
  4525. GC annotate_context,const XSegment *highlight_info)
  4526. {
  4527. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  4528. assert(display != (Display *) NULL);
  4529. assert(window != (Window) NULL);
  4530. assert(annotate_context != (GC) NULL);
  4531. assert(highlight_info != (XSegment *) NULL);
  4532. (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
  4533. highlight_info->y1,highlight_info->x2,highlight_info->y2);
  4534. }
  4535. /*
  4536. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4537. % %
  4538. % %
  4539. % %
  4540. % X H i g h l i g h t R e c t a n g l e %
  4541. % %
  4542. % %
  4543. % %
  4544. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4545. %
  4546. % XHighlightRectangle() puts a border on the X server around a region defined
  4547. % by highlight_info.
  4548. %
  4549. % The format of the XHighlightRectangle method is:
  4550. %
  4551. % void XHighlightRectangle(Display *display,Window window,
  4552. % GC annotate_context,const RectangleInfo *highlight_info)
  4553. %
  4554. % A description of each parameter follows:
  4555. %
  4556. % o display: Specifies a connection to an X server; returned from
  4557. % XOpenDisplay.
  4558. %
  4559. % o window: Specifies a pointer to a Window structure.
  4560. %
  4561. % o annotate_context: Specifies a pointer to a GC structure.
  4562. %
  4563. % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
  4564. % contains the extents of any highlighting rectangle.
  4565. %
  4566. */
  4567. MagickPrivate void XHighlightRectangle(Display *display,Window window,
  4568. GC annotate_context,const RectangleInfo *highlight_info)
  4569. {
  4570. assert(display != (Display *) NULL);
  4571. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  4572. assert(window != (Window) NULL);
  4573. assert(annotate_context != (GC) NULL);
  4574. assert(highlight_info != (RectangleInfo *) NULL);
  4575. if ((highlight_info->width < 4) || (highlight_info->height < 4))
  4576. return;
  4577. (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
  4578. (int) highlight_info->y,(unsigned int) highlight_info->width-1,
  4579. (unsigned int) highlight_info->height-1);
  4580. (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
  4581. 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
  4582. (unsigned int) highlight_info->height-3);
  4583. }
  4584. /*
  4585. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4586. % %
  4587. % %
  4588. % %
  4589. % X I m p o r t I m a g e %
  4590. % %
  4591. % %
  4592. % %
  4593. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4594. %
  4595. % XImportImage() reads an image from an X window.
  4596. %
  4597. % The format of the XImportImage method is:
  4598. %
  4599. % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
  4600. % ExceptionInfo *exception)
  4601. %
  4602. % A description of each parameter follows:
  4603. %
  4604. % o image_info: the image info.
  4605. %
  4606. % o ximage_info: Specifies a pointer to an XImportInfo structure.
  4607. %
  4608. % o exception: return any errors or warnings in this structure.
  4609. %
  4610. */
  4611. MagickExport Image *XImportImage(const ImageInfo *image_info,
  4612. XImportInfo *ximage_info,ExceptionInfo *exception)
  4613. {
  4614. Colormap
  4615. *colormaps;
  4616. Display
  4617. *display;
  4618. Image
  4619. *image;
  4620. int
  4621. number_colormaps,
  4622. number_windows,
  4623. x;
  4624. RectangleInfo
  4625. crop_info;
  4626. Status
  4627. status;
  4628. Window
  4629. *children,
  4630. client,
  4631. prior_target,
  4632. root,
  4633. target;
  4634. XTextProperty
  4635. window_name;
  4636. /*
  4637. Open X server connection.
  4638. */
  4639. assert(image_info != (const ImageInfo *) NULL);
  4640. assert(image_info->signature == MagickCoreSignature);
  4641. if (image_info->debug != MagickFalse)
  4642. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
  4643. image_info->filename);
  4644. assert(ximage_info != (XImportInfo *) NULL);
  4645. display=XOpenDisplay(image_info->server_name);
  4646. if (display == (Display *) NULL)
  4647. {
  4648. ThrowXWindowException(XServerError,"UnableToOpenXServer",
  4649. XDisplayName(image_info->server_name));
  4650. return((Image *) NULL);
  4651. }
  4652. /*
  4653. Set our forgiving exception handler.
  4654. */
  4655. (void) XSetErrorHandler(XError);
  4656. /*
  4657. Select target window.
  4658. */
  4659. crop_info.x=0;
  4660. crop_info.y=0;
  4661. crop_info.width=0;
  4662. crop_info.height=0;
  4663. root=XRootWindow(display,XDefaultScreen(display));
  4664. target=(Window) NULL;
  4665. if (*image_info->filename != '\0')
  4666. {
  4667. if (LocaleCompare(image_info->filename,"root") == 0)
  4668. target=root;
  4669. else
  4670. {
  4671. /*
  4672. Select window by ID or name.
  4673. */
  4674. if (isdigit((int) ((unsigned char) *image_info->filename)) != 0)
  4675. target=XWindowByID(display,root,(Window)
  4676. strtol(image_info->filename,(char **) NULL,0));
  4677. if (target == (Window) NULL)
  4678. target=XWindowByName(display,root,image_info->filename);
  4679. if (target == (Window) NULL)
  4680. ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists",
  4681. image_info->filename);
  4682. }
  4683. }
  4684. /*
  4685. If target window is not defined, interactively select one.
  4686. */
  4687. prior_target=target;
  4688. if (target == (Window) NULL)
  4689. target=XSelectWindow(display,&crop_info);
  4690. if (target == (Window) NULL)
  4691. ThrowXWindowException(XServerError,"UnableToReadXWindowImage",
  4692. image_info->filename);
  4693. client=target; /* obsolete */
  4694. if (target != root)
  4695. {
  4696. unsigned int
  4697. d;
  4698. status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
  4699. if (status != False)
  4700. {
  4701. for ( ; ; )
  4702. {
  4703. Window
  4704. parent;
  4705. /*
  4706. Find window manager frame.
  4707. */
  4708. status=XQueryTree(display,target,&root,&parent,&children,&d);
  4709. if ((status != False) && (children != (Window *) NULL))
  4710. (void) XFree((char *) children);
  4711. if ((status == False) || (parent == (Window) NULL) ||
  4712. (parent == root))
  4713. break;
  4714. target=parent;
  4715. }
  4716. /*
  4717. Get client window.
  4718. */
  4719. client=XClientWindow(display,target);
  4720. if (ximage_info->frame == MagickFalse)
  4721. target=client;
  4722. if ((ximage_info->frame == MagickFalse) &&
  4723. (prior_target != MagickFalse))
  4724. target=prior_target;
  4725. }
  4726. }
  4727. if (ximage_info->screen)
  4728. {
  4729. int
  4730. y;
  4731. Window
  4732. child;
  4733. XWindowAttributes
  4734. window_attributes;
  4735. /*
  4736. Obtain window image directly from screen.
  4737. */
  4738. status=XGetWindowAttributes(display,target,&window_attributes);
  4739. if (status == False)
  4740. {
  4741. ThrowXWindowException(XServerError,"UnableToReadXWindowAttributes",
  4742. image_info->filename);
  4743. (void) XCloseDisplay(display);
  4744. return((Image *) NULL);
  4745. }
  4746. (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
  4747. crop_info.x=(ssize_t) x;
  4748. crop_info.y=(ssize_t) y;
  4749. crop_info.width=(size_t) window_attributes.width;
  4750. crop_info.height=(size_t) window_attributes.height;
  4751. if (ximage_info->borders != 0)
  4752. {
  4753. /*
  4754. Include border in image.
  4755. */
  4756. crop_info.x-=window_attributes.border_width;
  4757. crop_info.y-=window_attributes.border_width;
  4758. crop_info.width+=window_attributes.border_width << 1;
  4759. crop_info.height+=window_attributes.border_width << 1;
  4760. }
  4761. target=root;
  4762. }
  4763. /*
  4764. If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
  4765. */
  4766. number_windows=0;
  4767. status=XGetWMColormapWindows(display,target,&children,&number_windows);
  4768. if ((status == True) && (number_windows > 0))
  4769. {
  4770. ximage_info->descend=MagickTrue;
  4771. (void) XFree ((char *) children);
  4772. }
  4773. colormaps=XListInstalledColormaps(display,target,&number_colormaps);
  4774. if (number_colormaps > 0)
  4775. {
  4776. if (number_colormaps > 1)
  4777. ximage_info->descend=MagickTrue;
  4778. (void) XFree((char *) colormaps);
  4779. }
  4780. /*
  4781. Alert the user not to alter the screen.
  4782. */
  4783. if (ximage_info->silent == MagickFalse)
  4784. (void) XBell(display,0);
  4785. /*
  4786. Get image by window id.
  4787. */
  4788. (void) XGrabServer(display);
  4789. image=XGetWindowImage(display,target,ximage_info->borders,
  4790. ximage_info->descend ? 1U : 0U,exception);
  4791. (void) XUngrabServer(display);
  4792. if (image == (Image *) NULL)
  4793. ThrowXWindowException(XServerError,"UnableToReadXWindowImage",
  4794. image_info->filename)
  4795. else
  4796. {
  4797. (void) CopyMagickString(image->filename,image_info->filename,
  4798. MagickPathExtent);
  4799. if ((crop_info.width != 0) && (crop_info.height != 0))
  4800. {
  4801. Image
  4802. *crop_image;
  4803. /*
  4804. Crop image as defined by the cropping rectangle.
  4805. */
  4806. crop_image=CropImage(image,&crop_info,exception);
  4807. if (crop_image != (Image *) NULL)
  4808. {
  4809. image=DestroyImage(image);
  4810. image=crop_image;
  4811. }
  4812. }
  4813. status=XGetWMName(display,target,&window_name);
  4814. if (status == True)
  4815. {
  4816. if (*image_info->filename == '\0')
  4817. (void) CopyMagickString(image->filename,(char *) window_name.value,
  4818. (size_t) window_name.nitems+1);
  4819. (void) XFree((void *) window_name.value);
  4820. }
  4821. }
  4822. if (ximage_info->silent == MagickFalse)
  4823. {
  4824. /*
  4825. Alert the user we're done.
  4826. */
  4827. (void) XBell(display,0);
  4828. (void) XBell(display,0);
  4829. }
  4830. (void) XCloseDisplay(display);
  4831. return(image);
  4832. }
  4833. /*
  4834. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4835. % %
  4836. % %
  4837. % %
  4838. % X I n i t i a l i z e W i n d o w s %
  4839. % %
  4840. % %
  4841. % %
  4842. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4843. %
  4844. % XInitializeWindows() initializes the XWindows structure.
  4845. %
  4846. % The format of the XInitializeWindows method is:
  4847. %
  4848. % XWindows *XInitializeWindows(Display *display,
  4849. % XResourceInfo *resource_info)
  4850. %
  4851. % A description of each parameter follows:
  4852. %
  4853. % o windows: XInitializeWindows returns a pointer to a XWindows structure.
  4854. %
  4855. % o display: Specifies a connection to an X server; returned from
  4856. % XOpenDisplay.
  4857. %
  4858. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  4859. %
  4860. */
  4861. MagickPrivate XWindows *XInitializeWindows(Display *display,
  4862. XResourceInfo *resource_info)
  4863. {
  4864. Window
  4865. root_window;
  4866. XWindows
  4867. *windows;
  4868. /*
  4869. Allocate windows structure.
  4870. */
  4871. windows=(XWindows *) AcquireMagickMemory(sizeof(*windows));
  4872. if (windows == (XWindows *) NULL)
  4873. {
  4874. ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
  4875. "...");
  4876. return((XWindows *) NULL);
  4877. }
  4878. (void) memset(windows,0,sizeof(*windows));
  4879. windows->pixel_info=(XPixelInfo *) AcquireMagickMemory(
  4880. sizeof(*windows->pixel_info));
  4881. windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory(
  4882. sizeof(*windows->icon_pixel));
  4883. windows->icon_resources=(XResourceInfo *) AcquireMagickMemory(
  4884. sizeof(*windows->icon_resources));
  4885. if ((windows->pixel_info == (XPixelInfo *) NULL) ||
  4886. (windows->icon_pixel == (XPixelInfo *) NULL) ||
  4887. (windows->icon_resources == (XResourceInfo *) NULL))
  4888. {
  4889. ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
  4890. "...");
  4891. return((XWindows *) NULL);
  4892. }
  4893. /*
  4894. Initialize windows structure.
  4895. */
  4896. windows->display=display;
  4897. windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse);
  4898. windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
  4899. windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
  4900. windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
  4901. windows->im_remote_command=
  4902. XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
  4903. windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse);
  4904. windows->im_update_colormap=
  4905. XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse);
  4906. windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse);
  4907. windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse);
  4908. windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse);
  4909. windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse);
  4910. windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse);
  4911. #if defined(MAGICKCORE_WINDOWS_SUPPORT)
  4912. (void) XSynchronize(display,IsWindows95());
  4913. #endif
  4914. if (IsEventLogging())
  4915. {
  4916. (void) XSynchronize(display,MagickTrue);
  4917. (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
  4918. GetMagickVersion((size_t *) NULL));
  4919. (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
  4920. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4921. " Window Manager: 0x%lx",windows->wm_protocols);
  4922. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4923. " delete window: 0x%lx",windows->wm_delete_window);
  4924. (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx",
  4925. windows->wm_take_focus);
  4926. (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx",
  4927. windows->im_protocols);
  4928. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4929. " remote command: 0x%lx",windows->im_remote_command);
  4930. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4931. " update widget: 0x%lx",windows->im_update_widget);
  4932. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4933. " update colormap: 0x%lx",windows->im_update_colormap);
  4934. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4935. " former image: 0x%lx",windows->im_former_image);
  4936. (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx",
  4937. windows->im_next_image);
  4938. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4939. " retain colors: 0x%lx",windows->im_retain_colors);
  4940. (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx",
  4941. windows->im_exit);
  4942. (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx",
  4943. windows->dnd_protocols);
  4944. }
  4945. /*
  4946. Allocate standard colormap.
  4947. */
  4948. windows->map_info=XAllocStandardColormap();
  4949. windows->icon_map=XAllocStandardColormap();
  4950. if ((windows->map_info == (XStandardColormap *) NULL) ||
  4951. (windows->icon_map == (XStandardColormap *) NULL))
  4952. ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
  4953. "...");
  4954. windows->map_info->colormap=(Colormap) NULL;
  4955. windows->icon_map->colormap=(Colormap) NULL;
  4956. windows->pixel_info->pixels=(unsigned long *) NULL;
  4957. windows->pixel_info->annotate_context=(GC) NULL;
  4958. windows->pixel_info->highlight_context=(GC) NULL;
  4959. windows->pixel_info->widget_context=(GC) NULL;
  4960. windows->font_info=(XFontStruct *) NULL;
  4961. windows->icon_pixel->annotate_context=(GC) NULL;
  4962. windows->icon_pixel->pixels=(unsigned long *) NULL;
  4963. /*
  4964. Allocate visual.
  4965. */
  4966. *windows->icon_resources=(*resource_info);
  4967. windows->icon_resources->visual_type=(char *) "default";
  4968. windows->icon_resources->colormap=SharedColormap;
  4969. windows->visual_info=
  4970. XBestVisualInfo(display,windows->map_info,resource_info);
  4971. windows->icon_visual=
  4972. XBestVisualInfo(display,windows->icon_map,windows->icon_resources);
  4973. if ((windows->visual_info == (XVisualInfo *) NULL) ||
  4974. (windows->icon_visual == (XVisualInfo *) NULL))
  4975. ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
  4976. resource_info->visual_type);
  4977. if (IsEventLogging())
  4978. {
  4979. (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
  4980. (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx",
  4981. windows->visual_info->visualid);
  4982. (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s",
  4983. XVisualClassName(windows->visual_info->klass));
  4984. (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes",
  4985. windows->visual_info->depth);
  4986. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4987. " size of colormap: %d entries",windows->visual_info->colormap_size);
  4988. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4989. " red, green, blue masks: 0x%lx 0x%lx 0x%lx",
  4990. windows->visual_info->red_mask,windows->visual_info->green_mask,
  4991. windows->visual_info->blue_mask);
  4992. (void) LogMagickEvent(X11Event,GetMagickModule(),
  4993. " significant bits in color: %d bits",
  4994. windows->visual_info->bits_per_rgb);
  4995. }
  4996. /*
  4997. Allocate class and manager hints.
  4998. */
  4999. windows->class_hints=XAllocClassHint();
  5000. windows->manager_hints=XAllocWMHints();
  5001. if ((windows->class_hints == (XClassHint *) NULL) ||
  5002. (windows->manager_hints == (XWMHints *) NULL))
  5003. ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
  5004. "...");
  5005. /*
  5006. Determine group leader if we have one.
  5007. */
  5008. root_window=XRootWindow(display,windows->visual_info->screen);
  5009. windows->group_leader.id=(Window) NULL;
  5010. if (resource_info->window_group != (char *) NULL)
  5011. {
  5012. if (isdigit((int) ((unsigned char) *resource_info->window_group)) != 0)
  5013. windows->group_leader.id=XWindowByID(display,root_window,(Window)
  5014. strtol((char *) resource_info->window_group,(char **) NULL,0));
  5015. if (windows->group_leader.id == (Window) NULL)
  5016. windows->group_leader.id=
  5017. XWindowByName(display,root_window,resource_info->window_group);
  5018. }
  5019. return(windows);
  5020. }
  5021. /*
  5022. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5023. % %
  5024. % %
  5025. % %
  5026. % X M a k e C u r s o r %
  5027. % %
  5028. % %
  5029. % %
  5030. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5031. %
  5032. % XMakeCursor() creates a crosshairs X11 cursor.
  5033. %
  5034. % The format of the XMakeCursor method is:
  5035. %
  5036. % Cursor XMakeCursor(Display *display,Window window,Colormap colormap,
  5037. % char *background_color,char *foreground_color)
  5038. %
  5039. % A description of each parameter follows:
  5040. %
  5041. % o display: Specifies a connection to an X server; returned from
  5042. % XOpenDisplay.
  5043. %
  5044. % o window: Specifies the ID of the window for which the cursor is
  5045. % assigned.
  5046. %
  5047. % o colormap: Specifies the ID of the colormap from which the background
  5048. % and foreground color will be retrieved.
  5049. %
  5050. % o background_color: Specifies the color to use for the cursor background.
  5051. %
  5052. % o foreground_color: Specifies the color to use for the cursor foreground.
  5053. %
  5054. */
  5055. MagickPrivate Cursor XMakeCursor(Display *display,Window window,
  5056. Colormap colormap,char *background_color,char *foreground_color)
  5057. {
  5058. #define scope_height 17
  5059. #define scope_x_hot 8
  5060. #define scope_y_hot 8
  5061. #define scope_width 17
  5062. static const unsigned char
  5063. scope_bits[] =
  5064. {
  5065. 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
  5066. 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
  5067. 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
  5068. 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
  5069. 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
  5070. },
  5071. scope_mask_bits[] =
  5072. {
  5073. 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
  5074. 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
  5075. 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
  5076. 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
  5077. 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
  5078. };
  5079. Cursor
  5080. cursor;
  5081. Pixmap
  5082. mask,
  5083. source;
  5084. XColor
  5085. background,
  5086. foreground;
  5087. assert(display != (Display *) NULL);
  5088. assert(window != (Window) NULL);
  5089. assert(colormap != (Colormap) NULL);
  5090. assert(background_color != (char *) NULL);
  5091. assert(foreground_color != (char *) NULL);
  5092. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color);
  5093. source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
  5094. scope_height);
  5095. mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
  5096. scope_width,scope_height);
  5097. if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
  5098. {
  5099. ThrowXWindowException(XServerError,"UnableToCreatePixmap","...");
  5100. return((Cursor) NULL);
  5101. }
  5102. (void) XParseColor(display,colormap,background_color,&background);
  5103. (void) XParseColor(display,colormap,foreground_color,&foreground);
  5104. cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
  5105. scope_x_hot,scope_y_hot);
  5106. (void) XFreePixmap(display,source);
  5107. (void) XFreePixmap(display,mask);
  5108. return(cursor);
  5109. }
  5110. /*
  5111. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5112. % %
  5113. % %
  5114. % %
  5115. % X M a k e I m a g e %
  5116. % %
  5117. % %
  5118. % %
  5119. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5120. %
  5121. % XMakeImage() creates an X11 image. If the image size differs from the X11
  5122. % image size, the image is first resized.
  5123. %
  5124. % The format of the XMakeImage method is:
  5125. %
  5126. % MagickBooleanType XMakeImage(Display *display,
  5127. % const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
  5128. % unsigned int width,unsigned int height,ExceptionInfo *exception)
  5129. %
  5130. % A description of each parameter follows:
  5131. %
  5132. % o display: Specifies a connection to an X server; returned from
  5133. % XOpenDisplay.
  5134. %
  5135. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  5136. %
  5137. % o window: Specifies a pointer to a XWindowInfo structure.
  5138. %
  5139. % o image: the image.
  5140. %
  5141. % o width: Specifies the width in pixels of the rectangular area to
  5142. % display.
  5143. %
  5144. % o height: Specifies the height in pixels of the rectangular area to
  5145. % display.
  5146. %
  5147. % o exception: return any errors or warnings in this structure.
  5148. %
  5149. */
  5150. MagickPrivate MagickBooleanType XMakeImage(Display *display,
  5151. const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
  5152. unsigned int width,unsigned int height,ExceptionInfo *exception)
  5153. {
  5154. #define CheckOverflowException(length,width,height) \
  5155. (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
  5156. int
  5157. depth,
  5158. format;
  5159. size_t
  5160. length;
  5161. XImage
  5162. *matte_image,
  5163. *ximage;
  5164. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  5165. assert(display != (Display *) NULL);
  5166. assert(resource_info != (XResourceInfo *) NULL);
  5167. assert(window != (XWindowInfo *) NULL);
  5168. assert(width != 0);
  5169. assert(height != 0);
  5170. if ((window->width == 0) || (window->height == 0))
  5171. return(MagickFalse);
  5172. /*
  5173. Apply user transforms to the image.
  5174. */
  5175. (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
  5176. (void) XFlush(display);
  5177. depth=(int) window->depth;
  5178. if (window->destroy)
  5179. window->image=DestroyImage(window->image);
  5180. window->image=image;
  5181. window->destroy=MagickFalse;
  5182. if (window->image != (Image *) NULL)
  5183. {
  5184. if (window->crop_geometry != (char *) NULL)
  5185. {
  5186. Image
  5187. *crop_image;
  5188. RectangleInfo
  5189. crop_info;
  5190. /*
  5191. Crop image.
  5192. */
  5193. window->image->page.x=0;
  5194. window->image->page.y=0;
  5195. (void) ParsePageGeometry(window->image,window->crop_geometry,
  5196. &crop_info,exception);
  5197. crop_image=CropImage(window->image,&crop_info,exception);
  5198. if (crop_image != (Image *) NULL)
  5199. {
  5200. if (window->image != image)
  5201. window->image=DestroyImage(window->image);
  5202. window->image=crop_image;
  5203. window->destroy=MagickTrue;
  5204. }
  5205. }
  5206. if ((width != (unsigned int) window->image->columns) ||
  5207. (height != (unsigned int) window->image->rows))
  5208. {
  5209. Image
  5210. *resize_image;
  5211. /*
  5212. Resize image.
  5213. */
  5214. resize_image=NewImageList();
  5215. if ((window->pixel_info->colors == 0) &&
  5216. (window->image->rows > (unsigned long) XDisplayHeight(display,window->screen)) &&
  5217. (window->image->columns > (unsigned long) XDisplayWidth(display,window->screen)))
  5218. resize_image=ResizeImage(window->image,width,height,
  5219. image->filter,exception);
  5220. else
  5221. {
  5222. if (window->image->storage_class == PseudoClass)
  5223. resize_image=SampleImage(window->image,width,height,
  5224. exception);
  5225. else
  5226. resize_image=ThumbnailImage(window->image,width,height,
  5227. exception);
  5228. }
  5229. if (resize_image != (Image *) NULL)
  5230. {
  5231. if (window->image != image)
  5232. window->image=DestroyImage(window->image);
  5233. window->image=resize_image;
  5234. window->destroy=MagickTrue;
  5235. }
  5236. }
  5237. width=(unsigned int) window->image->columns;
  5238. assert((size_t) width == window->image->columns);
  5239. height=(unsigned int) window->image->rows;
  5240. assert((size_t) height == window->image->rows);
  5241. }
  5242. /*
  5243. Create X image.
  5244. */
  5245. ximage=(XImage *) NULL;
  5246. format=(depth == 1) ? XYBitmap : ZPixmap;
  5247. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  5248. if (window->shared_memory != MagickFalse)
  5249. {
  5250. XShmSegmentInfo
  5251. *segment_info;
  5252. segment_info=(XShmSegmentInfo *) window->segment_info;
  5253. segment_info[1].shmid=(-1);
  5254. segment_info[1].shmaddr=(char *) NULL;
  5255. ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format,
  5256. (char *) NULL,&segment_info[1],width,height);
  5257. if (ximage == (XImage *) NULL)
  5258. window->shared_memory=MagickFalse;
  5259. else
  5260. {
  5261. length=(size_t) ximage->bytes_per_line*ximage->height;
  5262. if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
  5263. window->shared_memory=MagickFalse;
  5264. }
  5265. if (window->shared_memory != MagickFalse)
  5266. segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777);
  5267. if (window->shared_memory != MagickFalse)
  5268. segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0);
  5269. if (segment_info[1].shmid < 0)
  5270. window->shared_memory=MagickFalse;
  5271. if (window->shared_memory != MagickFalse)
  5272. (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
  5273. else
  5274. {
  5275. if (ximage != (XImage *) NULL)
  5276. XDestroyImage(ximage);
  5277. ximage=(XImage *) NULL;
  5278. if (segment_info[1].shmaddr)
  5279. {
  5280. (void) shmdt(segment_info[1].shmaddr);
  5281. segment_info[1].shmaddr=(char *) NULL;
  5282. }
  5283. if (segment_info[1].shmid >= 0)
  5284. {
  5285. (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
  5286. segment_info[1].shmid=(-1);
  5287. }
  5288. }
  5289. }
  5290. #endif
  5291. /*
  5292. Allocate X image pixel data.
  5293. */
  5294. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  5295. if (window->shared_memory)
  5296. {
  5297. Status
  5298. status;
  5299. XShmSegmentInfo
  5300. *segment_info;
  5301. (void) XSync(display,MagickFalse);
  5302. xerror_alert=MagickFalse;
  5303. segment_info=(XShmSegmentInfo *) window->segment_info;
  5304. ximage->data=segment_info[1].shmaddr;
  5305. segment_info[1].readOnly=MagickFalse;
  5306. status=XShmAttach(display,&segment_info[1]);
  5307. if (status != False)
  5308. (void) XSync(display,MagickFalse);
  5309. if ((status == False) || (xerror_alert != MagickFalse))
  5310. {
  5311. window->shared_memory=MagickFalse;
  5312. if (status != False)
  5313. XShmDetach(display,&segment_info[1]);
  5314. ximage->data=NULL;
  5315. XDestroyImage(ximage);
  5316. ximage=(XImage *) NULL;
  5317. if (segment_info[1].shmid >= 0)
  5318. {
  5319. if (segment_info[1].shmaddr != NULL)
  5320. (void) shmdt(segment_info[1].shmaddr);
  5321. (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
  5322. segment_info[1].shmid=(-1);
  5323. segment_info[1].shmaddr=(char *) NULL;
  5324. }
  5325. }
  5326. }
  5327. #endif
  5328. if (window->shared_memory == MagickFalse)
  5329. ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0,
  5330. (char *) NULL,width,height,XBitmapPad(display),0);
  5331. if (ximage == (XImage *) NULL)
  5332. {
  5333. /*
  5334. Unable to create X image.
  5335. */
  5336. (void) XCheckDefineCursor(display,window->id,window->cursor);
  5337. return(MagickFalse);
  5338. }
  5339. length=(size_t) ximage->bytes_per_line*ximage->height;
  5340. if (IsEventLogging())
  5341. {
  5342. (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
  5343. (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d",
  5344. ximage->width,ximage->height);
  5345. (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d",
  5346. ximage->format);
  5347. (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d",
  5348. ximage->byte_order);
  5349. (void) LogMagickEvent(X11Event,GetMagickModule(),
  5350. " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
  5351. ximage->bitmap_bit_order,ximage->bitmap_pad);
  5352. (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d",
  5353. ximage->depth);
  5354. (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d",
  5355. ximage->bytes_per_line);
  5356. (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d",
  5357. ximage->bits_per_pixel);
  5358. (void) LogMagickEvent(X11Event,GetMagickModule(),
  5359. " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
  5360. ximage->green_mask,ximage->blue_mask);
  5361. }
  5362. if (window->shared_memory == MagickFalse)
  5363. {
  5364. if (ximage->format == XYBitmap)
  5365. {
  5366. ximage->data=(char *) AcquireQuantumMemory((size_t)
  5367. ximage->bytes_per_line,(size_t) ximage->depth*ximage->height);
  5368. if (ximage->data != (char *) NULL)
  5369. (void) memset(ximage->data,0,(size_t)
  5370. ximage->bytes_per_line*ximage->depth*ximage->height);
  5371. }
  5372. else
  5373. {
  5374. ximage->data=(char *) AcquireQuantumMemory((size_t)
  5375. ximage->bytes_per_line,(size_t) ximage->height);
  5376. if (ximage->data != (char *) NULL)
  5377. (void) memset(ximage->data,0,(size_t)
  5378. ximage->bytes_per_line*ximage->height);
  5379. }
  5380. }
  5381. if (ximage->data == (char *) NULL)
  5382. {
  5383. /*
  5384. Unable to allocate pixel data.
  5385. */
  5386. XDestroyImage(ximage);
  5387. ximage=(XImage *) NULL;
  5388. (void) XCheckDefineCursor(display,window->id,window->cursor);
  5389. return(MagickFalse);
  5390. }
  5391. if (window->ximage != (XImage *) NULL)
  5392. {
  5393. /*
  5394. Destroy previous X image.
  5395. */
  5396. length=(size_t) window->ximage->bytes_per_line*window->ximage->height;
  5397. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  5398. if (window->segment_info != (XShmSegmentInfo *) NULL)
  5399. {
  5400. XShmSegmentInfo
  5401. *segment_info;
  5402. segment_info=(XShmSegmentInfo *) window->segment_info;
  5403. if (segment_info[0].shmid >= 0)
  5404. {
  5405. (void) XSync(display,MagickFalse);
  5406. (void) XShmDetach(display,&segment_info[0]);
  5407. (void) XSync(display,MagickFalse);
  5408. if (segment_info[0].shmaddr != (char *) NULL)
  5409. (void) shmdt(segment_info[0].shmaddr);
  5410. (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
  5411. segment_info[0].shmid=(-1);
  5412. segment_info[0].shmaddr=(char *) NULL;
  5413. window->ximage->data=(char *) NULL;
  5414. }
  5415. }
  5416. #endif
  5417. if (window->ximage->data != (char *) NULL)
  5418. free(window->ximage->data);
  5419. window->ximage->data=(char *) NULL;
  5420. XDestroyImage(window->ximage);
  5421. window->ximage=(XImage *) NULL;
  5422. }
  5423. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  5424. if (window->segment_info != (XShmSegmentInfo *) NULL)
  5425. {
  5426. XShmSegmentInfo
  5427. *segment_info;
  5428. segment_info=(XShmSegmentInfo *) window->segment_info;
  5429. segment_info[0]=segment_info[1];
  5430. }
  5431. #endif
  5432. window->ximage=ximage;
  5433. matte_image=(XImage *) NULL;
  5434. if ((window->shape != MagickFalse) && (window->image != (Image *) NULL))
  5435. if ((window->image->alpha_trait != UndefinedPixelTrait) &&
  5436. ((int) width <= XDisplayWidth(display,window->screen)) &&
  5437. ((int) height <= XDisplayHeight(display,window->screen)))
  5438. {
  5439. /*
  5440. Create matte image.
  5441. */
  5442. matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
  5443. (char *) NULL,width,height,XBitmapPad(display),0);
  5444. if (IsEventLogging())
  5445. {
  5446. (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
  5447. (void) LogMagickEvent(X11Event,GetMagickModule(),
  5448. " width, height: %dx%d",matte_image->width,matte_image->height);
  5449. }
  5450. if (matte_image != (XImage *) NULL)
  5451. {
  5452. /*
  5453. Allocate matte image pixel data.
  5454. */
  5455. matte_image->data=(char *) malloc((size_t)
  5456. matte_image->bytes_per_line*matte_image->depth*
  5457. matte_image->height);
  5458. if (matte_image->data == (char *) NULL)
  5459. {
  5460. XDestroyImage(matte_image);
  5461. matte_image=(XImage *) NULL;
  5462. }
  5463. }
  5464. }
  5465. if (window->matte_image != (XImage *) NULL)
  5466. {
  5467. /*
  5468. Free matte image.
  5469. */
  5470. if (window->matte_image->data != (char *) NULL)
  5471. free(window->matte_image->data);
  5472. window->matte_image->data=(char *) NULL;
  5473. XDestroyImage(window->matte_image);
  5474. window->matte_image=(XImage *) NULL;
  5475. }
  5476. window->matte_image=matte_image;
  5477. if (window->matte_pixmap != (Pixmap) NULL)
  5478. {
  5479. (void) XFreePixmap(display,window->matte_pixmap);
  5480. window->matte_pixmap=(Pixmap) NULL;
  5481. #if defined(MAGICKCORE_HAVE_SHAPE)
  5482. if (window->shape != MagickFalse)
  5483. XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
  5484. #endif
  5485. }
  5486. window->stasis=MagickFalse;
  5487. /*
  5488. Convert pixels to X image data.
  5489. */
  5490. if (window->image != (Image *) NULL)
  5491. {
  5492. if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
  5493. (ximage->bitmap_bit_order == LSBFirst)))
  5494. XMakeImageLSBFirst(resource_info,window,window->image,ximage,
  5495. matte_image,exception);
  5496. else
  5497. XMakeImageMSBFirst(resource_info,window,window->image,ximage,
  5498. matte_image,exception);
  5499. }
  5500. if (window->matte_image != (XImage *) NULL)
  5501. {
  5502. /*
  5503. Create matte pixmap.
  5504. */
  5505. window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
  5506. if (window->matte_pixmap != (Pixmap) NULL)
  5507. {
  5508. GC
  5509. graphics_context;
  5510. XGCValues
  5511. context_values;
  5512. /*
  5513. Copy matte image to matte pixmap.
  5514. */
  5515. context_values.background=0;
  5516. context_values.foreground=1;
  5517. graphics_context=XCreateGC(display,window->matte_pixmap,
  5518. (size_t) (GCBackground | GCForeground),&context_values);
  5519. (void) XPutImage(display,window->matte_pixmap,graphics_context,
  5520. window->matte_image,0,0,0,0,width,height);
  5521. (void) XFreeGC(display,graphics_context);
  5522. #if defined(MAGICKCORE_HAVE_SHAPE)
  5523. if (window->shape != MagickFalse)
  5524. XShapeCombineMask(display,window->id,ShapeBounding,0,0,
  5525. window->matte_pixmap,ShapeSet);
  5526. #endif
  5527. }
  5528. }
  5529. (void) XMakePixmap(display,resource_info,window);
  5530. /*
  5531. Restore cursor.
  5532. */
  5533. (void) XCheckDefineCursor(display,window->id,window->cursor);
  5534. return(MagickTrue);
  5535. }
  5536. /*
  5537. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5538. % %
  5539. % %
  5540. % %
  5541. + X M a k e I m a g e L S B F i r s t %
  5542. % %
  5543. % %
  5544. % %
  5545. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5546. %
  5547. % XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image
  5548. % pixels are copied in least-significant bit and byte first order. The
  5549. % server's scanline pad is respected. Rather than using one or two general
  5550. % cases, many special cases are found here to help speed up the image
  5551. % conversion.
  5552. %
  5553. % The format of the XMakeImageLSBFirst method is:
  5554. %
  5555. % void XMakeImageLSBFirst(Display *display,XWindows *windows,
  5556. % ExceptionInfo *exception)
  5557. %
  5558. % A description of each parameter follows:
  5559. %
  5560. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  5561. %
  5562. % o window: Specifies a pointer to a XWindowInfo structure.
  5563. %
  5564. % o image: the image.
  5565. %
  5566. % o ximage: Specifies a pointer to a XImage structure; returned from
  5567. % XCreateImage.
  5568. %
  5569. % o matte_image: Specifies a pointer to a XImage structure; returned from
  5570. % XCreateImage.
  5571. %
  5572. % o exception: return any errors or warnings in this structure.
  5573. %
  5574. */
  5575. static void XMakeImageLSBFirst(const XResourceInfo *resource_info,
  5576. const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
  5577. ExceptionInfo *exception)
  5578. {
  5579. CacheView
  5580. *canvas_view;
  5581. Image
  5582. *canvas;
  5583. int
  5584. y;
  5585. register const Quantum
  5586. *p;
  5587. register int
  5588. x;
  5589. register unsigned char
  5590. *q;
  5591. unsigned char
  5592. bit,
  5593. byte;
  5594. unsigned int
  5595. scanline_pad;
  5596. unsigned long
  5597. pixel,
  5598. *pixels;
  5599. XStandardColormap
  5600. *map_info;
  5601. assert(resource_info != (XResourceInfo *) NULL);
  5602. assert(window != (XWindowInfo *) NULL);
  5603. assert(image != (Image *) NULL);
  5604. if (image->debug != MagickFalse)
  5605. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  5606. canvas=image;
  5607. if ((window->immutable == MagickFalse) &&
  5608. (image->storage_class == DirectClass) &&
  5609. (image->alpha_trait != UndefinedPixelTrait))
  5610. {
  5611. char
  5612. size[MagickPathExtent];
  5613. Image
  5614. *pattern;
  5615. ImageInfo
  5616. *image_info;
  5617. image_info=AcquireImageInfo();
  5618. (void) CopyMagickString(image_info->filename,
  5619. resource_info->image_info->texture != (char *) NULL ?
  5620. resource_info->image_info->texture : "pattern:checkerboard",
  5621. MagickPathExtent);
  5622. (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double)
  5623. image->columns,(double) image->rows);
  5624. image_info->size=ConstantString(size);
  5625. pattern=ReadImage(image_info,exception);
  5626. image_info=DestroyImageInfo(image_info);
  5627. if (pattern != (Image *) NULL)
  5628. {
  5629. canvas=CloneImage(image,0,0,MagickTrue,exception);
  5630. if (canvas != (Image *) NULL)
  5631. (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickTrue,
  5632. 0,0,exception);
  5633. pattern=DestroyImage(pattern);
  5634. }
  5635. }
  5636. scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
  5637. ximage->bits_per_pixel) >> 3));
  5638. map_info=window->map_info;
  5639. pixels=window->pixel_info->pixels;
  5640. q=(unsigned char *) ximage->data;
  5641. x=0;
  5642. canvas_view=AcquireVirtualCacheView(canvas,exception);
  5643. if (ximage->format == XYBitmap)
  5644. {
  5645. register unsigned short
  5646. polarity;
  5647. unsigned char
  5648. background,
  5649. foreground;
  5650. /*
  5651. Convert canvas to big-endian bitmap.
  5652. */
  5653. background=(unsigned char)
  5654. (XPixelIntensity(&window->pixel_info->foreground_color) <
  5655. XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
  5656. foreground=(unsigned char)
  5657. (XPixelIntensity(&window->pixel_info->background_color) <
  5658. XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
  5659. polarity=(unsigned short) ((GetPixelInfoIntensity(image,
  5660. &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
  5661. if (canvas->colors == 2)
  5662. polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) <
  5663. GetPixelInfoIntensity(image,&canvas->colormap[1]);
  5664. for (y=0; y < (int) canvas->rows; y++)
  5665. {
  5666. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
  5667. exception);
  5668. if (p == (const Quantum *) NULL)
  5669. break;
  5670. bit=0;
  5671. byte=0;
  5672. for (x=0; x < (int) canvas->columns; x++)
  5673. {
  5674. byte>>=1;
  5675. if (GetPixelIndex(canvas,p) == (Quantum) polarity)
  5676. byte|=foreground;
  5677. else
  5678. byte|=background;
  5679. bit++;
  5680. if (bit == 8)
  5681. {
  5682. *q++=byte;
  5683. bit=0;
  5684. byte=0;
  5685. }
  5686. p+=GetPixelChannels(canvas);
  5687. }
  5688. if (bit != 0)
  5689. *q=byte >> (8-bit);
  5690. q+=scanline_pad;
  5691. }
  5692. }
  5693. else
  5694. if (window->pixel_info->colors != 0)
  5695. switch (ximage->bits_per_pixel)
  5696. {
  5697. case 2:
  5698. {
  5699. register unsigned int
  5700. nibble;
  5701. /*
  5702. Convert to 2 bit color-mapped X canvas.
  5703. */
  5704. for (y=0; y < (int) canvas->rows; y++)
  5705. {
  5706. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5707. canvas->columns,1,exception);
  5708. if (p == (const Quantum *) NULL)
  5709. break;
  5710. nibble=0;
  5711. for (x=0; x < (int) canvas->columns; x++)
  5712. {
  5713. pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f;
  5714. switch (nibble)
  5715. {
  5716. case 0:
  5717. {
  5718. *q=(unsigned char) pixel;
  5719. nibble++;
  5720. break;
  5721. }
  5722. case 1:
  5723. {
  5724. *q|=(unsigned char) (pixel << 2);
  5725. nibble++;
  5726. break;
  5727. }
  5728. case 2:
  5729. {
  5730. *q|=(unsigned char) (pixel << 4);
  5731. nibble++;
  5732. break;
  5733. }
  5734. case 3:
  5735. {
  5736. *q|=(unsigned char) (pixel << 6);
  5737. q++;
  5738. nibble=0;
  5739. break;
  5740. }
  5741. }
  5742. p+=GetPixelChannels(canvas);
  5743. }
  5744. q+=scanline_pad;
  5745. }
  5746. break;
  5747. }
  5748. case 4:
  5749. {
  5750. register unsigned int
  5751. nibble;
  5752. /*
  5753. Convert to 4 bit color-mapped X canvas.
  5754. */
  5755. for (y=0; y < (int) canvas->rows; y++)
  5756. {
  5757. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5758. canvas->columns,1,exception);
  5759. if (p == (const Quantum *) NULL)
  5760. break;
  5761. nibble=0;
  5762. for (x=0; x < (int) canvas->columns; x++)
  5763. {
  5764. pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf;
  5765. switch (nibble)
  5766. {
  5767. case 0:
  5768. {
  5769. *q=(unsigned char) pixel;
  5770. nibble++;
  5771. break;
  5772. }
  5773. case 1:
  5774. {
  5775. *q|=(unsigned char) (pixel << 4);
  5776. q++;
  5777. nibble=0;
  5778. break;
  5779. }
  5780. }
  5781. p+=GetPixelChannels(canvas);
  5782. }
  5783. q+=scanline_pad;
  5784. }
  5785. break;
  5786. }
  5787. case 6:
  5788. case 8:
  5789. {
  5790. /*
  5791. Convert to 8 bit color-mapped X canvas.
  5792. */
  5793. if (resource_info->color_recovery &&
  5794. resource_info->quantize_info->dither_method != NoDitherMethod)
  5795. {
  5796. XDitherImage(canvas,ximage,exception);
  5797. break;
  5798. }
  5799. for (y=0; y < (int) canvas->rows; y++)
  5800. {
  5801. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5802. canvas->columns,1,exception);
  5803. if (p == (const Quantum *) NULL)
  5804. break;
  5805. for (x=0; x < (int) canvas->columns; x++)
  5806. {
  5807. pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
  5808. *q++=(unsigned char) pixel;
  5809. p+=GetPixelChannels(canvas);
  5810. }
  5811. q+=scanline_pad;
  5812. }
  5813. break;
  5814. }
  5815. default:
  5816. {
  5817. register int
  5818. k;
  5819. register unsigned int
  5820. bytes_per_pixel;
  5821. /*
  5822. Convert to multi-byte color-mapped X canvas.
  5823. */
  5824. bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
  5825. for (y=0; y < (int) canvas->rows; y++)
  5826. {
  5827. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5828. canvas->columns,1,exception);
  5829. if (p == (const Quantum *) NULL)
  5830. break;
  5831. for (x=0; x < (int) canvas->columns; x++)
  5832. {
  5833. pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
  5834. for (k=0; k < (int) bytes_per_pixel; k++)
  5835. {
  5836. *q++=(unsigned char) (pixel & 0xff);
  5837. pixel>>=8;
  5838. }
  5839. p+=GetPixelChannels(canvas);
  5840. }
  5841. q+=scanline_pad;
  5842. }
  5843. break;
  5844. }
  5845. }
  5846. else
  5847. switch (ximage->bits_per_pixel)
  5848. {
  5849. case 2:
  5850. {
  5851. register unsigned int
  5852. nibble;
  5853. /*
  5854. Convert to contiguous 2 bit continuous-tone X canvas.
  5855. */
  5856. for (y=0; y < (int) canvas->rows; y++)
  5857. {
  5858. nibble=0;
  5859. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5860. canvas->columns,1,exception);
  5861. if (p == (const Quantum *) NULL)
  5862. break;
  5863. for (x=0; x < (int) canvas->columns; x++)
  5864. {
  5865. pixel=XGammaPixel(canvas,map_info,p);
  5866. pixel&=0xf;
  5867. switch (nibble)
  5868. {
  5869. case 0:
  5870. {
  5871. *q=(unsigned char) pixel;
  5872. nibble++;
  5873. break;
  5874. }
  5875. case 1:
  5876. {
  5877. *q|=(unsigned char) (pixel << 2);
  5878. nibble++;
  5879. break;
  5880. }
  5881. case 2:
  5882. {
  5883. *q|=(unsigned char) (pixel << 4);
  5884. nibble++;
  5885. break;
  5886. }
  5887. case 3:
  5888. {
  5889. *q|=(unsigned char) (pixel << 6);
  5890. q++;
  5891. nibble=0;
  5892. break;
  5893. }
  5894. }
  5895. p+=GetPixelChannels(canvas);
  5896. }
  5897. q+=scanline_pad;
  5898. }
  5899. break;
  5900. }
  5901. case 4:
  5902. {
  5903. register unsigned int
  5904. nibble;
  5905. /*
  5906. Convert to contiguous 4 bit continuous-tone X canvas.
  5907. */
  5908. for (y=0; y < (int) canvas->rows; y++)
  5909. {
  5910. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5911. canvas->columns,1,exception);
  5912. if (p == (const Quantum *) NULL)
  5913. break;
  5914. nibble=0;
  5915. for (x=0; x < (int) canvas->columns; x++)
  5916. {
  5917. pixel=XGammaPixel(canvas,map_info,p);
  5918. pixel&=0xf;
  5919. switch (nibble)
  5920. {
  5921. case 0:
  5922. {
  5923. *q=(unsigned char) pixel;
  5924. nibble++;
  5925. break;
  5926. }
  5927. case 1:
  5928. {
  5929. *q|=(unsigned char) (pixel << 4);
  5930. q++;
  5931. nibble=0;
  5932. break;
  5933. }
  5934. }
  5935. p+=GetPixelChannels(canvas);
  5936. }
  5937. q+=scanline_pad;
  5938. }
  5939. break;
  5940. }
  5941. case 6:
  5942. case 8:
  5943. {
  5944. /*
  5945. Convert to contiguous 8 bit continuous-tone X canvas.
  5946. */
  5947. if (resource_info->color_recovery &&
  5948. resource_info->quantize_info->dither_method != NoDitherMethod)
  5949. {
  5950. XDitherImage(canvas,ximage,exception);
  5951. break;
  5952. }
  5953. for (y=0; y < (int) canvas->rows; y++)
  5954. {
  5955. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5956. canvas->columns,1,exception);
  5957. if (p == (const Quantum *) NULL)
  5958. break;
  5959. for (x=0; x < (int) canvas->columns; x++)
  5960. {
  5961. pixel=XGammaPixel(canvas,map_info,p);
  5962. *q++=(unsigned char) pixel;
  5963. p+=GetPixelChannels(canvas);
  5964. }
  5965. q+=scanline_pad;
  5966. }
  5967. break;
  5968. }
  5969. default:
  5970. {
  5971. if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
  5972. (map_info->green_max == 255) && (map_info->blue_max == 255) &&
  5973. (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
  5974. (map_info->blue_mult == 1))
  5975. {
  5976. /*
  5977. Convert to 32 bit continuous-tone X canvas.
  5978. */
  5979. for (y=0; y < (int) canvas->rows; y++)
  5980. {
  5981. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  5982. canvas->columns,1,exception);
  5983. if (p == (const Quantum *) NULL)
  5984. break;
  5985. if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
  5986. (blue_gamma != 1.0))
  5987. {
  5988. /*
  5989. Gamma correct canvas.
  5990. */
  5991. for (x=(int) canvas->columns-1; x >= 0; x--)
  5992. {
  5993. *q++=ScaleQuantumToChar(XBlueGamma(
  5994. GetPixelBlue(canvas,p)));
  5995. *q++=ScaleQuantumToChar(XGreenGamma(
  5996. GetPixelGreen(canvas,p)));
  5997. *q++=ScaleQuantumToChar(XRedGamma(
  5998. GetPixelRed(canvas,p)));
  5999. *q++=0;
  6000. p+=GetPixelChannels(canvas);
  6001. }
  6002. continue;
  6003. }
  6004. for (x=(int) canvas->columns-1; x >= 0; x--)
  6005. {
  6006. *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
  6007. *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
  6008. *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
  6009. *q++=0;
  6010. p+=GetPixelChannels(canvas);
  6011. }
  6012. }
  6013. }
  6014. else
  6015. if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
  6016. (map_info->green_max == 255) && (map_info->blue_max == 255) &&
  6017. (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
  6018. (map_info->blue_mult == 65536L))
  6019. {
  6020. /*
  6021. Convert to 32 bit continuous-tone X canvas.
  6022. */
  6023. for (y=0; y < (int) canvas->rows; y++)
  6024. {
  6025. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6026. canvas->columns,1,exception);
  6027. if (p == (const Quantum *) NULL)
  6028. break;
  6029. if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
  6030. (blue_gamma != 1.0))
  6031. {
  6032. /*
  6033. Gamma correct canvas.
  6034. */
  6035. for (x=(int) canvas->columns-1; x >= 0; x--)
  6036. {
  6037. *q++=ScaleQuantumToChar(XRedGamma(
  6038. GetPixelRed(canvas,p)));
  6039. *q++=ScaleQuantumToChar(XGreenGamma(
  6040. GetPixelGreen(canvas,p)));
  6041. *q++=ScaleQuantumToChar(XBlueGamma(
  6042. GetPixelBlue(canvas,p)));
  6043. *q++=0;
  6044. p+=GetPixelChannels(canvas);
  6045. }
  6046. continue;
  6047. }
  6048. for (x=(int) canvas->columns-1; x >= 0; x--)
  6049. {
  6050. *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
  6051. *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
  6052. *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
  6053. *q++=0;
  6054. p+=GetPixelChannels(canvas);
  6055. }
  6056. }
  6057. }
  6058. else
  6059. {
  6060. register int
  6061. k;
  6062. register unsigned int
  6063. bytes_per_pixel;
  6064. /*
  6065. Convert to multi-byte continuous-tone X canvas.
  6066. */
  6067. bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
  6068. for (y=0; y < (int) canvas->rows; y++)
  6069. {
  6070. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6071. canvas->columns,1,exception);
  6072. if (p == (const Quantum *) NULL)
  6073. break;
  6074. for (x=0; x < (int) canvas->columns; x++)
  6075. {
  6076. pixel=XGammaPixel(canvas,map_info,p);
  6077. for (k=0; k < (int) bytes_per_pixel; k++)
  6078. {
  6079. *q++=(unsigned char) (pixel & 0xff);
  6080. pixel>>=8;
  6081. }
  6082. p+=GetPixelChannels(canvas);
  6083. }
  6084. q+=scanline_pad;
  6085. }
  6086. }
  6087. break;
  6088. }
  6089. }
  6090. if (matte_image != (XImage *) NULL)
  6091. {
  6092. /*
  6093. Initialize matte canvas.
  6094. */
  6095. scanline_pad=(unsigned int) (matte_image->bytes_per_line-
  6096. ((matte_image->width*matte_image->bits_per_pixel) >> 3));
  6097. q=(unsigned char *) matte_image->data;
  6098. for (y=0; y < (int) canvas->rows; y++)
  6099. {
  6100. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
  6101. exception);
  6102. if (p == (const Quantum *) NULL)
  6103. break;
  6104. bit=0;
  6105. byte=0;
  6106. for (x=(int) canvas->columns-1; x >= 0; x--)
  6107. {
  6108. byte>>=1;
  6109. if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
  6110. byte|=0x80;
  6111. bit++;
  6112. if (bit == 8)
  6113. {
  6114. *q++=byte;
  6115. bit=0;
  6116. byte=0;
  6117. }
  6118. p+=GetPixelChannels(canvas);
  6119. }
  6120. if (bit != 0)
  6121. *q=byte >> (8-bit);
  6122. q+=scanline_pad;
  6123. }
  6124. }
  6125. canvas_view=DestroyCacheView(canvas_view);
  6126. if (canvas != image)
  6127. canvas=DestroyImage(canvas);
  6128. }
  6129. /*
  6130. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6131. % %
  6132. % %
  6133. % %
  6134. + X M a k e I m a g e M S B F i r s t %
  6135. % %
  6136. % %
  6137. % %
  6138. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6139. %
  6140. % XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X
  6141. % image pixels are copied in most-significant bit and byte first order. The
  6142. % server's scanline pad is also respected. Rather than using one or two
  6143. % general cases, many special cases are found here to help speed up the image
  6144. % conversion.
  6145. %
  6146. % The format of the XMakeImageMSBFirst method is:
  6147. %
  6148. % XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image,
  6149. % ExceptionInfo *exception)
  6150. %
  6151. % A description of each parameter follows:
  6152. %
  6153. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  6154. %
  6155. % o window: Specifies a pointer to a XWindowInfo structure.
  6156. %
  6157. % o image: the image.
  6158. %
  6159. % o ximage: Specifies a pointer to a XImage structure; returned from
  6160. % XCreateImage.
  6161. %
  6162. % o matte_image: Specifies a pointer to a XImage structure; returned from
  6163. % XCreateImage.
  6164. %
  6165. % o exception: return any errors or warnings in this structure.
  6166. %
  6167. */
  6168. static void XMakeImageMSBFirst(const XResourceInfo *resource_info,
  6169. const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
  6170. ExceptionInfo *exception)
  6171. {
  6172. CacheView
  6173. *canvas_view;
  6174. Image
  6175. *canvas;
  6176. int
  6177. y;
  6178. register int
  6179. x;
  6180. register const Quantum
  6181. *p;
  6182. register unsigned char
  6183. *q;
  6184. unsigned char
  6185. bit,
  6186. byte;
  6187. unsigned int
  6188. scanline_pad;
  6189. unsigned long
  6190. pixel,
  6191. *pixels;
  6192. XStandardColormap
  6193. *map_info;
  6194. assert(resource_info != (XResourceInfo *) NULL);
  6195. assert(window != (XWindowInfo *) NULL);
  6196. assert(image != (Image *) NULL);
  6197. if (image->debug != MagickFalse)
  6198. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  6199. canvas=image;
  6200. if ((window->immutable != MagickFalse) &&
  6201. (image->storage_class == DirectClass) &&
  6202. (image->alpha_trait != UndefinedPixelTrait))
  6203. {
  6204. char
  6205. size[MagickPathExtent];
  6206. Image
  6207. *pattern;
  6208. ImageInfo
  6209. *image_info;
  6210. image_info=AcquireImageInfo();
  6211. (void) CopyMagickString(image_info->filename,
  6212. resource_info->image_info->texture != (char *) NULL ?
  6213. resource_info->image_info->texture : "pattern:checkerboard",
  6214. MagickPathExtent);
  6215. (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double)
  6216. image->columns,(double) image->rows);
  6217. image_info->size=ConstantString(size);
  6218. pattern=ReadImage(image_info,exception);
  6219. image_info=DestroyImageInfo(image_info);
  6220. if (pattern != (Image *) NULL)
  6221. {
  6222. canvas=CloneImage(image,0,0,MagickTrue,exception);
  6223. if (canvas != (Image *) NULL)
  6224. (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickFalse,
  6225. 0,0,exception);
  6226. pattern=DestroyImage(pattern);
  6227. }
  6228. }
  6229. scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
  6230. ximage->bits_per_pixel) >> 3));
  6231. map_info=window->map_info;
  6232. pixels=window->pixel_info->pixels;
  6233. q=(unsigned char *) ximage->data;
  6234. x=0;
  6235. canvas_view=AcquireVirtualCacheView(canvas,exception);
  6236. if (ximage->format == XYBitmap)
  6237. {
  6238. register unsigned short
  6239. polarity;
  6240. unsigned char
  6241. background,
  6242. foreground;
  6243. /*
  6244. Convert canvas to big-endian bitmap.
  6245. */
  6246. background=(unsigned char)
  6247. (XPixelIntensity(&window->pixel_info->foreground_color) <
  6248. XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00);
  6249. foreground=(unsigned char)
  6250. (XPixelIntensity(&window->pixel_info->background_color) <
  6251. XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00);
  6252. polarity=(unsigned short) ((GetPixelInfoIntensity(image,
  6253. &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
  6254. if (canvas->colors == 2)
  6255. polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) <
  6256. GetPixelInfoIntensity(image,&canvas->colormap[1]);
  6257. for (y=0; y < (int) canvas->rows; y++)
  6258. {
  6259. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
  6260. exception);
  6261. if (p == (const Quantum *) NULL)
  6262. break;
  6263. bit=0;
  6264. byte=0;
  6265. for (x=(int) canvas->columns-1; x >= 0; x--)
  6266. {
  6267. byte<<=1;
  6268. if (GetPixelIndex(canvas,p) == (Quantum) polarity)
  6269. byte|=foreground;
  6270. else
  6271. byte|=background;
  6272. bit++;
  6273. if (bit == 8)
  6274. {
  6275. *q++=byte;
  6276. bit=0;
  6277. byte=0;
  6278. }
  6279. p+=GetPixelChannels(canvas);
  6280. }
  6281. if (bit != 0)
  6282. *q=byte << (8-bit);
  6283. q+=scanline_pad;
  6284. }
  6285. }
  6286. else
  6287. if (window->pixel_info->colors != 0)
  6288. switch (ximage->bits_per_pixel)
  6289. {
  6290. case 2:
  6291. {
  6292. register unsigned int
  6293. nibble;
  6294. /*
  6295. Convert to 2 bit color-mapped X canvas.
  6296. */
  6297. for (y=0; y < (int) canvas->rows; y++)
  6298. {
  6299. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6300. canvas->columns,1,exception);
  6301. if (p == (const Quantum *) NULL)
  6302. break;
  6303. nibble=0;
  6304. for (x=0; x < (int) canvas->columns; x++)
  6305. {
  6306. pixel=pixels[(ssize_t)
  6307. GetPixelIndex(canvas,p)] & 0xf;
  6308. switch (nibble)
  6309. {
  6310. case 0:
  6311. {
  6312. *q=(unsigned char) (pixel << 6);
  6313. nibble++;
  6314. break;
  6315. }
  6316. case 1:
  6317. {
  6318. *q|=(unsigned char) (pixel << 4);
  6319. nibble++;
  6320. break;
  6321. }
  6322. case 2:
  6323. {
  6324. *q|=(unsigned char) (pixel << 2);
  6325. nibble++;
  6326. break;
  6327. }
  6328. case 3:
  6329. {
  6330. *q|=(unsigned char) pixel;
  6331. q++;
  6332. nibble=0;
  6333. break;
  6334. }
  6335. }
  6336. p+=GetPixelChannels(canvas);
  6337. }
  6338. q+=scanline_pad;
  6339. }
  6340. break;
  6341. }
  6342. case 4:
  6343. {
  6344. register unsigned int
  6345. nibble;
  6346. /*
  6347. Convert to 4 bit color-mapped X canvas.
  6348. */
  6349. for (y=0; y < (int) canvas->rows; y++)
  6350. {
  6351. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6352. canvas->columns,1,exception);
  6353. if (p == (const Quantum *) NULL)
  6354. break;
  6355. nibble=0;
  6356. for (x=0; x < (int) canvas->columns; x++)
  6357. {
  6358. pixel=pixels[(ssize_t)
  6359. GetPixelIndex(canvas,p)] & 0xf;
  6360. switch (nibble)
  6361. {
  6362. case 0:
  6363. {
  6364. *q=(unsigned char) (pixel << 4);
  6365. nibble++;
  6366. break;
  6367. }
  6368. case 1:
  6369. {
  6370. *q|=(unsigned char) pixel;
  6371. q++;
  6372. nibble=0;
  6373. break;
  6374. }
  6375. }
  6376. p+=GetPixelChannels(canvas);
  6377. }
  6378. q+=scanline_pad;
  6379. }
  6380. break;
  6381. }
  6382. case 6:
  6383. case 8:
  6384. {
  6385. /*
  6386. Convert to 8 bit color-mapped X canvas.
  6387. */
  6388. if ((resource_info->color_recovery != MagickFalse) &&
  6389. (resource_info->quantize_info->dither_method != NoDitherMethod))
  6390. {
  6391. XDitherImage(canvas,ximage,exception);
  6392. break;
  6393. }
  6394. for (y=0; y < (int) canvas->rows; y++)
  6395. {
  6396. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6397. canvas->columns,1,exception);
  6398. if (p == (const Quantum *) NULL)
  6399. break;
  6400. for (x=0; x < (int) canvas->columns; x++)
  6401. {
  6402. pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
  6403. *q++=(unsigned char) pixel;
  6404. p+=GetPixelChannels(canvas);
  6405. }
  6406. q+=scanline_pad;
  6407. }
  6408. break;
  6409. }
  6410. default:
  6411. {
  6412. register int
  6413. k;
  6414. register unsigned int
  6415. bytes_per_pixel;
  6416. unsigned char
  6417. channel[sizeof(size_t)];
  6418. /*
  6419. Convert to 8 bit color-mapped X canvas.
  6420. */
  6421. bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
  6422. for (y=0; y < (int) canvas->rows; y++)
  6423. {
  6424. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6425. canvas->columns,1,exception);
  6426. if (p == (const Quantum *) NULL)
  6427. break;
  6428. for (x=0; x < (int) canvas->columns; x++)
  6429. {
  6430. pixel=pixels[(ssize_t)
  6431. GetPixelIndex(canvas,p)];
  6432. for (k=(int) bytes_per_pixel-1; k >= 0; k--)
  6433. {
  6434. channel[k]=(unsigned char) pixel;
  6435. pixel>>=8;
  6436. }
  6437. for (k=0; k < (int) bytes_per_pixel; k++)
  6438. *q++=channel[k];
  6439. p+=GetPixelChannels(canvas);
  6440. }
  6441. q+=scanline_pad;
  6442. }
  6443. break;
  6444. }
  6445. }
  6446. else
  6447. switch (ximage->bits_per_pixel)
  6448. {
  6449. case 2:
  6450. {
  6451. register unsigned int
  6452. nibble;
  6453. /*
  6454. Convert to 4 bit continuous-tone X canvas.
  6455. */
  6456. for (y=0; y < (int) canvas->rows; y++)
  6457. {
  6458. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6459. canvas->columns,1,exception);
  6460. if (p == (const Quantum *) NULL)
  6461. break;
  6462. nibble=0;
  6463. for (x=(int) canvas->columns-1; x >= 0; x--)
  6464. {
  6465. pixel=XGammaPixel(canvas,map_info,p);
  6466. pixel&=0xf;
  6467. switch (nibble)
  6468. {
  6469. case 0:
  6470. {
  6471. *q=(unsigned char) (pixel << 6);
  6472. nibble++;
  6473. break;
  6474. }
  6475. case 1:
  6476. {
  6477. *q|=(unsigned char) (pixel << 4);
  6478. nibble++;
  6479. break;
  6480. }
  6481. case 2:
  6482. {
  6483. *q|=(unsigned char) (pixel << 2);
  6484. nibble++;
  6485. break;
  6486. }
  6487. case 3:
  6488. {
  6489. *q|=(unsigned char) pixel;
  6490. q++;
  6491. nibble=0;
  6492. break;
  6493. }
  6494. }
  6495. p+=GetPixelChannels(canvas);
  6496. }
  6497. q+=scanline_pad;
  6498. }
  6499. break;
  6500. }
  6501. case 4:
  6502. {
  6503. register unsigned int
  6504. nibble;
  6505. /*
  6506. Convert to 4 bit continuous-tone X canvas.
  6507. */
  6508. for (y=0; y < (int) canvas->rows; y++)
  6509. {
  6510. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6511. canvas->columns,1,exception);
  6512. if (p == (const Quantum *) NULL)
  6513. break;
  6514. nibble=0;
  6515. for (x=(int) canvas->columns-1; x >= 0; x--)
  6516. {
  6517. pixel=XGammaPixel(canvas,map_info,p);
  6518. pixel&=0xf;
  6519. switch (nibble)
  6520. {
  6521. case 0:
  6522. {
  6523. *q=(unsigned char) (pixel << 4);
  6524. nibble++;
  6525. break;
  6526. }
  6527. case 1:
  6528. {
  6529. *q|=(unsigned char) pixel;
  6530. q++;
  6531. nibble=0;
  6532. break;
  6533. }
  6534. }
  6535. p+=GetPixelChannels(canvas);
  6536. }
  6537. q+=scanline_pad;
  6538. }
  6539. break;
  6540. }
  6541. case 6:
  6542. case 8:
  6543. {
  6544. /*
  6545. Convert to 8 bit continuous-tone X canvas.
  6546. */
  6547. if ((resource_info->color_recovery != MagickFalse) &&
  6548. (resource_info->quantize_info->dither_method != NoDitherMethod))
  6549. {
  6550. XDitherImage(canvas,ximage,exception);
  6551. break;
  6552. }
  6553. for (y=0; y < (int) canvas->rows; y++)
  6554. {
  6555. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6556. canvas->columns,1,exception);
  6557. if (p == (const Quantum *) NULL)
  6558. break;
  6559. for (x=(int) canvas->columns-1; x >= 0; x--)
  6560. {
  6561. pixel=XGammaPixel(canvas,map_info,p);
  6562. *q++=(unsigned char) pixel;
  6563. p+=GetPixelChannels(canvas);
  6564. }
  6565. q+=scanline_pad;
  6566. }
  6567. break;
  6568. }
  6569. default:
  6570. {
  6571. if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
  6572. (map_info->green_max == 255) && (map_info->blue_max == 255) &&
  6573. (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
  6574. (map_info->blue_mult == 1))
  6575. {
  6576. /*
  6577. Convert to 32 bit continuous-tone X canvas.
  6578. */
  6579. for (y=0; y < (int) canvas->rows; y++)
  6580. {
  6581. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6582. canvas->columns,1,exception);
  6583. if (p == (const Quantum *) NULL)
  6584. break;
  6585. if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
  6586. (blue_gamma != 1.0))
  6587. {
  6588. /*
  6589. Gamma correct canvas.
  6590. */
  6591. for (x=(int) canvas->columns-1; x >= 0; x--)
  6592. {
  6593. *q++=0;
  6594. *q++=ScaleQuantumToChar(XRedGamma(
  6595. GetPixelRed(canvas,p)));
  6596. *q++=ScaleQuantumToChar(XGreenGamma(
  6597. GetPixelGreen(canvas,p)));
  6598. *q++=ScaleQuantumToChar(XBlueGamma(
  6599. GetPixelBlue(canvas,p)));
  6600. p+=GetPixelChannels(canvas);
  6601. }
  6602. continue;
  6603. }
  6604. for (x=(int) canvas->columns-1; x >= 0; x--)
  6605. {
  6606. *q++=0;
  6607. *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
  6608. *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
  6609. *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
  6610. p+=GetPixelChannels(canvas);
  6611. }
  6612. }
  6613. }
  6614. else
  6615. if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
  6616. (map_info->green_max == 255) && (map_info->blue_max == 255) &&
  6617. (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
  6618. (map_info->blue_mult == 65536L))
  6619. {
  6620. /*
  6621. Convert to 32 bit continuous-tone X canvas.
  6622. */
  6623. for (y=0; y < (int) canvas->rows; y++)
  6624. {
  6625. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6626. canvas->columns,1,exception);
  6627. if (p == (const Quantum *) NULL)
  6628. break;
  6629. if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
  6630. (blue_gamma != 1.0))
  6631. {
  6632. /*
  6633. Gamma correct canvas.
  6634. */
  6635. for (x=(int) canvas->columns-1; x >= 0; x--)
  6636. {
  6637. *q++=0;
  6638. *q++=ScaleQuantumToChar(XBlueGamma(
  6639. GetPixelBlue(canvas,p)));
  6640. *q++=ScaleQuantumToChar(XGreenGamma(
  6641. GetPixelGreen(canvas,p)));
  6642. *q++=ScaleQuantumToChar(XRedGamma(
  6643. GetPixelRed(canvas,p)));
  6644. p+=GetPixelChannels(canvas);
  6645. }
  6646. continue;
  6647. }
  6648. for (x=(int) canvas->columns-1; x >= 0; x--)
  6649. {
  6650. *q++=0;
  6651. *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
  6652. *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
  6653. *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
  6654. p+=GetPixelChannels(canvas);
  6655. }
  6656. }
  6657. }
  6658. else
  6659. {
  6660. register int
  6661. k;
  6662. register unsigned int
  6663. bytes_per_pixel;
  6664. unsigned char
  6665. channel[sizeof(size_t)];
  6666. /*
  6667. Convert to multi-byte continuous-tone X canvas.
  6668. */
  6669. bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
  6670. for (y=0; y < (int) canvas->rows; y++)
  6671. {
  6672. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
  6673. canvas->columns,1,exception);
  6674. if (p == (const Quantum *) NULL)
  6675. break;
  6676. for (x=(int) canvas->columns-1; x >= 0; x--)
  6677. {
  6678. pixel=XGammaPixel(canvas,map_info,p);
  6679. for (k=(int) bytes_per_pixel-1; k >= 0; k--)
  6680. {
  6681. channel[k]=(unsigned char) pixel;
  6682. pixel>>=8;
  6683. }
  6684. for (k=0; k < (int) bytes_per_pixel; k++)
  6685. *q++=channel[k];
  6686. p+=GetPixelChannels(canvas);
  6687. }
  6688. q+=scanline_pad;
  6689. }
  6690. }
  6691. break;
  6692. }
  6693. }
  6694. if (matte_image != (XImage *) NULL)
  6695. {
  6696. /*
  6697. Initialize matte canvas.
  6698. */
  6699. scanline_pad=(unsigned int) (matte_image->bytes_per_line-
  6700. ((matte_image->width*matte_image->bits_per_pixel) >> 3));
  6701. q=(unsigned char *) matte_image->data;
  6702. for (y=0; y < (int) canvas->rows; y++)
  6703. {
  6704. p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
  6705. exception);
  6706. if (p == (const Quantum *) NULL)
  6707. break;
  6708. bit=0;
  6709. byte=0;
  6710. for (x=(int) canvas->columns-1; x >= 0; x--)
  6711. {
  6712. byte<<=1;
  6713. if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
  6714. byte|=0x01;
  6715. bit++;
  6716. if (bit == 8)
  6717. {
  6718. *q++=byte;
  6719. bit=0;
  6720. byte=0;
  6721. }
  6722. p+=GetPixelChannels(canvas);
  6723. }
  6724. if (bit != 0)
  6725. *q=byte << (8-bit);
  6726. q+=scanline_pad;
  6727. }
  6728. }
  6729. canvas_view=DestroyCacheView(canvas_view);
  6730. if (canvas != image)
  6731. canvas=DestroyImage(canvas);
  6732. }
  6733. /*
  6734. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6735. % %
  6736. % %
  6737. % %
  6738. % X M a k e M a g n i f y I m a g e %
  6739. % %
  6740. % %
  6741. % %
  6742. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6743. %
  6744. % XMakeMagnifyImage() magnifies a region of an X image and displays it.
  6745. %
  6746. % The format of the XMakeMagnifyImage method is:
  6747. %
  6748. % void XMakeMagnifyImage(Display *display,XWindows *windows,
  6749. % ExceptionInfo *exception)
  6750. %
  6751. % A description of each parameter follows:
  6752. %
  6753. % o display: Specifies a connection to an X server; returned from
  6754. % XOpenDisplay.
  6755. %
  6756. % o windows: Specifies a pointer to a XWindows structure.
  6757. %
  6758. % o exception: return any errors or warnings in this structure.
  6759. %
  6760. */
  6761. MagickPrivate void XMakeMagnifyImage(Display *display,XWindows *windows,
  6762. ExceptionInfo *exception)
  6763. {
  6764. char
  6765. tuple[MagickPathExtent];
  6766. int
  6767. y;
  6768. PixelInfo
  6769. pixel;
  6770. register int
  6771. x;
  6772. register ssize_t
  6773. i;
  6774. register unsigned char
  6775. *p,
  6776. *q;
  6777. ssize_t
  6778. n;
  6779. static unsigned int
  6780. previous_magnify = 0;
  6781. static XWindowInfo
  6782. magnify_window;
  6783. unsigned int
  6784. height,
  6785. j,
  6786. k,
  6787. l,
  6788. magnify,
  6789. scanline_pad,
  6790. width;
  6791. XImage
  6792. *ximage;
  6793. /*
  6794. Check boundary conditions.
  6795. */
  6796. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  6797. assert(display != (Display *) NULL);
  6798. assert(windows != (XWindows *) NULL);
  6799. magnify=1;
  6800. for (n=1; n < (ssize_t) windows->magnify.data; n++)
  6801. magnify<<=1;
  6802. while ((magnify*windows->image.ximage->width) < windows->magnify.width)
  6803. magnify<<=1;
  6804. while ((magnify*windows->image.ximage->height) < windows->magnify.height)
  6805. magnify<<=1;
  6806. while (magnify > windows->magnify.width)
  6807. magnify>>=1;
  6808. while (magnify > windows->magnify.height)
  6809. magnify>>=1;
  6810. if (magnify == 0)
  6811. magnify=1;
  6812. if (magnify != previous_magnify)
  6813. {
  6814. Status
  6815. status;
  6816. XTextProperty
  6817. window_name;
  6818. /*
  6819. New magnify factor: update magnify window name.
  6820. */
  6821. i=0;
  6822. while ((1 << i) <= (int) magnify)
  6823. i++;
  6824. (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
  6825. "Magnify %.20gX",(double) i);
  6826. status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
  6827. if (status != False)
  6828. {
  6829. XSetWMName(display,windows->magnify.id,&window_name);
  6830. XSetWMIconName(display,windows->magnify.id,&window_name);
  6831. (void) XFree((void *) window_name.value);
  6832. }
  6833. }
  6834. previous_magnify=magnify;
  6835. ximage=windows->image.ximage;
  6836. width=(unsigned int) windows->magnify.ximage->width;
  6837. height=(unsigned int) windows->magnify.ximage->height;
  6838. if ((windows->magnify.x < 0) ||
  6839. (windows->magnify.x >= windows->image.ximage->width))
  6840. windows->magnify.x=windows->image.ximage->width >> 1;
  6841. x=windows->magnify.x-((width/magnify) >> 1);
  6842. if (x < 0)
  6843. x=0;
  6844. else
  6845. if (x > (int) (ximage->width-(width/magnify)))
  6846. x=ximage->width-width/magnify;
  6847. if ((windows->magnify.y < 0) ||
  6848. (windows->magnify.y >= windows->image.ximage->height))
  6849. windows->magnify.y=windows->image.ximage->height >> 1;
  6850. y=windows->magnify.y-((height/magnify) >> 1);
  6851. if (y < 0)
  6852. y=0;
  6853. else
  6854. if (y > (int) (ximage->height-(height/magnify)))
  6855. y=ximage->height-height/magnify;
  6856. q=(unsigned char *) windows->magnify.ximage->data;
  6857. scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line-
  6858. ((width*windows->magnify.ximage->bits_per_pixel) >> 3));
  6859. if (ximage->bits_per_pixel < 8)
  6860. {
  6861. register unsigned char
  6862. background,
  6863. byte,
  6864. foreground,
  6865. p_bit,
  6866. q_bit;
  6867. register unsigned int
  6868. plane;
  6869. XPixelInfo
  6870. *pixel_info;
  6871. pixel_info=windows->magnify.pixel_info;
  6872. switch (ximage->bitmap_bit_order)
  6873. {
  6874. case LSBFirst:
  6875. {
  6876. /*
  6877. Magnify little-endian bitmap.
  6878. */
  6879. background=0x00;
  6880. foreground=0x80;
  6881. if (ximage->format == XYBitmap)
  6882. {
  6883. background=(unsigned char)
  6884. (XPixelIntensity(&pixel_info->foreground_color) <
  6885. XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00);
  6886. foreground=(unsigned char)
  6887. (XPixelIntensity(&pixel_info->background_color) <
  6888. XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00);
  6889. if (windows->magnify.depth > 1)
  6890. Swap(background,foreground);
  6891. }
  6892. for (i=0; i < (ssize_t) height; i+=magnify)
  6893. {
  6894. /*
  6895. Propogate pixel magnify rows.
  6896. */
  6897. for (j=0; j < magnify; j++)
  6898. {
  6899. p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  6900. ((x*ximage->bits_per_pixel) >> 3);
  6901. p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
  6902. q_bit=0;
  6903. byte=0;
  6904. for (k=0; k < width; k+=magnify)
  6905. {
  6906. /*
  6907. Propogate pixel magnify columns.
  6908. */
  6909. for (l=0; l < magnify; l++)
  6910. {
  6911. /*
  6912. Propogate each bit plane.
  6913. */
  6914. for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
  6915. {
  6916. byte>>=1;
  6917. if (*p & (0x01 << (p_bit+plane)))
  6918. byte|=foreground;
  6919. else
  6920. byte|=background;
  6921. q_bit++;
  6922. if (q_bit == 8)
  6923. {
  6924. *q++=byte;
  6925. q_bit=0;
  6926. byte=0;
  6927. }
  6928. }
  6929. }
  6930. p_bit+=ximage->bits_per_pixel;
  6931. if (p_bit == 8)
  6932. {
  6933. p++;
  6934. p_bit=0;
  6935. }
  6936. if (q_bit != 0)
  6937. *q=byte >> (8-q_bit);
  6938. q+=scanline_pad;
  6939. }
  6940. }
  6941. y++;
  6942. }
  6943. break;
  6944. }
  6945. case MSBFirst:
  6946. default:
  6947. {
  6948. /*
  6949. Magnify big-endian bitmap.
  6950. */
  6951. background=0x00;
  6952. foreground=0x01;
  6953. if (ximage->format == XYBitmap)
  6954. {
  6955. background=(unsigned char)
  6956. (XPixelIntensity(&pixel_info->foreground_color) <
  6957. XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00);
  6958. foreground=(unsigned char)
  6959. (XPixelIntensity(&pixel_info->background_color) <
  6960. XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00);
  6961. if (windows->magnify.depth > 1)
  6962. Swap(background,foreground);
  6963. }
  6964. for (i=0; i < (ssize_t) height; i+=magnify)
  6965. {
  6966. /*
  6967. Propogate pixel magnify rows.
  6968. */
  6969. for (j=0; j < magnify; j++)
  6970. {
  6971. p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  6972. ((x*ximage->bits_per_pixel) >> 3);
  6973. p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
  6974. q_bit=0;
  6975. byte=0;
  6976. for (k=0; k < width; k+=magnify)
  6977. {
  6978. /*
  6979. Propogate pixel magnify columns.
  6980. */
  6981. for (l=0; l < magnify; l++)
  6982. {
  6983. /*
  6984. Propogate each bit plane.
  6985. */
  6986. for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
  6987. {
  6988. byte<<=1;
  6989. if (*p & (0x80 >> (p_bit+plane)))
  6990. byte|=foreground;
  6991. else
  6992. byte|=background;
  6993. q_bit++;
  6994. if (q_bit == 8)
  6995. {
  6996. *q++=byte;
  6997. q_bit=0;
  6998. byte=0;
  6999. }
  7000. }
  7001. }
  7002. p_bit+=ximage->bits_per_pixel;
  7003. if (p_bit == 8)
  7004. {
  7005. p++;
  7006. p_bit=0;
  7007. }
  7008. if (q_bit != 0)
  7009. *q=byte << (8-q_bit);
  7010. q+=scanline_pad;
  7011. }
  7012. }
  7013. y++;
  7014. }
  7015. break;
  7016. }
  7017. }
  7018. }
  7019. else
  7020. switch (ximage->bits_per_pixel)
  7021. {
  7022. case 6:
  7023. case 8:
  7024. {
  7025. /*
  7026. Magnify 8 bit X image.
  7027. */
  7028. for (i=0; i < (ssize_t) height; i+=magnify)
  7029. {
  7030. /*
  7031. Propogate pixel magnify rows.
  7032. */
  7033. for (j=0; j < magnify; j++)
  7034. {
  7035. p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  7036. ((x*ximage->bits_per_pixel) >> 3);
  7037. for (k=0; k < width; k+=magnify)
  7038. {
  7039. /*
  7040. Propogate pixel magnify columns.
  7041. */
  7042. for (l=0; l < magnify; l++)
  7043. *q++=(*p);
  7044. p++;
  7045. }
  7046. q+=scanline_pad;
  7047. }
  7048. y++;
  7049. }
  7050. break;
  7051. }
  7052. default:
  7053. {
  7054. register unsigned int
  7055. bytes_per_pixel,
  7056. m;
  7057. /*
  7058. Magnify multi-byte X image.
  7059. */
  7060. bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3;
  7061. for (i=0; i < (ssize_t) height; i+=magnify)
  7062. {
  7063. /*
  7064. Propogate pixel magnify rows.
  7065. */
  7066. for (j=0; j < magnify; j++)
  7067. {
  7068. p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  7069. ((x*ximage->bits_per_pixel) >> 3);
  7070. for (k=0; k < width; k+=magnify)
  7071. {
  7072. /*
  7073. Propogate pixel magnify columns.
  7074. */
  7075. for (l=0; l < magnify; l++)
  7076. for (m=0; m < bytes_per_pixel; m++)
  7077. *q++=(*(p+m));
  7078. p+=bytes_per_pixel;
  7079. }
  7080. q+=scanline_pad;
  7081. }
  7082. y++;
  7083. }
  7084. break;
  7085. }
  7086. }
  7087. /*
  7088. Copy X image to magnify pixmap.
  7089. */
  7090. x=windows->magnify.x-((width/magnify) >> 1);
  7091. if (x < 0)
  7092. x=(int) ((width >> 1)-windows->magnify.x*magnify);
  7093. else
  7094. if (x > (int) (ximage->width-(width/magnify)))
  7095. x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1));
  7096. else
  7097. x=0;
  7098. y=windows->magnify.y-((height/magnify) >> 1);
  7099. if (y < 0)
  7100. y=(int) ((height >> 1)-windows->magnify.y*magnify);
  7101. else
  7102. if (y > (int) (ximage->height-(height/magnify)))
  7103. y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1));
  7104. else
  7105. y=0;
  7106. if ((x != 0) || (y != 0))
  7107. (void) XFillRectangle(display,windows->magnify.pixmap,
  7108. windows->magnify.annotate_context,0,0,width,height);
  7109. (void) XPutImage(display,windows->magnify.pixmap,
  7110. windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
  7111. height-y);
  7112. if ((magnify > 1) && ((magnify <= (width >> 1)) &&
  7113. (magnify <= (height >> 1))))
  7114. {
  7115. RectangleInfo
  7116. highlight_info;
  7117. /*
  7118. Highlight center pixel.
  7119. */
  7120. highlight_info.x=(ssize_t) windows->magnify.width >> 1;
  7121. highlight_info.y=(ssize_t) windows->magnify.height >> 1;
  7122. highlight_info.width=magnify;
  7123. highlight_info.height=magnify;
  7124. (void) XDrawRectangle(display,windows->magnify.pixmap,
  7125. windows->magnify.highlight_context,(int) highlight_info.x,
  7126. (int) highlight_info.y,(unsigned int) highlight_info.width-1,
  7127. (unsigned int) highlight_info.height-1);
  7128. if (magnify > 2)
  7129. (void) XDrawRectangle(display,windows->magnify.pixmap,
  7130. windows->magnify.annotate_context,(int) highlight_info.x+1,
  7131. (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
  7132. (unsigned int) highlight_info.height-3);
  7133. }
  7134. /*
  7135. Show center pixel color.
  7136. */
  7137. (void) GetOneVirtualPixelInfo(windows->image.image,TileVirtualPixelMethod,
  7138. (ssize_t) windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,exception);
  7139. (void) FormatLocaleString(tuple,MagickPathExtent,"%d,%d: ",
  7140. windows->magnify.x,windows->magnify.y);
  7141. (void) ConcatenateMagickString(tuple,"(",MagickPathExtent);
  7142. ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple);
  7143. (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
  7144. ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple);
  7145. (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
  7146. ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple);
  7147. if (pixel.colorspace == CMYKColorspace)
  7148. {
  7149. (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
  7150. ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple);
  7151. }
  7152. if (pixel.alpha_trait != UndefinedPixelTrait)
  7153. {
  7154. (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
  7155. ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple);
  7156. }
  7157. (void) ConcatenateMagickString(tuple,")",MagickPathExtent);
  7158. height=(unsigned int) windows->magnify.font_info->ascent+
  7159. windows->magnify.font_info->descent;
  7160. x=windows->magnify.font_info->max_bounds.width >> 1;
  7161. y=windows->magnify.font_info->ascent+(height >> 2);
  7162. (void) XDrawImageString(display,windows->magnify.pixmap,
  7163. windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
  7164. GetColorTuple(&pixel,MagickTrue,tuple);
  7165. y+=height;
  7166. (void) XDrawImageString(display,windows->magnify.pixmap,
  7167. windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
  7168. (void) QueryColorname(windows->image.image,&pixel,SVGCompliance,tuple,
  7169. exception);
  7170. y+=height;
  7171. (void) XDrawImageString(display,windows->magnify.pixmap,
  7172. windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
  7173. /*
  7174. Refresh magnify window.
  7175. */
  7176. magnify_window=windows->magnify;
  7177. magnify_window.x=0;
  7178. magnify_window.y=0;
  7179. XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
  7180. }
  7181. /*
  7182. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7183. % %
  7184. % %
  7185. % %
  7186. % X M a k e P i x m a p %
  7187. % %
  7188. % %
  7189. % %
  7190. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7191. %
  7192. % XMakePixmap() creates an X11 pixmap.
  7193. %
  7194. % The format of the XMakePixmap method is:
  7195. %
  7196. % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
  7197. % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
  7198. % XPixelInfo *pixel)
  7199. %
  7200. % A description of each parameter follows:
  7201. %
  7202. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  7203. %
  7204. % o display: Specifies a connection to an X server; returned from
  7205. % XOpenDisplay.
  7206. %
  7207. % o window: Specifies a pointer to a XWindowInfo structure.
  7208. %
  7209. */
  7210. static MagickBooleanType XMakePixmap(Display *display,
  7211. const XResourceInfo *resource_info,XWindowInfo *window)
  7212. {
  7213. unsigned int
  7214. height,
  7215. width;
  7216. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  7217. assert(display != (Display *) NULL);
  7218. assert(resource_info != (XResourceInfo *) NULL);
  7219. assert(window != (XWindowInfo *) NULL);
  7220. if (window->pixmap != (Pixmap) NULL)
  7221. {
  7222. /*
  7223. Destroy previous X pixmap.
  7224. */
  7225. (void) XFreePixmap(display,window->pixmap);
  7226. window->pixmap=(Pixmap) NULL;
  7227. }
  7228. if (window->use_pixmap == MagickFalse)
  7229. return(MagickFalse);
  7230. if (window->ximage == (XImage *) NULL)
  7231. return(MagickFalse);
  7232. /*
  7233. Display busy cursor.
  7234. */
  7235. (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
  7236. (void) XFlush(display);
  7237. /*
  7238. Create pixmap.
  7239. */
  7240. width=(unsigned int) window->ximage->width;
  7241. height=(unsigned int) window->ximage->height;
  7242. window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
  7243. if (window->pixmap == (Pixmap) NULL)
  7244. {
  7245. /*
  7246. Unable to allocate pixmap.
  7247. */
  7248. (void) XCheckDefineCursor(display,window->id,window->cursor);
  7249. return(MagickFalse);
  7250. }
  7251. /*
  7252. Copy X image to pixmap.
  7253. */
  7254. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  7255. if (window->shared_memory)
  7256. (void) XShmPutImage(display,window->pixmap,window->annotate_context,
  7257. window->ximage,0,0,0,0,width,height,MagickTrue);
  7258. #endif
  7259. if (window->shared_memory == MagickFalse)
  7260. (void) XPutImage(display,window->pixmap,window->annotate_context,
  7261. window->ximage,0,0,0,0,width,height);
  7262. if (IsEventLogging())
  7263. {
  7264. (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
  7265. (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u",
  7266. width,height);
  7267. }
  7268. /*
  7269. Restore cursor.
  7270. */
  7271. (void) XCheckDefineCursor(display,window->id,window->cursor);
  7272. return(MagickTrue);
  7273. }
  7274. /*
  7275. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7276. % %
  7277. % %
  7278. % %
  7279. % X M a k e S t a n d a r d C o l o r m a p %
  7280. % %
  7281. % %
  7282. % %
  7283. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7284. %
  7285. % XMakeStandardColormap() creates an X11 Standard Colormap.
  7286. %
  7287. % The format of the XMakeStandardColormap method is:
  7288. %
  7289. % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
  7290. % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
  7291. % XPixelInfo *pixel,ExceptionInfo *exception)
  7292. %
  7293. % A description of each parameter follows:
  7294. %
  7295. % o display: Specifies a connection to an X server; returned from
  7296. % XOpenDisplay.
  7297. %
  7298. % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  7299. % returned from XGetVisualInfo.
  7300. %
  7301. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  7302. %
  7303. % o image: the image.
  7304. %
  7305. % o map_info: If a Standard Colormap type is specified, this structure is
  7306. % initialized with info from the Standard Colormap.
  7307. %
  7308. % o pixel: Specifies a pointer to a XPixelInfo structure.
  7309. %
  7310. % o exception: return any errors or warnings in this structure.
  7311. %
  7312. */
  7313. #if defined(__cplusplus) || defined(c_plusplus)
  7314. extern "C" {
  7315. #endif
  7316. static inline double DiversityPixelIntensity(
  7317. const DiversityPacket *pixel)
  7318. {
  7319. double
  7320. intensity;
  7321. intensity=0.212656*pixel->red+0.715158*pixel->green+0.072186*pixel->blue;
  7322. return(intensity);
  7323. }
  7324. static int IntensityCompare(const void *x,const void *y)
  7325. {
  7326. DiversityPacket
  7327. *color_1,
  7328. *color_2;
  7329. int
  7330. diversity;
  7331. color_1=(DiversityPacket *) x;
  7332. color_2=(DiversityPacket *) y;
  7333. diversity=(int) (DiversityPixelIntensity(color_2)-
  7334. DiversityPixelIntensity(color_1));
  7335. return(diversity);
  7336. }
  7337. static int PopularityCompare(const void *x,const void *y)
  7338. {
  7339. DiversityPacket
  7340. *color_1,
  7341. *color_2;
  7342. color_1=(DiversityPacket *) x;
  7343. color_2=(DiversityPacket *) y;
  7344. return((int) color_2->count-(int) color_1->count);
  7345. }
  7346. #if defined(__cplusplus) || defined(c_plusplus)
  7347. }
  7348. #endif
  7349. static inline Quantum ScaleXToQuantum(const size_t x,
  7350. const size_t scale)
  7351. {
  7352. return((Quantum) (((double) QuantumRange*x)/scale+0.5));
  7353. }
  7354. MagickPrivate void XMakeStandardColormap(Display *display,
  7355. XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image,
  7356. XStandardColormap *map_info,XPixelInfo *pixel,ExceptionInfo *exception)
  7357. {
  7358. Colormap
  7359. colormap;
  7360. register ssize_t
  7361. i;
  7362. Status
  7363. status;
  7364. size_t
  7365. number_colors,
  7366. retain_colors;
  7367. unsigned short
  7368. gray_value;
  7369. XColor
  7370. color,
  7371. *colors,
  7372. *p;
  7373. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  7374. assert(display != (Display *) NULL);
  7375. assert(visual_info != (XVisualInfo *) NULL);
  7376. assert(map_info != (XStandardColormap *) NULL);
  7377. assert(resource_info != (XResourceInfo *) NULL);
  7378. assert(pixel != (XPixelInfo *) NULL);
  7379. if (resource_info->map_type != (char *) NULL)
  7380. {
  7381. /*
  7382. Standard Colormap is already defined (i.e. xstdcmap).
  7383. */
  7384. XGetPixelInfo(display,visual_info,map_info,resource_info,image,
  7385. pixel);
  7386. number_colors=(unsigned int) (map_info->base_pixel+
  7387. (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
  7388. if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
  7389. if ((image->alpha_trait == UndefinedPixelTrait) &&
  7390. (resource_info->color_recovery == MagickFalse) &&
  7391. (resource_info->quantize_info->dither_method != NoDitherMethod) &&
  7392. (number_colors < MaxColormapSize))
  7393. {
  7394. Image
  7395. *affinity_image;
  7396. register Quantum
  7397. *magick_restrict q;
  7398. /*
  7399. Improve image appearance with error diffusion.
  7400. */
  7401. affinity_image=AcquireImage((ImageInfo *) NULL,exception);
  7402. if (affinity_image == (Image *) NULL)
  7403. ThrowXWindowFatalException(ResourceLimitFatalError,
  7404. "UnableToDitherImage",image->filename);
  7405. affinity_image->columns=number_colors;
  7406. affinity_image->rows=1;
  7407. /*
  7408. Initialize colormap image.
  7409. */
  7410. q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
  7411. 1,exception);
  7412. if (q != (Quantum *) NULL)
  7413. {
  7414. for (i=0; i < (ssize_t) number_colors; i++)
  7415. {
  7416. SetPixelRed(affinity_image,0,q);
  7417. if (map_info->red_max != 0)
  7418. SetPixelRed(affinity_image,ScaleXToQuantum((size_t)
  7419. (i/map_info->red_mult),map_info->red_max),q);
  7420. SetPixelGreen(affinity_image,0,q);
  7421. if (map_info->green_max != 0)
  7422. SetPixelGreen(affinity_image,ScaleXToQuantum((size_t)
  7423. ((i/map_info->green_mult) % (map_info->green_max+1)),
  7424. map_info->green_max),q);
  7425. SetPixelBlue(affinity_image,0,q);
  7426. if (map_info->blue_max != 0)
  7427. SetPixelBlue(affinity_image,ScaleXToQuantum((size_t)
  7428. (i % map_info->green_mult),map_info->blue_max),q);
  7429. SetPixelAlpha(affinity_image,
  7430. TransparentAlpha,q);
  7431. q+=GetPixelChannels(affinity_image);
  7432. }
  7433. (void) SyncAuthenticPixels(affinity_image,exception);
  7434. (void) RemapImage(resource_info->quantize_info,image,
  7435. affinity_image,exception);
  7436. }
  7437. XGetPixelInfo(display,visual_info,map_info,resource_info,image,
  7438. pixel);
  7439. (void) SetImageStorageClass(image,DirectClass,exception);
  7440. affinity_image=DestroyImage(affinity_image);
  7441. }
  7442. if (IsEventLogging())
  7443. {
  7444. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7445. "Standard Colormap:");
  7446. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7447. " colormap id: 0x%lx",map_info->colormap);
  7448. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7449. " red, green, blue max: %lu %lu %lu",map_info->red_max,
  7450. map_info->green_max,map_info->blue_max);
  7451. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7452. " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
  7453. map_info->green_mult,map_info->blue_mult);
  7454. }
  7455. return;
  7456. }
  7457. if ((visual_info->klass != DirectColor) &&
  7458. (visual_info->klass != TrueColor))
  7459. if ((image->storage_class == DirectClass) ||
  7460. ((int) image->colors > visual_info->colormap_size))
  7461. {
  7462. QuantizeInfo
  7463. quantize_info;
  7464. /*
  7465. Image has more colors than the visual supports.
  7466. */
  7467. quantize_info=(*resource_info->quantize_info);
  7468. quantize_info.number_colors=(size_t) visual_info->colormap_size;
  7469. (void) QuantizeImage(&quantize_info,image,exception);
  7470. }
  7471. /*
  7472. Free previous and create new colormap.
  7473. */
  7474. (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
  7475. colormap=XDefaultColormap(display,visual_info->screen);
  7476. if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  7477. colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
  7478. visual_info->visual,visual_info->klass == DirectColor ?
  7479. AllocAll : AllocNone);
  7480. if (colormap == (Colormap) NULL)
  7481. ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap",
  7482. image->filename);
  7483. /*
  7484. Initialize the map and pixel info structures.
  7485. */
  7486. XGetMapInfo(visual_info,colormap,map_info);
  7487. XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel);
  7488. /*
  7489. Allocating colors in server colormap is based on visual class.
  7490. */
  7491. switch (visual_info->klass)
  7492. {
  7493. case StaticGray:
  7494. case StaticColor:
  7495. {
  7496. /*
  7497. Define Standard Colormap for StaticGray or StaticColor visual.
  7498. */
  7499. number_colors=image->colors;
  7500. colors=(XColor *) AcquireQuantumMemory((size_t)
  7501. visual_info->colormap_size,sizeof(*colors));
  7502. if (colors == (XColor *) NULL)
  7503. ThrowXWindowFatalException(ResourceLimitFatalError,
  7504. "UnableToCreateColormap",image->filename);
  7505. p=colors;
  7506. color.flags=(char) (DoRed | DoGreen | DoBlue);
  7507. for (i=0; i < (ssize_t) image->colors; i++)
  7508. {
  7509. color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
  7510. color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
  7511. color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
  7512. if (visual_info->klass != StaticColor)
  7513. {
  7514. gray_value=(unsigned short) XPixelIntensity(&color);
  7515. color.red=gray_value;
  7516. color.green=gray_value;
  7517. color.blue=gray_value;
  7518. }
  7519. status=XAllocColor(display,colormap,&color);
  7520. if (status == False)
  7521. {
  7522. colormap=XCopyColormapAndFree(display,colormap);
  7523. (void) XAllocColor(display,colormap,&color);
  7524. }
  7525. pixel->pixels[i]=color.pixel;
  7526. *p++=color;
  7527. }
  7528. break;
  7529. }
  7530. case GrayScale:
  7531. case PseudoColor:
  7532. {
  7533. unsigned int
  7534. colormap_type;
  7535. /*
  7536. Define Standard Colormap for GrayScale or PseudoColor visual.
  7537. */
  7538. number_colors=image->colors;
  7539. colors=(XColor *) AcquireQuantumMemory((size_t)
  7540. visual_info->colormap_size,sizeof(*colors));
  7541. if (colors == (XColor *) NULL)
  7542. ThrowXWindowFatalException(ResourceLimitFatalError,
  7543. "UnableToCreateColormap",image->filename);
  7544. /*
  7545. Preallocate our GUI colors.
  7546. */
  7547. (void) XAllocColor(display,colormap,&pixel->foreground_color);
  7548. (void) XAllocColor(display,colormap,&pixel->background_color);
  7549. (void) XAllocColor(display,colormap,&pixel->border_color);
  7550. (void) XAllocColor(display,colormap,&pixel->matte_color);
  7551. (void) XAllocColor(display,colormap,&pixel->highlight_color);
  7552. (void) XAllocColor(display,colormap,&pixel->shadow_color);
  7553. (void) XAllocColor(display,colormap,&pixel->depth_color);
  7554. (void) XAllocColor(display,colormap,&pixel->trough_color);
  7555. for (i=0; i < MaxNumberPens; i++)
  7556. (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
  7557. /*
  7558. Determine if image colors will "fit" into X server colormap.
  7559. */
  7560. colormap_type=resource_info->colormap;
  7561. status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *)
  7562. NULL,0,pixel->pixels,(unsigned int) image->colors);
  7563. if (status != False)
  7564. colormap_type=PrivateColormap;
  7565. if (colormap_type == SharedColormap)
  7566. {
  7567. CacheView
  7568. *image_view;
  7569. DiversityPacket
  7570. *diversity;
  7571. int
  7572. y;
  7573. register int
  7574. x;
  7575. unsigned short
  7576. index;
  7577. XColor
  7578. *server_colors;
  7579. /*
  7580. Define Standard colormap for shared GrayScale or PseudoColor visual.
  7581. */
  7582. diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors,
  7583. sizeof(*diversity));
  7584. if (diversity == (DiversityPacket *) NULL)
  7585. ThrowXWindowFatalException(ResourceLimitFatalError,
  7586. "UnableToCreateColormap",image->filename);
  7587. for (i=0; i < (ssize_t) image->colors; i++)
  7588. {
  7589. diversity[i].red=ClampToQuantum(image->colormap[i].red);
  7590. diversity[i].green=ClampToQuantum(image->colormap[i].green);
  7591. diversity[i].blue=ClampToQuantum(image->colormap[i].blue);
  7592. diversity[i].index=(unsigned short) i;
  7593. diversity[i].count=0;
  7594. }
  7595. image_view=AcquireAuthenticCacheView(image,exception);
  7596. for (y=0; y < (int) image->rows; y++)
  7597. {
  7598. register int
  7599. x;
  7600. register const Quantum
  7601. *magick_restrict p;
  7602. p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
  7603. image->columns,1,exception);
  7604. if (p == (const Quantum *) NULL)
  7605. break;
  7606. for (x=(int) image->columns-1; x >= 0; x--)
  7607. {
  7608. diversity[(ssize_t) GetPixelIndex(image,p)].count++;
  7609. p+=GetPixelChannels(image);
  7610. }
  7611. }
  7612. image_view=DestroyCacheView(image_view);
  7613. /*
  7614. Sort colors by decreasing intensity.
  7615. */
  7616. qsort((void *) diversity,image->colors,sizeof(*diversity),
  7617. IntensityCompare);
  7618. for (i=0; i < (ssize_t) image->colors; )
  7619. {
  7620. diversity[i].count<<=4; /* increase this colors popularity */
  7621. i+=MagickMax((int) (image->colors >> 4),2);
  7622. }
  7623. diversity[image->colors-1].count<<=4;
  7624. qsort((void *) diversity,image->colors,sizeof(*diversity),
  7625. PopularityCompare);
  7626. /*
  7627. Allocate colors.
  7628. */
  7629. p=colors;
  7630. color.flags=(char) (DoRed | DoGreen | DoBlue);
  7631. for (i=0; i < (ssize_t) image->colors; i++)
  7632. {
  7633. index=diversity[i].index;
  7634. color.red=
  7635. ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
  7636. color.green=
  7637. ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
  7638. color.blue=
  7639. ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
  7640. if (visual_info->klass != PseudoColor)
  7641. {
  7642. gray_value=(unsigned short) XPixelIntensity(&color);
  7643. color.red=gray_value;
  7644. color.green=gray_value;
  7645. color.blue=gray_value;
  7646. }
  7647. status=XAllocColor(display,colormap,&color);
  7648. if (status == False)
  7649. break;
  7650. pixel->pixels[index]=color.pixel;
  7651. *p++=color;
  7652. }
  7653. /*
  7654. Read X server colormap.
  7655. */
  7656. server_colors=(XColor *) AcquireQuantumMemory((size_t)
  7657. visual_info->colormap_size,sizeof(*server_colors));
  7658. if (server_colors == (XColor *) NULL)
  7659. ThrowXWindowFatalException(ResourceLimitFatalError,
  7660. "UnableToCreateColormap",image->filename);
  7661. for (x=visual_info->colormap_size-1; x >= 0; x--)
  7662. server_colors[x].pixel=(size_t) x;
  7663. (void) XQueryColors(display,colormap,server_colors,
  7664. (int) MagickMin((unsigned int) visual_info->colormap_size,256));
  7665. /*
  7666. Select remaining colors from X server colormap.
  7667. */
  7668. for (; i < (ssize_t) image->colors; i++)
  7669. {
  7670. index=diversity[i].index;
  7671. color.red=ScaleQuantumToShort(
  7672. XRedGamma(image->colormap[index].red));
  7673. color.green=ScaleQuantumToShort(
  7674. XGreenGamma(image->colormap[index].green));
  7675. color.blue=ScaleQuantumToShort(
  7676. XBlueGamma(image->colormap[index].blue));
  7677. if (visual_info->klass != PseudoColor)
  7678. {
  7679. gray_value=(unsigned short) XPixelIntensity(&color);
  7680. color.red=gray_value;
  7681. color.green=gray_value;
  7682. color.blue=gray_value;
  7683. }
  7684. XBestPixel(display,colormap,server_colors,(unsigned int)
  7685. visual_info->colormap_size,&color);
  7686. pixel->pixels[index]=color.pixel;
  7687. *p++=color;
  7688. }
  7689. if ((int) image->colors < visual_info->colormap_size)
  7690. {
  7691. /*
  7692. Fill up colors array-- more choices for pen colors.
  7693. */
  7694. retain_colors=MagickMin((unsigned int)
  7695. (visual_info->colormap_size-image->colors),256);
  7696. for (i=0; i < (ssize_t) retain_colors; i++)
  7697. *p++=server_colors[i];
  7698. number_colors+=retain_colors;
  7699. }
  7700. server_colors=(XColor *) RelinquishMagickMemory(server_colors);
  7701. diversity=(DiversityPacket *) RelinquishMagickMemory(diversity);
  7702. break;
  7703. }
  7704. /*
  7705. Define Standard colormap for private GrayScale or PseudoColor visual.
  7706. */
  7707. if (status == False)
  7708. {
  7709. /*
  7710. Not enough colormap entries in the colormap-- Create a new colormap.
  7711. */
  7712. colormap=XCreateColormap(display,
  7713. XRootWindow(display,visual_info->screen),visual_info->visual,
  7714. AllocNone);
  7715. if (colormap == (Colormap) NULL)
  7716. ThrowXWindowFatalException(ResourceLimitFatalError,
  7717. "UnableToCreateColormap",image->filename);
  7718. map_info->colormap=colormap;
  7719. if ((int) image->colors < visual_info->colormap_size)
  7720. {
  7721. /*
  7722. Retain colors from the default colormap to help lessens the
  7723. effects of colormap flashing.
  7724. */
  7725. retain_colors=MagickMin((unsigned int)
  7726. (visual_info->colormap_size-image->colors),256);
  7727. p=colors+image->colors;
  7728. for (i=0; i < (ssize_t) retain_colors; i++)
  7729. {
  7730. p->pixel=(unsigned long) i;
  7731. p++;
  7732. }
  7733. (void) XQueryColors(display,
  7734. XDefaultColormap(display,visual_info->screen),
  7735. colors+image->colors,(int) retain_colors);
  7736. /*
  7737. Transfer colors from default to private colormap.
  7738. */
  7739. (void) XAllocColorCells(display,colormap,MagickFalse,
  7740. (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
  7741. retain_colors);
  7742. p=colors+image->colors;
  7743. for (i=0; i < (ssize_t) retain_colors; i++)
  7744. {
  7745. p->pixel=pixel->pixels[i];
  7746. p++;
  7747. }
  7748. (void) XStoreColors(display,colormap,colors+image->colors,
  7749. (int) retain_colors);
  7750. number_colors+=retain_colors;
  7751. }
  7752. (void) XAllocColorCells(display,colormap,MagickFalse,
  7753. (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
  7754. image->colors);
  7755. }
  7756. /*
  7757. Store the image colormap.
  7758. */
  7759. p=colors;
  7760. color.flags=(char) (DoRed | DoGreen | DoBlue);
  7761. for (i=0; i < (ssize_t) image->colors; i++)
  7762. {
  7763. color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
  7764. color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
  7765. color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
  7766. if (visual_info->klass != PseudoColor)
  7767. {
  7768. gray_value=(unsigned short) XPixelIntensity(&color);
  7769. color.red=gray_value;
  7770. color.green=gray_value;
  7771. color.blue=gray_value;
  7772. }
  7773. color.pixel=pixel->pixels[i];
  7774. *p++=color;
  7775. }
  7776. (void) XStoreColors(display,colormap,colors,(int) image->colors);
  7777. break;
  7778. }
  7779. case TrueColor:
  7780. case DirectColor:
  7781. default:
  7782. {
  7783. MagickBooleanType
  7784. linear_colormap;
  7785. /*
  7786. Define Standard Colormap for TrueColor or DirectColor visual.
  7787. */
  7788. number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
  7789. (map_info->green_max*map_info->green_mult)+
  7790. (map_info->blue_max*map_info->blue_mult)+1);
  7791. linear_colormap=(number_colors > 4096) ||
  7792. (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
  7793. ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
  7794. ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ?
  7795. MagickTrue : MagickFalse;
  7796. if (linear_colormap != MagickFalse)
  7797. number_colors=(size_t) visual_info->colormap_size;
  7798. /*
  7799. Allocate color array.
  7800. */
  7801. colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
  7802. if (colors == (XColor *) NULL)
  7803. ThrowXWindowFatalException(ResourceLimitFatalError,
  7804. "UnableToCreateColormap",image->filename);
  7805. /*
  7806. Initialize linear color ramp.
  7807. */
  7808. p=colors;
  7809. color.flags=(char) (DoRed | DoGreen | DoBlue);
  7810. if (linear_colormap != MagickFalse)
  7811. for (i=0; i < (ssize_t) number_colors; i++)
  7812. {
  7813. color.blue=(unsigned short) 0;
  7814. if (map_info->blue_max != 0)
  7815. color.blue=(unsigned short) ((size_t)
  7816. ((65535L*(i % map_info->green_mult))/map_info->blue_max));
  7817. color.green=color.blue;
  7818. color.red=color.blue;
  7819. color.pixel=XStandardPixel(map_info,&color);
  7820. *p++=color;
  7821. }
  7822. else
  7823. for (i=0; i < (ssize_t) number_colors; i++)
  7824. {
  7825. color.red=(unsigned short) 0;
  7826. if (map_info->red_max != 0)
  7827. color.red=(unsigned short) ((size_t)
  7828. ((65535L*(i/map_info->red_mult))/map_info->red_max));
  7829. color.green=(unsigned int) 0;
  7830. if (map_info->green_max != 0)
  7831. color.green=(unsigned short) ((size_t)
  7832. ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
  7833. map_info->green_max));
  7834. color.blue=(unsigned short) 0;
  7835. if (map_info->blue_max != 0)
  7836. color.blue=(unsigned short) ((size_t)
  7837. ((65535L*(i % map_info->green_mult))/map_info->blue_max));
  7838. color.pixel=XStandardPixel(map_info,&color);
  7839. *p++=color;
  7840. }
  7841. if ((visual_info->klass == DirectColor) &&
  7842. (colormap != XDefaultColormap(display,visual_info->screen)))
  7843. (void) XStoreColors(display,colormap,colors,(int) number_colors);
  7844. else
  7845. for (i=0; i < (ssize_t) number_colors; i++)
  7846. (void) XAllocColor(display,colormap,&colors[i]);
  7847. break;
  7848. }
  7849. }
  7850. if ((visual_info->klass != DirectColor) &&
  7851. (visual_info->klass != TrueColor))
  7852. {
  7853. /*
  7854. Set foreground, background, border, etc. pixels.
  7855. */
  7856. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7857. &pixel->foreground_color);
  7858. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7859. &pixel->background_color);
  7860. if (pixel->background_color.pixel == pixel->foreground_color.pixel)
  7861. {
  7862. /*
  7863. Foreground and background colors must differ.
  7864. */
  7865. pixel->background_color.red=(~pixel->foreground_color.red);
  7866. pixel->background_color.green=
  7867. (~pixel->foreground_color.green);
  7868. pixel->background_color.blue=
  7869. (~pixel->foreground_color.blue);
  7870. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7871. &pixel->background_color);
  7872. }
  7873. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7874. &pixel->border_color);
  7875. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7876. &pixel->matte_color);
  7877. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7878. &pixel->highlight_color);
  7879. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7880. &pixel->shadow_color);
  7881. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7882. &pixel->depth_color);
  7883. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7884. &pixel->trough_color);
  7885. for (i=0; i < MaxNumberPens; i++)
  7886. {
  7887. XBestPixel(display,colormap,colors,(unsigned int) number_colors,
  7888. &pixel->pen_colors[i]);
  7889. pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
  7890. }
  7891. pixel->colors=(ssize_t) (image->colors+MaxNumberPens);
  7892. }
  7893. colors=(XColor *) RelinquishMagickMemory(colors);
  7894. if (IsEventLogging())
  7895. {
  7896. (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
  7897. (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
  7898. map_info->colormap);
  7899. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7900. " red, green, blue max: %lu %lu %lu",map_info->red_max,
  7901. map_info->green_max,map_info->blue_max);
  7902. (void) LogMagickEvent(X11Event,GetMagickModule(),
  7903. " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
  7904. map_info->green_mult,map_info->blue_mult);
  7905. }
  7906. }
  7907. /*
  7908. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7909. % %
  7910. % %
  7911. % %
  7912. % X M a k e W i n d o w %
  7913. % %
  7914. % %
  7915. % %
  7916. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7917. %
  7918. % XMakeWindow() creates an X11 window.
  7919. %
  7920. % The format of the XMakeWindow method is:
  7921. %
  7922. % void XMakeWindow(Display *display,Window parent,char **argv,int argc,
  7923. % XClassHint *class_hint,XWMHints *manager_hints,
  7924. % XWindowInfo *window_info)
  7925. %
  7926. % A description of each parameter follows:
  7927. %
  7928. % o display: Specifies a connection to an X server; returned from
  7929. % XOpenDisplay.
  7930. %
  7931. % o parent: Specifies the parent window_info.
  7932. %
  7933. % o argv: Specifies the application's argument list.
  7934. %
  7935. % o argc: Specifies the number of arguments.
  7936. %
  7937. % o class_hint: Specifies a pointer to a X11 XClassHint structure.
  7938. %
  7939. % o manager_hints: Specifies a pointer to a X11 XWMHints structure.
  7940. %
  7941. % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
  7942. %
  7943. */
  7944. MagickPrivate void XMakeWindow(Display *display,Window parent,char **argv,
  7945. int argc,XClassHint *class_hint,XWMHints *manager_hints,
  7946. XWindowInfo *window_info)
  7947. {
  7948. #define MinWindowSize 64
  7949. Atom
  7950. atom_list[2];
  7951. int
  7952. gravity;
  7953. static XTextProperty
  7954. icon_name,
  7955. window_name;
  7956. Status
  7957. status;
  7958. XSizeHints
  7959. *size_hints;
  7960. /*
  7961. Set window info hints.
  7962. */
  7963. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  7964. assert(display != (Display *) NULL);
  7965. assert(window_info != (XWindowInfo *) NULL);
  7966. size_hints=XAllocSizeHints();
  7967. if (size_hints == (XSizeHints *) NULL)
  7968. ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]);
  7969. size_hints->flags=(int) window_info->flags;
  7970. size_hints->x=window_info->x;
  7971. size_hints->y=window_info->y;
  7972. size_hints->width=(int) window_info->width;
  7973. size_hints->height=(int) window_info->height;
  7974. if (window_info->immutable != MagickFalse)
  7975. {
  7976. /*
  7977. Window size cannot be changed.
  7978. */
  7979. size_hints->min_width=size_hints->width;
  7980. size_hints->min_height=size_hints->height;
  7981. size_hints->max_width=size_hints->width;
  7982. size_hints->max_height=size_hints->height;
  7983. size_hints->flags|=PMinSize;
  7984. size_hints->flags|=PMaxSize;
  7985. }
  7986. else
  7987. {
  7988. /*
  7989. Window size can be changed.
  7990. */
  7991. size_hints->min_width=(int) window_info->min_width;
  7992. size_hints->min_height=(int) window_info->min_height;
  7993. size_hints->flags|=PResizeInc;
  7994. size_hints->width_inc=(int) window_info->width_inc;
  7995. size_hints->height_inc=(int) window_info->height_inc;
  7996. #if !defined(PRE_R4_ICCCM)
  7997. size_hints->flags|=PBaseSize;
  7998. size_hints->base_width=size_hints->width_inc;
  7999. size_hints->base_height=size_hints->height_inc;
  8000. #endif
  8001. }
  8002. gravity=NorthWestGravity;
  8003. if (window_info->geometry != (char *) NULL)
  8004. {
  8005. char
  8006. default_geometry[MagickPathExtent],
  8007. geometry[MagickPathExtent];
  8008. int
  8009. flags;
  8010. register char
  8011. *p;
  8012. /*
  8013. User specified geometry.
  8014. */
  8015. (void) FormatLocaleString(default_geometry,MagickPathExtent,"%dx%d",
  8016. size_hints->width,size_hints->height);
  8017. (void) CopyMagickString(geometry,window_info->geometry,MagickPathExtent);
  8018. p=geometry;
  8019. while (strlen(p) != 0)
  8020. {
  8021. if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%'))
  8022. p++;
  8023. else
  8024. (void) memmove(p,p+1,MagickPathExtent-(p-geometry));
  8025. }
  8026. flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
  8027. window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
  8028. &size_hints->width,&size_hints->height,&gravity);
  8029. if ((flags & WidthValue) && (flags & HeightValue))
  8030. size_hints->flags|=USSize;
  8031. if ((flags & XValue) && (flags & YValue))
  8032. {
  8033. size_hints->flags|=USPosition;
  8034. window_info->x=size_hints->x;
  8035. window_info->y=size_hints->y;
  8036. }
  8037. }
  8038. #if !defined(PRE_R4_ICCCM)
  8039. size_hints->win_gravity=gravity;
  8040. size_hints->flags|=PWinGravity;
  8041. #endif
  8042. if (window_info->id == (Window) NULL)
  8043. window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
  8044. (unsigned int) size_hints->width,(unsigned int) size_hints->height,
  8045. window_info->border_width,(int) window_info->depth,InputOutput,
  8046. window_info->visual,(unsigned long) window_info->mask,
  8047. &window_info->attributes);
  8048. else
  8049. {
  8050. MagickStatusType
  8051. mask;
  8052. XEvent
  8053. sans_event;
  8054. XWindowChanges
  8055. window_changes;
  8056. /*
  8057. Window already exists; change relevant attributes.
  8058. */
  8059. (void) XChangeWindowAttributes(display,window_info->id,(unsigned long)
  8060. window_info->mask,&window_info->attributes);
  8061. mask=ConfigureNotify;
  8062. while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ;
  8063. window_changes.x=window_info->x;
  8064. window_changes.y=window_info->y;
  8065. window_changes.width=(int) window_info->width;
  8066. window_changes.height=(int) window_info->height;
  8067. mask=(MagickStatusType) (CWWidth | CWHeight);
  8068. if (window_info->flags & USPosition)
  8069. mask|=CWX | CWY;
  8070. (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
  8071. mask,&window_changes);
  8072. }
  8073. if (window_info->id == (Window) NULL)
  8074. ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
  8075. window_info->name);
  8076. status=XStringListToTextProperty(&window_info->name,1,&window_name);
  8077. if (status == False)
  8078. ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
  8079. window_info->name);
  8080. status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
  8081. if (status == False)
  8082. ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
  8083. window_info->icon_name);
  8084. if (window_info->icon_geometry != (char *) NULL)
  8085. {
  8086. int
  8087. flags,
  8088. height,
  8089. width;
  8090. /*
  8091. User specified icon geometry.
  8092. */
  8093. size_hints->flags|=USPosition;
  8094. flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
  8095. (char *) NULL,0,size_hints,&manager_hints->icon_x,
  8096. &manager_hints->icon_y,&width,&height,&gravity);
  8097. if ((flags & XValue) && (flags & YValue))
  8098. manager_hints->flags|=IconPositionHint;
  8099. }
  8100. XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
  8101. size_hints,manager_hints,class_hint);
  8102. if (window_name.value != (void *) NULL)
  8103. {
  8104. (void) XFree((void *) window_name.value);
  8105. window_name.value=(unsigned char *) NULL;
  8106. window_name.nitems=0;
  8107. }
  8108. if (icon_name.value != (void *) NULL)
  8109. {
  8110. (void) XFree((void *) icon_name.value);
  8111. icon_name.value=(unsigned char *) NULL;
  8112. icon_name.nitems=0;
  8113. }
  8114. atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
  8115. atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
  8116. (void) XSetWMProtocols(display,window_info->id,atom_list,2);
  8117. (void) XFree((void *) size_hints);
  8118. if (window_info->shape != MagickFalse)
  8119. {
  8120. #if defined(MAGICKCORE_HAVE_SHAPE)
  8121. int
  8122. error_base,
  8123. event_base;
  8124. /*
  8125. Can we apply a non-rectangular shaping mask?
  8126. */
  8127. error_base=0;
  8128. event_base=0;
  8129. if (XShapeQueryExtension(display,&error_base,&event_base) == 0)
  8130. window_info->shape=MagickFalse;
  8131. #else
  8132. window_info->shape=MagickFalse;
  8133. #endif
  8134. }
  8135. window_info->shape=MagickFalse; /* Fedora 30 has a broken shape extention */
  8136. if (window_info->shared_memory != MagickFalse)
  8137. {
  8138. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  8139. /*
  8140. Can we use shared memory with this window?
  8141. */
  8142. if (XShmQueryExtension(display) == 0)
  8143. window_info->shared_memory=MagickFalse;
  8144. #else
  8145. window_info->shared_memory=MagickFalse;
  8146. #endif
  8147. }
  8148. window_info->image=NewImageList();
  8149. window_info->destroy=MagickFalse;
  8150. }
  8151. /*
  8152. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8153. % %
  8154. % %
  8155. % %
  8156. % X M a g i c k P r o g r e s s M o n i t o r %
  8157. % %
  8158. % %
  8159. % %
  8160. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8161. %
  8162. % XMagickProgressMonitor() displays the progress a task is making in
  8163. % completing a task.
  8164. %
  8165. % The format of the XMagickProgressMonitor method is:
  8166. %
  8167. % void XMagickProgressMonitor(const char *task,
  8168. % const MagickOffsetType quantum,const MagickSizeType span,
  8169. % void *client_data)
  8170. %
  8171. % A description of each parameter follows:
  8172. %
  8173. % o task: Identifies the task in progress.
  8174. %
  8175. % o quantum: Specifies the quantum position within the span which represents
  8176. % how much progress has been made in completing a task.
  8177. %
  8178. % o span: Specifies the span relative to completing a task.
  8179. %
  8180. % o client_data: Pointer to any client data.
  8181. %
  8182. */
  8183. static const char *GetLocaleMonitorMessage(const char *text)
  8184. {
  8185. char
  8186. message[MagickPathExtent],
  8187. tag[MagickPathExtent];
  8188. const char
  8189. *locale_message;
  8190. register char
  8191. *p;
  8192. (void) CopyMagickString(tag,text,MagickPathExtent);
  8193. p=strrchr(tag,'/');
  8194. if (p != (char *) NULL)
  8195. *p='\0';
  8196. (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
  8197. locale_message=GetLocaleMessage(message);
  8198. if (locale_message == message)
  8199. return(text);
  8200. return(locale_message);
  8201. }
  8202. MagickPrivate MagickBooleanType XMagickProgressMonitor(const char *tag,
  8203. const MagickOffsetType quantum,const MagickSizeType span,
  8204. void *magick_unused(client_data))
  8205. {
  8206. XWindows
  8207. *windows;
  8208. windows=XSetWindows((XWindows *) ~0);
  8209. if (windows == (XWindows *) NULL)
  8210. return(MagickTrue);
  8211. if (windows->info.mapped != MagickFalse)
  8212. XProgressMonitorWidget(windows->display,windows,
  8213. GetLocaleMonitorMessage(tag),quantum,span);
  8214. return(MagickTrue);
  8215. }
  8216. /*
  8217. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8218. % %
  8219. % %
  8220. % %
  8221. % X Q u e r y C o l o r D a t a b a s e %
  8222. % %
  8223. % %
  8224. % %
  8225. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8226. %
  8227. % XQueryColorCompliance() looks up a RGB values for a color given in the target
  8228. % string.
  8229. %
  8230. % The format of the XQueryColorDatabase method is:
  8231. %
  8232. % MagickBooleanType XQueryColorCompliance(const char *target,XColor *color)
  8233. %
  8234. % A description of each parameter follows:
  8235. %
  8236. % o target: Specifies the color to lookup in the X color database.
  8237. %
  8238. % o color: A pointer to an PixelInfo structure. The RGB value of the target
  8239. % color is returned as this value.
  8240. %
  8241. */
  8242. MagickPrivate MagickBooleanType XQueryColorCompliance(const char *target,
  8243. XColor *color)
  8244. {
  8245. Colormap
  8246. colormap;
  8247. static Display
  8248. *display = (Display *) NULL;
  8249. Status
  8250. status;
  8251. XColor
  8252. xcolor;
  8253. /*
  8254. Initialize color return value.
  8255. */
  8256. assert(color != (XColor *) NULL);
  8257. color->red=0;
  8258. color->green=0;
  8259. color->blue=0;
  8260. color->flags=(char) (DoRed | DoGreen | DoBlue);
  8261. if ((target == (char *) NULL) || (*target == '\0'))
  8262. target="#ffffffffffff";
  8263. /*
  8264. Let the X server define the color for us.
  8265. */
  8266. if (display == (Display *) NULL)
  8267. display=XOpenDisplay((char *) NULL);
  8268. if (display == (Display *) NULL)
  8269. {
  8270. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target);
  8271. return(MagickFalse);
  8272. }
  8273. colormap=XDefaultColormap(display,XDefaultScreen(display));
  8274. status=XParseColor(display,colormap,(char *) target,&xcolor);
  8275. if (status == False)
  8276. ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target)
  8277. else
  8278. {
  8279. color->red=xcolor.red;
  8280. color->green=xcolor.green;
  8281. color->blue=xcolor.blue;
  8282. color->flags=xcolor.flags;
  8283. }
  8284. return(status != False ? MagickTrue : MagickFalse);
  8285. }
  8286. /*
  8287. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8288. % %
  8289. % %
  8290. % %
  8291. % X Q u e r y P o s i t i o n %
  8292. % %
  8293. % %
  8294. % %
  8295. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8296. %
  8297. % XQueryPosition() gets the pointer coordinates relative to a window.
  8298. %
  8299. % The format of the XQueryPosition method is:
  8300. %
  8301. % void XQueryPosition(Display *display,const Window window,int *x,int *y)
  8302. %
  8303. % A description of each parameter follows:
  8304. %
  8305. % o display: Specifies a connection to an X server; returned from
  8306. % XOpenDisplay.
  8307. %
  8308. % o window: Specifies a pointer to a Window.
  8309. %
  8310. % o x: Return the x coordinate of the pointer relative to the origin of the
  8311. % window.
  8312. %
  8313. % o y: Return the y coordinate of the pointer relative to the origin of the
  8314. % window.
  8315. %
  8316. */
  8317. MagickPrivate void XQueryPosition(Display *display,const Window window,int *x,
  8318. int *y)
  8319. {
  8320. int
  8321. x_root,
  8322. y_root;
  8323. unsigned int
  8324. mask;
  8325. Window
  8326. root_window;
  8327. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  8328. assert(display != (Display *) NULL);
  8329. assert(window != (Window) NULL);
  8330. assert(x != (int *) NULL);
  8331. assert(y != (int *) NULL);
  8332. (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
  8333. x,y,&mask);
  8334. }
  8335. /*
  8336. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8337. % %
  8338. % %
  8339. % %
  8340. % X R e f r e s h W i n d o w %
  8341. % %
  8342. % %
  8343. % %
  8344. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8345. %
  8346. % XRefreshWindow() refreshes an image in a X window.
  8347. %
  8348. % The format of the XRefreshWindow method is:
  8349. %
  8350. % void XRefreshWindow(Display *display,const XWindowInfo *window,
  8351. % const XEvent *event)
  8352. %
  8353. % A description of each parameter follows:
  8354. %
  8355. % o display: Specifies a connection to an X server; returned from
  8356. % XOpenDisplay.
  8357. %
  8358. % o window: Specifies a pointer to a XWindowInfo structure.
  8359. %
  8360. % o event: Specifies a pointer to a XEvent structure. If it is NULL,
  8361. % the entire image is refreshed.
  8362. %
  8363. */
  8364. MagickPrivate void XRefreshWindow(Display *display,const XWindowInfo *window,
  8365. const XEvent *event)
  8366. {
  8367. int
  8368. x,
  8369. y;
  8370. unsigned int
  8371. height,
  8372. width;
  8373. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  8374. assert(display != (Display *) NULL);
  8375. assert(window != (XWindowInfo *) NULL);
  8376. if (window->ximage == (XImage *) NULL)
  8377. return;
  8378. if (event != (XEvent *) NULL)
  8379. {
  8380. /*
  8381. Determine geometry from expose event.
  8382. */
  8383. x=event->xexpose.x;
  8384. y=event->xexpose.y;
  8385. width=(unsigned int) event->xexpose.width;
  8386. height=(unsigned int) event->xexpose.height;
  8387. }
  8388. else
  8389. {
  8390. XEvent
  8391. sans_event;
  8392. /*
  8393. Refresh entire window; discard outstanding expose events.
  8394. */
  8395. x=0;
  8396. y=0;
  8397. width=window->width;
  8398. height=window->height;
  8399. while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ;
  8400. if (window->matte_pixmap != (Pixmap) NULL)
  8401. {
  8402. #if defined(MAGICKCORE_HAVE_SHAPE)
  8403. if (window->shape != MagickFalse)
  8404. XShapeCombineMask(display,window->id,ShapeBounding,0,0,
  8405. window->matte_pixmap,ShapeSet);
  8406. #endif
  8407. }
  8408. }
  8409. /*
  8410. Check boundary conditions.
  8411. */
  8412. if ((window->ximage->width-(x+window->x)) < (int) width)
  8413. width=(unsigned int) (window->ximage->width-(x+window->x));
  8414. if ((window->ximage->height-(y+window->y)) < (int) height)
  8415. height=(unsigned int) (window->ximage->height-(y+window->y));
  8416. /*
  8417. Refresh image.
  8418. */
  8419. if (window->matte_pixmap != (Pixmap) NULL)
  8420. (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
  8421. if (window->pixmap != (Pixmap) NULL)
  8422. {
  8423. if (window->depth > 1)
  8424. (void) XCopyArea(display,window->pixmap,window->id,
  8425. window->annotate_context,x+window->x,y+window->y,width,height,x,y);
  8426. else
  8427. (void) XCopyPlane(display,window->pixmap,window->id,
  8428. window->highlight_context,x+window->x,y+window->y,width,height,x,y,
  8429. 1L);
  8430. }
  8431. else
  8432. {
  8433. #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
  8434. if (window->shared_memory)
  8435. (void) XShmPutImage(display,window->id,window->annotate_context,
  8436. window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue);
  8437. #endif
  8438. if (window->shared_memory == MagickFalse)
  8439. (void) XPutImage(display,window->id,window->annotate_context,
  8440. window->ximage,x+window->x,y+window->y,x,y,width,height);
  8441. }
  8442. if (window->matte_pixmap != (Pixmap) NULL)
  8443. (void) XSetClipMask(display,window->annotate_context,None);
  8444. (void) XFlush(display);
  8445. }
  8446. /*
  8447. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8448. % %
  8449. % %
  8450. % %
  8451. % X R e m o t e C o m m a n d %
  8452. % %
  8453. % %
  8454. % %
  8455. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8456. %
  8457. % XRemoteCommand() forces a remote display(1) to display the specified
  8458. % image filename.
  8459. %
  8460. % The format of the XRemoteCommand method is:
  8461. %
  8462. % MagickBooleanType XRemoteCommand(Display *display,const char *window,
  8463. % const char *filename)
  8464. %
  8465. % A description of each parameter follows:
  8466. %
  8467. % o display: Specifies a connection to an X server; returned from
  8468. % XOpenDisplay.
  8469. %
  8470. % o window: Specifies the name or id of an X window.
  8471. %
  8472. % o filename: the name of the image filename to display.
  8473. %
  8474. */
  8475. MagickExport MagickBooleanType XRemoteCommand(Display *display,
  8476. const char *window,const char *filename)
  8477. {
  8478. Atom
  8479. remote_atom;
  8480. Window
  8481. remote_window,
  8482. root_window;
  8483. assert(filename != (char *) NULL);
  8484. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
  8485. if (display == (Display *) NULL)
  8486. display=XOpenDisplay((char *) NULL);
  8487. if (display == (Display *) NULL)
  8488. {
  8489. ThrowXWindowException(XServerError,"UnableToOpenXServer",filename);
  8490. return(MagickFalse);
  8491. }
  8492. remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
  8493. remote_window=(Window) NULL;
  8494. root_window=XRootWindow(display,XDefaultScreen(display));
  8495. if (window != (char *) NULL)
  8496. {
  8497. /*
  8498. Search window hierarchy and identify any clients by name or ID.
  8499. */
  8500. if (isdigit((int) ((unsigned char) *window)) != 0)
  8501. remote_window=XWindowByID(display,root_window,(Window)
  8502. strtol((char *) window,(char **) NULL,0));
  8503. if (remote_window == (Window) NULL)
  8504. remote_window=XWindowByName(display,root_window,window);
  8505. }
  8506. if (remote_window == (Window) NULL)
  8507. remote_window=XWindowByProperty(display,root_window,remote_atom);
  8508. if (remote_window == (Window) NULL)
  8509. {
  8510. ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay",
  8511. filename);
  8512. return(MagickFalse);
  8513. }
  8514. /*
  8515. Send remote command.
  8516. */
  8517. remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
  8518. (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
  8519. PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
  8520. (void) XSync(display,MagickFalse);
  8521. return(MagickTrue);
  8522. }
  8523. /*
  8524. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8525. % %
  8526. % %
  8527. % %
  8528. % X R e n d e r I m a g e %
  8529. % %
  8530. % %
  8531. % %
  8532. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8533. %
  8534. % XRenderImage() renders text on the image with an X11 font. It also returns
  8535. % the bounding box of the text relative to the image.
  8536. %
  8537. % The format of the XRenderImage method is:
  8538. %
  8539. % MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
  8540. % const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
  8541. %
  8542. % A description of each parameter follows:
  8543. %
  8544. % o image: the image.
  8545. %
  8546. % o draw_info: the draw info.
  8547. %
  8548. % o offset: (x,y) location of text relative to image.
  8549. %
  8550. % o metrics: bounding box of text.
  8551. %
  8552. % o exception: return any errors or warnings in this structure.
  8553. %
  8554. */
  8555. MagickPrivate MagickBooleanType XRenderImage(Image *image,
  8556. const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics,
  8557. ExceptionInfo *exception)
  8558. {
  8559. const char
  8560. *client_name;
  8561. DrawInfo
  8562. cache_info;
  8563. Display
  8564. *display;
  8565. ImageInfo
  8566. *image_info;
  8567. MagickBooleanType
  8568. status;
  8569. size_t
  8570. height,
  8571. width;
  8572. XAnnotateInfo
  8573. annotate_info;
  8574. XFontStruct
  8575. *font_info;
  8576. XPixelInfo
  8577. pixel;
  8578. XResourceInfo
  8579. resource_info;
  8580. XrmDatabase
  8581. resource_database;
  8582. XStandardColormap
  8583. *map_info;
  8584. XVisualInfo
  8585. *visual_info;
  8586. /*
  8587. Open X server connection.
  8588. */
  8589. display=XOpenDisplay(draw_info->server_name);
  8590. if (display == (Display *) NULL)
  8591. {
  8592. ThrowXWindowException(XServerError,"UnableToOpenXServer",
  8593. draw_info->server_name);
  8594. return(MagickFalse);
  8595. }
  8596. /*
  8597. Get user defaults from X resource database.
  8598. */
  8599. (void) XSetErrorHandler(XError);
  8600. image_info=AcquireImageInfo();
  8601. client_name=GetClientName();
  8602. resource_database=XGetResourceDatabase(display,client_name);
  8603. XGetResourceInfo(image_info,resource_database,client_name,&resource_info);
  8604. resource_info.close_server=MagickFalse;
  8605. resource_info.colormap=PrivateColormap;
  8606. resource_info.font=AcquireString(draw_info->font);
  8607. resource_info.background_color=AcquireString("#ffffffffffff");
  8608. resource_info.foreground_color=AcquireString("#000000000000");
  8609. map_info=XAllocStandardColormap();
  8610. visual_info=(XVisualInfo *) NULL;
  8611. font_info=(XFontStruct *) NULL;
  8612. pixel.pixels=(unsigned long *) NULL;
  8613. if (map_info == (XStandardColormap *) NULL)
  8614. {
  8615. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
  8616. image->filename);
  8617. return(MagickFalse);
  8618. }
  8619. /*
  8620. Initialize visual info.
  8621. */
  8622. visual_info=XBestVisualInfo(display,map_info,&resource_info);
  8623. if (visual_info == (XVisualInfo *) NULL)
  8624. {
  8625. XFreeResources(display,visual_info,map_info,&pixel,font_info,
  8626. &resource_info,(XWindowInfo *) NULL);
  8627. ThrowXWindowException(XServerError,"UnableToGetVisual",image->filename);
  8628. return(MagickFalse);
  8629. }
  8630. map_info->colormap=(Colormap) NULL;
  8631. /*
  8632. Initialize Standard Colormap info.
  8633. */
  8634. XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
  8635. map_info);
  8636. XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL,
  8637. &pixel);
  8638. pixel.annotate_context=XDefaultGC(display,visual_info->screen);
  8639. /*
  8640. Initialize font info.
  8641. */
  8642. font_info=XBestFont(display,&resource_info,MagickFalse);
  8643. if (font_info == (XFontStruct *) NULL)
  8644. {
  8645. XFreeResources(display,visual_info,map_info,&pixel,font_info,
  8646. &resource_info,(XWindowInfo *) NULL);
  8647. ThrowXWindowException(XServerError,"UnableToLoadFont",draw_info->font);
  8648. return(MagickFalse);
  8649. }
  8650. cache_info=(*draw_info);
  8651. /*
  8652. Initialize annotate info.
  8653. */
  8654. XGetAnnotateInfo(&annotate_info);
  8655. annotate_info.stencil=ForegroundStencil;
  8656. if (cache_info.font != draw_info->font)
  8657. {
  8658. /*
  8659. Type name has changed.
  8660. */
  8661. (void) XFreeFont(display,font_info);
  8662. (void) CloneString(&resource_info.font,draw_info->font);
  8663. font_info=XBestFont(display,&resource_info,MagickFalse);
  8664. if (font_info == (XFontStruct *) NULL)
  8665. {
  8666. ThrowXWindowException(XServerError,"UnableToLoadFont",
  8667. draw_info->font);
  8668. return(MagickFalse);
  8669. }
  8670. }
  8671. if (image->debug != MagickFalse)
  8672. (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
  8673. "Font %s; pointsize %g",draw_info->font != (char *) NULL ?
  8674. draw_info->font : "none",draw_info->pointsize);
  8675. cache_info=(*draw_info);
  8676. annotate_info.font_info=font_info;
  8677. annotate_info.text=(char *) draw_info->text;
  8678. annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text,(int)
  8679. strlen(draw_info->text));
  8680. annotate_info.height=(unsigned int) font_info->ascent+font_info->descent;
  8681. metrics->pixels_per_em.x=(double) font_info->max_bounds.width;
  8682. metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent;
  8683. metrics->ascent=(double) font_info->ascent+4;
  8684. metrics->descent=(double) (-font_info->descent);
  8685. metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine);
  8686. metrics->height=(double) font_info->ascent+font_info->descent;
  8687. metrics->max_advance=(double) font_info->max_bounds.width;
  8688. metrics->bounds.x1=0.0;
  8689. metrics->bounds.y1=metrics->descent;
  8690. metrics->bounds.x2=metrics->ascent+metrics->descent;
  8691. metrics->bounds.y2=metrics->ascent+metrics->descent;
  8692. metrics->underline_position=(-2.0);
  8693. metrics->underline_thickness=1.0;
  8694. if (draw_info->render == MagickFalse)
  8695. return(MagickTrue);
  8696. if (draw_info->fill.alpha == TransparentAlpha)
  8697. return(MagickTrue);
  8698. /*
  8699. Render fill color.
  8700. */
  8701. width=annotate_info.width;
  8702. height=annotate_info.height;
  8703. if ((fabs(draw_info->affine.rx) >= MagickEpsilon) ||
  8704. (fabs(draw_info->affine.ry) >= MagickEpsilon))
  8705. {
  8706. if ((fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) &&
  8707. (fabs(draw_info->affine.rx+draw_info->affine.ry) < MagickEpsilon))
  8708. annotate_info.degrees=(double) (180.0/MagickPI)*
  8709. atan2(draw_info->affine.rx,draw_info->affine.sx);
  8710. }
  8711. (void) FormatLocaleString(annotate_info.geometry,MagickPathExtent,
  8712. "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height,
  8713. ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+
  8714. draw_info->interline_spacing-0.5));
  8715. pixel.pen_color.red=ScaleQuantumToShort(
  8716. ClampToQuantum(draw_info->fill.red));
  8717. pixel.pen_color.green=ScaleQuantumToShort(
  8718. ClampToQuantum(draw_info->fill.green));
  8719. pixel.pen_color.blue=ScaleQuantumToShort(
  8720. ClampToQuantum(draw_info->fill.blue));
  8721. status=XAnnotateImage(display,&pixel,&annotate_info,image,exception);
  8722. if (status == 0)
  8723. {
  8724. ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
  8725. image->filename);
  8726. return(MagickFalse);
  8727. }
  8728. return(MagickTrue);
  8729. }
  8730. /*
  8731. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8732. % %
  8733. % %
  8734. % %
  8735. % X R e t a i n W i n d o w C o l o r s %
  8736. % %
  8737. % %
  8738. % %
  8739. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8740. %
  8741. % XRetainWindowColors() sets X11 color resources on a window. This preserves
  8742. % the colors associated with an image displayed on the window.
  8743. %
  8744. % The format of the XRetainWindowColors method is:
  8745. %
  8746. % void XRetainWindowColors(Display *display,const Window window)
  8747. %
  8748. % A description of each parameter follows:
  8749. %
  8750. % o display: Specifies a connection to an X server; returned from
  8751. % XOpenDisplay.
  8752. %
  8753. % o window: Specifies a pointer to a XWindowInfo structure.
  8754. %
  8755. */
  8756. MagickExport void XRetainWindowColors(Display *display,const Window window)
  8757. {
  8758. Atom
  8759. property;
  8760. Pixmap
  8761. pixmap;
  8762. /*
  8763. Put property on the window.
  8764. */
  8765. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  8766. assert(display != (Display *) NULL);
  8767. assert(window != (Window) NULL);
  8768. property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
  8769. if (property == (Atom) NULL)
  8770. {
  8771. ThrowXWindowException(XServerError,"UnableToCreateProperty",
  8772. "_XSETROOT_ID");
  8773. return;
  8774. }
  8775. pixmap=XCreatePixmap(display,window,1,1,1);
  8776. if (pixmap == (Pixmap) NULL)
  8777. {
  8778. ThrowXWindowException(XServerError,"UnableToCreateBitmap","");
  8779. return;
  8780. }
  8781. (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
  8782. (unsigned char *) &pixmap,1);
  8783. (void) XSetCloseDownMode(display,RetainPermanent);
  8784. }
  8785. /*
  8786. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8787. % %
  8788. % %
  8789. % %
  8790. % X S e l e c t W i n d o w %
  8791. % %
  8792. % %
  8793. % %
  8794. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8795. %
  8796. % XSelectWindow() allows a user to select a window using the mouse. If the
  8797. % mouse moves, a cropping rectangle is drawn and the extents of the rectangle
  8798. % is returned in the crop_info structure.
  8799. %
  8800. % The format of the XSelectWindow function is:
  8801. %
  8802. % target_window=XSelectWindow(display,crop_info)
  8803. %
  8804. % A description of each parameter follows:
  8805. %
  8806. % o window: XSelectWindow returns the window id.
  8807. %
  8808. % o display: Specifies a pointer to the Display structure; returned from
  8809. % XOpenDisplay.
  8810. %
  8811. % o crop_info: Specifies a pointer to a RectangleInfo structure. It
  8812. % contains the extents of any cropping rectangle.
  8813. %
  8814. */
  8815. static Window XSelectWindow(Display *display,RectangleInfo *crop_info)
  8816. {
  8817. #define MinimumCropArea (unsigned int) 9
  8818. Cursor
  8819. target_cursor;
  8820. GC
  8821. annotate_context;
  8822. int
  8823. presses,
  8824. x_offset,
  8825. y_offset;
  8826. Status
  8827. status;
  8828. Window
  8829. root_window,
  8830. target_window;
  8831. XEvent
  8832. event;
  8833. XGCValues
  8834. context_values;
  8835. /*
  8836. Initialize graphic context.
  8837. */
  8838. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  8839. assert(display != (Display *) NULL);
  8840. assert(crop_info != (RectangleInfo *) NULL);
  8841. root_window=XRootWindow(display,XDefaultScreen(display));
  8842. context_values.background=XBlackPixel(display,XDefaultScreen(display));
  8843. context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
  8844. context_values.function=GXinvert;
  8845. context_values.plane_mask=
  8846. context_values.background ^ context_values.foreground;
  8847. context_values.subwindow_mode=IncludeInferiors;
  8848. annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground |
  8849. GCForeground | GCFunction | GCSubwindowMode),&context_values);
  8850. if (annotate_context == (GC) NULL)
  8851. return(MagickFalse);
  8852. /*
  8853. Grab the pointer using target cursor.
  8854. */
  8855. target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display,
  8856. XDefaultScreen(display)),(char * ) "white",(char * ) "black");
  8857. status=XGrabPointer(display,root_window,MagickFalse,(unsigned int)
  8858. (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
  8859. GrabModeAsync,root_window,target_cursor,CurrentTime);
  8860. if (status != GrabSuccess)
  8861. {
  8862. ThrowXWindowException(XServerError,"UnableToGrabMouse","");
  8863. return((Window) NULL);
  8864. }
  8865. /*
  8866. Select a window.
  8867. */
  8868. crop_info->width=0;
  8869. crop_info->height=0;
  8870. presses=0;
  8871. target_window=(Window) NULL;
  8872. x_offset=0;
  8873. y_offset=0;
  8874. (void) XGrabServer(display);
  8875. do
  8876. {
  8877. if ((crop_info->width*crop_info->height) >= MinimumCropArea)
  8878. (void) XDrawRectangle(display,root_window,annotate_context,
  8879. (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
  8880. (unsigned int) crop_info->height-1);
  8881. /*
  8882. Allow another event.
  8883. */
  8884. (void) XAllowEvents(display,SyncPointer,CurrentTime);
  8885. (void) XWindowEvent(display,root_window,ButtonPressMask |
  8886. ButtonReleaseMask | ButtonMotionMask,&event);
  8887. if ((crop_info->width*crop_info->height) >= MinimumCropArea)
  8888. (void) XDrawRectangle(display,root_window,annotate_context,
  8889. (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
  8890. (unsigned int) crop_info->height-1);
  8891. switch (event.type)
  8892. {
  8893. case ButtonPress:
  8894. {
  8895. target_window=XGetSubwindow(display,event.xbutton.subwindow,
  8896. event.xbutton.x,event.xbutton.y);
  8897. if (target_window == (Window) NULL)
  8898. target_window=root_window;
  8899. x_offset=event.xbutton.x_root;
  8900. y_offset=event.xbutton.y_root;
  8901. crop_info->x=(ssize_t) x_offset;
  8902. crop_info->y=(ssize_t) y_offset;
  8903. crop_info->width=0;
  8904. crop_info->height=0;
  8905. presses++;
  8906. break;
  8907. }
  8908. case ButtonRelease:
  8909. {
  8910. presses--;
  8911. break;
  8912. }
  8913. case MotionNotify:
  8914. {
  8915. /*
  8916. Discard pending button motion events.
  8917. */
  8918. while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
  8919. crop_info->x=(ssize_t) event.xmotion.x;
  8920. crop_info->y=(ssize_t) event.xmotion.y;
  8921. /*
  8922. Check boundary conditions.
  8923. */
  8924. if ((int) crop_info->x < x_offset)
  8925. crop_info->width=(size_t) (x_offset-crop_info->x);
  8926. else
  8927. {
  8928. crop_info->width=(size_t) (crop_info->x-x_offset);
  8929. crop_info->x=(ssize_t) x_offset;
  8930. }
  8931. if ((int) crop_info->y < y_offset)
  8932. crop_info->height=(size_t) (y_offset-crop_info->y);
  8933. else
  8934. {
  8935. crop_info->height=(size_t) (crop_info->y-y_offset);
  8936. crop_info->y=(ssize_t) y_offset;
  8937. }
  8938. }
  8939. default:
  8940. break;
  8941. }
  8942. } while ((target_window == (Window) NULL) || (presses > 0));
  8943. (void) XUngrabServer(display);
  8944. (void) XUngrabPointer(display,CurrentTime);
  8945. (void) XFreeCursor(display,target_cursor);
  8946. (void) XFreeGC(display,annotate_context);
  8947. if ((crop_info->width*crop_info->height) < MinimumCropArea)
  8948. {
  8949. crop_info->width=0;
  8950. crop_info->height=0;
  8951. }
  8952. if ((crop_info->width != 0) && (crop_info->height != 0))
  8953. target_window=root_window;
  8954. return(target_window);
  8955. }
  8956. /*
  8957. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8958. % %
  8959. % %
  8960. % %
  8961. % X S e t C u r s o r S t a t e %
  8962. % %
  8963. % %
  8964. % %
  8965. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8966. %
  8967. % XSetCursorState() sets the cursor state to busy, otherwise the cursor are
  8968. % reset to their default.
  8969. %
  8970. % The format of the XXSetCursorState method is:
  8971. %
  8972. % XSetCursorState(display,windows,const MagickStatusType state)
  8973. %
  8974. % A description of each parameter follows:
  8975. %
  8976. % o display: Specifies a connection to an X server; returned from
  8977. % XOpenDisplay.
  8978. %
  8979. % o windows: Specifies a pointer to a XWindows structure.
  8980. %
  8981. % o state: An unsigned integer greater than 0 sets the cursor state
  8982. % to busy, otherwise the cursor are reset to their default.
  8983. %
  8984. */
  8985. MagickPrivate void XSetCursorState(Display *display,XWindows *windows,
  8986. const MagickStatusType state)
  8987. {
  8988. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  8989. assert(display != (Display *) NULL);
  8990. assert(windows != (XWindows *) NULL);
  8991. if (state)
  8992. {
  8993. (void) XCheckDefineCursor(display,windows->image.id,
  8994. windows->image.busy_cursor);
  8995. (void) XCheckDefineCursor(display,windows->pan.id,
  8996. windows->pan.busy_cursor);
  8997. (void) XCheckDefineCursor(display,windows->magnify.id,
  8998. windows->magnify.busy_cursor);
  8999. (void) XCheckDefineCursor(display,windows->command.id,
  9000. windows->command.busy_cursor);
  9001. }
  9002. else
  9003. {
  9004. (void) XCheckDefineCursor(display,windows->image.id,
  9005. windows->image.cursor);
  9006. (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
  9007. (void) XCheckDefineCursor(display,windows->magnify.id,
  9008. windows->magnify.cursor);
  9009. (void) XCheckDefineCursor(display,windows->command.id,
  9010. windows->command.cursor);
  9011. (void) XCheckDefineCursor(display,windows->command.id,
  9012. windows->widget.cursor);
  9013. (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  9014. }
  9015. windows->info.mapped=MagickFalse;
  9016. }
  9017. /*
  9018. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9019. % %
  9020. % %
  9021. % %
  9022. % X S e t W i n d o w s %
  9023. % %
  9024. % %
  9025. % %
  9026. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9027. %
  9028. % XSetWindows() sets the X windows structure if the windows info is specified.
  9029. % Otherwise the current windows structure is returned.
  9030. %
  9031. % The format of the XSetWindows method is:
  9032. %
  9033. % XWindows *XSetWindows(XWindows *windows_info)
  9034. %
  9035. % A description of each parameter follows:
  9036. %
  9037. % o windows_info: Initialize the Windows structure with this information.
  9038. %
  9039. */
  9040. MagickPrivate XWindows *XSetWindows(XWindows *windows_info)
  9041. {
  9042. static XWindows
  9043. *windows = (XWindows *) NULL;
  9044. if (windows_info != (XWindows *) ~0)
  9045. {
  9046. windows=(XWindows *) RelinquishMagickMemory(windows);
  9047. windows=windows_info;
  9048. }
  9049. return(windows);
  9050. }
  9051. /*
  9052. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9053. % %
  9054. % %
  9055. % %
  9056. % X U s e r P r e f e r e n c e s %
  9057. % %
  9058. % %
  9059. % %
  9060. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9061. %
  9062. % XUserPreferences() saves the preferences in a configuration file in the
  9063. % users' home directory.
  9064. %
  9065. % The format of the XUserPreferences method is:
  9066. %
  9067. % void XUserPreferences(XResourceInfo *resource_info)
  9068. %
  9069. % A description of each parameter follows:
  9070. %
  9071. % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  9072. %
  9073. */
  9074. MagickPrivate void XUserPreferences(XResourceInfo *resource_info)
  9075. {
  9076. #if defined(X11_PREFERENCES_PATH)
  9077. char
  9078. cache[MagickPathExtent],
  9079. filename[MagickPathExtent],
  9080. specifier[MagickPathExtent];
  9081. const char
  9082. *client_name,
  9083. *value;
  9084. XrmDatabase
  9085. preferences_database;
  9086. /*
  9087. Save user preferences to the client configuration file.
  9088. */
  9089. assert(resource_info != (XResourceInfo *) NULL);
  9090. client_name=GetClientName();
  9091. preferences_database=XrmGetStringDatabase("");
  9092. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.backdrop",client_name);
  9093. value=resource_info->backdrop ? "True" : "False";
  9094. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9095. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.colormap",client_name);
  9096. value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
  9097. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9098. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmExit",
  9099. client_name);
  9100. value=resource_info->confirm_exit ? "True" : "False";
  9101. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9102. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmEdit",
  9103. client_name);
  9104. value=resource_info->confirm_edit ? "True" : "False";
  9105. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9106. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.displayWarnings",
  9107. client_name);
  9108. value=resource_info->display_warnings ? "True" : "False";
  9109. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9110. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.dither",client_name);
  9111. value=resource_info->quantize_info->dither_method != NoDitherMethod ?
  9112. "True" : "False";
  9113. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9114. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.gammaCorrect",
  9115. client_name);
  9116. value=resource_info->gamma_correct ? "True" : "False";
  9117. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9118. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.undoCache",client_name);
  9119. (void) FormatLocaleString(cache,MagickPathExtent,"%.20g",(double)
  9120. resource_info->undo_cache);
  9121. XrmPutStringResource(&preferences_database,specifier,cache);
  9122. (void) FormatLocaleString(specifier,MagickPathExtent,"%s.usePixmap",client_name);
  9123. value=resource_info->use_pixmap ? "True" : "False";
  9124. XrmPutStringResource(&preferences_database,specifier,(char *) value);
  9125. (void) FormatLocaleString(filename,MagickPathExtent,"%s%src",
  9126. X11_PREFERENCES_PATH,client_name);
  9127. ExpandFilename(filename);
  9128. XrmPutFileDatabase(preferences_database,filename);
  9129. #endif
  9130. }
  9131. /*
  9132. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9133. % %
  9134. % %
  9135. % %
  9136. % X V i s u a l C l a s s N a m e %
  9137. % %
  9138. % %
  9139. % %
  9140. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9141. %
  9142. % XVisualClassName() returns the visual class name as a character string.
  9143. %
  9144. % The format of the XVisualClassName method is:
  9145. %
  9146. % char *XVisualClassName(const int visual_class)
  9147. %
  9148. % A description of each parameter follows:
  9149. %
  9150. % o visual_type: XVisualClassName returns the visual class as a character
  9151. % string.
  9152. %
  9153. % o class: Specifies the visual class.
  9154. %
  9155. */
  9156. static const char *XVisualClassName(const int visual_class)
  9157. {
  9158. switch (visual_class)
  9159. {
  9160. case StaticGray: return("StaticGray");
  9161. case GrayScale: return("GrayScale");
  9162. case StaticColor: return("StaticColor");
  9163. case PseudoColor: return("PseudoColor");
  9164. case TrueColor: return("TrueColor");
  9165. case DirectColor: return("DirectColor");
  9166. }
  9167. return("unknown visual class");
  9168. }
  9169. /*
  9170. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9171. % %
  9172. % %
  9173. % %
  9174. % X W a r n i n g %
  9175. % %
  9176. % %
  9177. % %
  9178. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9179. %
  9180. % XWarning() displays a warning reason in a Notice widget.
  9181. %
  9182. % The format of the XWarning method is:
  9183. %
  9184. % void XWarning(const unsigned int warning,const char *reason,
  9185. % const char *description)
  9186. %
  9187. % A description of each parameter follows:
  9188. %
  9189. % o warning: Specifies the numeric warning category.
  9190. %
  9191. % o reason: Specifies the reason to display before terminating the
  9192. % program.
  9193. %
  9194. % o description: Specifies any description to the reason.
  9195. %
  9196. */
  9197. MagickPrivate void XWarning(const ExceptionType magick_unused(warning),
  9198. const char *reason,const char *description)
  9199. {
  9200. char
  9201. text[MagickPathExtent];
  9202. XWindows
  9203. *windows;
  9204. if (reason == (char *) NULL)
  9205. return;
  9206. (void) CopyMagickString(text,reason,MagickPathExtent);
  9207. (void) ConcatenateMagickString(text,":",MagickPathExtent);
  9208. windows=XSetWindows((XWindows *) ~0);
  9209. XNoticeWidget(windows->display,windows,text,(char *) description);
  9210. }
  9211. /*
  9212. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9213. % %
  9214. % %
  9215. % %
  9216. % X W i n d o w B y I D %
  9217. % %
  9218. % %
  9219. % %
  9220. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9221. %
  9222. % XWindowByID() locates a child window with a given ID. If not window with
  9223. % the given name is found, 0 is returned. Only the window specified and its
  9224. % subwindows are searched.
  9225. %
  9226. % The format of the XWindowByID function is:
  9227. %
  9228. % child=XWindowByID(display,window,id)
  9229. %
  9230. % A description of each parameter follows:
  9231. %
  9232. % o child: XWindowByID returns the window with the specified
  9233. % id. If no windows are found, XWindowByID returns 0.
  9234. %
  9235. % o display: Specifies a pointer to the Display structure; returned from
  9236. % XOpenDisplay.
  9237. %
  9238. % o id: Specifies the id of the window to locate.
  9239. %
  9240. */
  9241. MagickPrivate Window XWindowByID(Display *display,const Window root_window,
  9242. const size_t id)
  9243. {
  9244. RectangleInfo
  9245. rectangle_info;
  9246. register int
  9247. i;
  9248. Status
  9249. status;
  9250. unsigned int
  9251. number_children;
  9252. Window
  9253. child,
  9254. *children,
  9255. window;
  9256. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  9257. assert(display != (Display *) NULL);
  9258. assert(root_window != (Window) NULL);
  9259. if (id == 0)
  9260. return(XSelectWindow(display,&rectangle_info));
  9261. if (root_window == id)
  9262. return(root_window);
  9263. status=XQueryTree(display,root_window,&child,&child,&children,
  9264. &number_children);
  9265. if (status == False)
  9266. return((Window) NULL);
  9267. window=(Window) NULL;
  9268. for (i=0; i < (int) number_children; i++)
  9269. {
  9270. /*
  9271. Search each child and their children.
  9272. */
  9273. window=XWindowByID(display,children[i],id);
  9274. if (window != (Window) NULL)
  9275. break;
  9276. }
  9277. if (children != (Window *) NULL)
  9278. (void) XFree((void *) children);
  9279. return(window);
  9280. }
  9281. /*
  9282. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9283. % %
  9284. % %
  9285. % %
  9286. % X W i n d o w B y N a m e %
  9287. % %
  9288. % %
  9289. % %
  9290. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9291. %
  9292. % XWindowByName() locates a window with a given name on a display. If no
  9293. % window with the given name is found, 0 is returned. If more than one window
  9294. % has the given name, the first one is returned. Only root and its children
  9295. % are searched.
  9296. %
  9297. % The format of the XWindowByName function is:
  9298. %
  9299. % window=XWindowByName(display,root_window,name)
  9300. %
  9301. % A description of each parameter follows:
  9302. %
  9303. % o window: XWindowByName returns the window id.
  9304. %
  9305. % o display: Specifies a pointer to the Display structure; returned from
  9306. % XOpenDisplay.
  9307. %
  9308. % o root_window: Specifies the id of the root window.
  9309. %
  9310. % o name: Specifies the name of the window to locate.
  9311. %
  9312. */
  9313. MagickPrivate Window XWindowByName(Display *display,const Window root_window,
  9314. const char *name)
  9315. {
  9316. register int
  9317. i;
  9318. Status
  9319. status;
  9320. unsigned int
  9321. number_children;
  9322. Window
  9323. *children,
  9324. child,
  9325. window;
  9326. XTextProperty
  9327. window_name;
  9328. assert(display != (Display *) NULL);
  9329. assert(root_window != (Window) NULL);
  9330. assert(name != (char *) NULL);
  9331. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
  9332. if (XGetWMName(display,root_window,&window_name) != 0)
  9333. if (LocaleCompare((char *) window_name.value,name) == 0)
  9334. return(root_window);
  9335. status=XQueryTree(display,root_window,&child,&child,&children,
  9336. &number_children);
  9337. if (status == False)
  9338. return((Window) NULL);
  9339. window=(Window) NULL;
  9340. for (i=0; i < (int) number_children; i++)
  9341. {
  9342. /*
  9343. Search each child and their children.
  9344. */
  9345. window=XWindowByName(display,children[i],name);
  9346. if (window != (Window) NULL)
  9347. break;
  9348. }
  9349. if (children != (Window *) NULL)
  9350. (void) XFree((void *) children);
  9351. return(window);
  9352. }
  9353. /*
  9354. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9355. % %
  9356. % %
  9357. % %
  9358. % X W i n d o w B y P r o p e r y %
  9359. % %
  9360. % %
  9361. % %
  9362. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9363. %
  9364. % XWindowByProperty() locates a child window with a given property. If not
  9365. % window with the given name is found, 0 is returned. If more than one window
  9366. % has the given property, the first one is returned. Only the window
  9367. % specified and its subwindows are searched.
  9368. %
  9369. % The format of the XWindowByProperty function is:
  9370. %
  9371. % child=XWindowByProperty(display,window,property)
  9372. %
  9373. % A description of each parameter follows:
  9374. %
  9375. % o child: XWindowByProperty returns the window id with the specified
  9376. % property. If no windows are found, XWindowByProperty returns 0.
  9377. %
  9378. % o display: Specifies a pointer to the Display structure; returned from
  9379. % XOpenDisplay.
  9380. %
  9381. % o property: Specifies the property of the window to locate.
  9382. %
  9383. */
  9384. MagickPrivate Window XWindowByProperty(Display *display,const Window window,
  9385. const Atom property)
  9386. {
  9387. Atom
  9388. type;
  9389. int
  9390. format;
  9391. Status
  9392. status;
  9393. unsigned char
  9394. *data;
  9395. unsigned int
  9396. i,
  9397. number_children;
  9398. unsigned long
  9399. after,
  9400. number_items;
  9401. Window
  9402. child,
  9403. *children,
  9404. parent,
  9405. root;
  9406. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  9407. assert(display != (Display *) NULL);
  9408. assert(window != (Window) NULL);
  9409. assert(property != (Atom) NULL);
  9410. status=XQueryTree(display,window,&root,&parent,&children,&number_children);
  9411. if (status == False)
  9412. return((Window) NULL);
  9413. type=(Atom) NULL;
  9414. child=(Window) NULL;
  9415. for (i=0; (i < number_children) && (child == (Window) NULL); i++)
  9416. {
  9417. status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse,
  9418. (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
  9419. if (data != NULL)
  9420. (void) XFree((void *) data);
  9421. if ((status == Success) && (type != (Atom) NULL))
  9422. child=children[i];
  9423. }
  9424. for (i=0; (i < number_children) && (child == (Window) NULL); i++)
  9425. child=XWindowByProperty(display,children[i],property);
  9426. if (children != (Window *) NULL)
  9427. (void) XFree((void *) children);
  9428. return(child);
  9429. }
  9430. #else
  9431. /*
  9432. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9433. % %
  9434. % %
  9435. % %
  9436. % X I m p o r t I m a g e %
  9437. % %
  9438. % %
  9439. % %
  9440. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9441. %
  9442. % XImportImage() reads an image from an X window.
  9443. %
  9444. % The format of the XImportImage method is:
  9445. %
  9446. % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
  9447. % ExceptionInfo *exception)
  9448. %
  9449. % A description of each parameter follows:
  9450. %
  9451. % o image_info: the image info..
  9452. %
  9453. % o ximage_info: Specifies a pointer to an XImportInfo structure.
  9454. %
  9455. % o exception: return any errors or warnings in this structure.
  9456. %
  9457. */
  9458. MagickExport Image *XImportImage(const ImageInfo *image_info,
  9459. XImportInfo *ximage_info,ExceptionInfo *exception)
  9460. {
  9461. assert(image_info != (const ImageInfo *) NULL);
  9462. assert(image_info->signature == MagickCoreSignature);
  9463. if (image_info->debug != MagickFalse)
  9464. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
  9465. image_info->filename);
  9466. assert(ximage_info != (XImportInfo *) NULL);
  9467. assert(exception != (ExceptionInfo *) NULL);
  9468. assert(exception->signature == MagickCoreSignature);
  9469. (void) exception;
  9470. return((Image *) NULL);
  9471. }
  9472. /*
  9473. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9474. % %
  9475. % %
  9476. % %
  9477. % X R e n d e r X 1 1 %
  9478. % %
  9479. % %
  9480. % %
  9481. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9482. %
  9483. % XRenderImage() renders text on the image with an X11 font. It also returns
  9484. % the bounding box of the text relative to the image.
  9485. %
  9486. % The format of the XRenderImage method is:
  9487. %
  9488. % MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
  9489. % const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
  9490. %
  9491. % A description of each parameter follows:
  9492. %
  9493. % o image: the image.
  9494. %
  9495. % o draw_info: the draw info.
  9496. %
  9497. % o offset: (x,y) location of text relative to image.
  9498. %
  9499. % o metrics: bounding box of text.
  9500. %
  9501. % o exception: return any errors or warnings in this structure.
  9502. %
  9503. */
  9504. MagickPrivate MagickBooleanType XRenderImage(Image *image,
  9505. const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics,
  9506. ExceptionInfo *exception)
  9507. {
  9508. (void) draw_info;
  9509. (void) offset;
  9510. (void) metrics;
  9511. (void) ThrowMagickException(exception,GetMagickModule(),
  9512. MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","'%s' (X11)",
  9513. image->filename);
  9514. return(MagickFalse);
  9515. }
  9516. #endif
  9517. /*
  9518. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9519. % %
  9520. % %
  9521. % %
  9522. + X C o m p o n e n t G e n e s i s %
  9523. % %
  9524. % %
  9525. % %
  9526. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9527. %
  9528. % XComponentGenesis() instantiates the X component.
  9529. %
  9530. % The format of the XComponentGenesis method is:
  9531. %
  9532. % MagickBooleanType XComponentGenesis(void)
  9533. %
  9534. */
  9535. MagickPrivate MagickBooleanType XComponentGenesis(void)
  9536. {
  9537. return(MagickTrue);
  9538. }
  9539. /*
  9540. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9541. % %
  9542. % %
  9543. % %
  9544. % X G e t I m p o r t I n f o %
  9545. % %
  9546. % %
  9547. % %
  9548. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9549. %
  9550. % XGetImportInfo() initializes the XImportInfo structure.
  9551. %
  9552. % The format of the XGetImportInfo method is:
  9553. %
  9554. % void XGetImportInfo(XImportInfo *ximage_info)
  9555. %
  9556. % A description of each parameter follows:
  9557. %
  9558. % o ximage_info: Specifies a pointer to an ImageInfo structure.
  9559. %
  9560. */
  9561. MagickExport void XGetImportInfo(XImportInfo *ximage_info)
  9562. {
  9563. assert(ximage_info != (XImportInfo *) NULL);
  9564. ximage_info->frame=MagickFalse;
  9565. ximage_info->borders=MagickFalse;
  9566. ximage_info->screen=MagickFalse;
  9567. ximage_info->descend=MagickTrue;
  9568. ximage_info->silent=MagickFalse;
  9569. }