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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i067:  imagemagic - X11 image processing and display, Part11/38
  4. Message-ID: <1993Jul14.175535.1295@sparky.sterling.com>
  5. X-Md4-Signature: ba79a299c3643ad3a0469013e44bbe6c
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 17:55:35 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 67
  13. Archive-name: imagemagic/part11
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.11 (part 11 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/X.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 11; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/X.c'
  36. else
  37. echo 'x - continuing file ImageMagick/X.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/X.c' &&
  39. X                  {
  40. X                    pixel=XStandardPixel(map_info,(*p),8);
  41. X                    for (k=bytes_per_pixel-1; k >= 0; k--)
  42. X                    {
  43. X                      channel[k]=(unsigned char) pixel;
  44. X                      pixel>>=8;
  45. X                    }
  46. X                    for (j=0; j <= ((int) p->length); j++)
  47. X                    {
  48. X                      for (k=0; k < bytes_per_pixel; k++)
  49. X                        *q++=channel[k];
  50. X                      x++;
  51. X                      if (x == ximage->width)
  52. X                        {
  53. X                          x=0;
  54. X                          q+=scanline_pad;
  55. X                        }
  56. X                    }
  57. X                    p++;
  58. X                  }
  59. X                }
  60. X              break;
  61. X            }
  62. X          }
  63. X        }
  64. X    }
  65. }
  66. X
  67. /*
  68. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  69. %                                                                             %
  70. %                                                                             %
  71. %                                                                             %
  72. %   X M a k e I n v i s i b l e C u r s o r                                   %
  73. %                                                                             %
  74. %                                                                             %
  75. %                                                                             %
  76. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  77. %
  78. %  Function XMakeInvisibleCursor creates an invisible X11 cursor.
  79. %
  80. %  The format of the XMakeInvisibleCursor routine is:
  81. %
  82. %      XMakeInvisibleCursor(display,window)
  83. %
  84. %  A description of each parameter follows:
  85. %
  86. %    o display: Specifies a connection to an X server;  returned from
  87. %      XOpenDisplay.
  88. %
  89. %    o window: Specifies the ID of the window for which the cursor is
  90. %      assigned.
  91. %
  92. %
  93. */
  94. Cursor XMakeInvisibleCursor(display,window)
  95. Display
  96. X  *display;
  97. X
  98. Window
  99. X  window;
  100. {
  101. X  Cursor
  102. X    cursor;
  103. X
  104. X  Pixmap
  105. X    pixmap;
  106. X
  107. X  XColor
  108. X    color;
  109. X
  110. X  static char
  111. X    bits[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  112. X
  113. X  color.red=0;
  114. X  color.green=0;
  115. X  color.blue=0;
  116. X  pixmap=XCreateBitmapFromData(display,window,bits,8,8);
  117. X  cursor=XCreatePixmapCursor(display,pixmap,pixmap,&color,&color,0,0);
  118. X  XFreePixmap(display,pixmap);
  119. X  return(cursor);
  120. }
  121. X
  122. /*
  123. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  124. %                                                                             %
  125. %                                                                             %
  126. %                                                                             %
  127. %   X M a k e P i x m a p                                                     %
  128. %                                                                             %
  129. %                                                                             %
  130. %                                                                             %
  131. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  132. %
  133. %  Function XMakePixmap creates an X11 pixmap.
  134. %
  135. %  The format of the XMakePixmap routine is:
  136. %
  137. %      status=XMakePixmap(display,resource_info,window)
  138. %
  139. %  A description of each parameter follows:
  140. %
  141. %    o status: Function XMakePixmap returns True if the X pixmap is
  142. %      successfully created.  False is returned is there is a memory shortage.
  143. %
  144. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  145. %
  146. %    o display: Specifies a connection to an X server; returned from
  147. %      XOpenDisplay.
  148. %
  149. %    o window: Specifies a pointer to a XWindowInfo structure.
  150. %
  151. %
  152. */
  153. unsigned int XMakePixmap(display,resource_info,window)
  154. Display
  155. X  *display;
  156. X
  157. XXResourceInfo
  158. X  *resource_info;
  159. X
  160. XXWindowInfo
  161. X  *window;
  162. {
  163. X  if (window->ximage == (XImage *) NULL)
  164. X    return(False);
  165. X  /*
  166. X    Display busy cursor.
  167. X  */
  168. X  XDefineCursor(display,window->id,window->busy_cursor);
  169. X  XFlush(display);
  170. X  /*
  171. X    Create pixmap.
  172. X  */
  173. X  if (window->pixmap != (Pixmap) NULL)
  174. X    XFreePixmap(display,window->pixmap);
  175. X  window->pixmap=XCreatePixmap(display,window->id,(unsigned int)
  176. X    window->ximage->width,(unsigned int) window->ximage->height,window->depth);
  177. X  if (window->pixmap == (Pixmap) NULL)
  178. X    {
  179. X      /*
  180. X        Unable to allocate pixmap.
  181. X      */
  182. X      XDefineCursor(display,window->id,window->cursor);
  183. X      return(False);
  184. X    }
  185. X  /*
  186. X    Copy X image to pixmap.
  187. X  */
  188. X  XPutImage(display,window->pixmap,window->graphic_context,window->ximage,
  189. X    0,0,0,0,(unsigned int) window->ximage->width,
  190. X    (unsigned int) window->ximage->height);
  191. X  if (resource_info->debug)
  192. X    {
  193. X      (void) fprintf(stderr,"Pixmap:\n");
  194. X      (void) fprintf(stderr,"  width, height: %dx%d\n",window->ximage->width,
  195. X        window->ximage->height);
  196. X    }
  197. X  /*
  198. X    Restore cursor.
  199. X  */
  200. X  XDefineCursor(display,window->id,window->cursor);
  201. X  return(True);
  202. }
  203. X
  204. /*
  205. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  206. %                                                                             %
  207. %                                                                             %
  208. %                                                                             %
  209. %   X M a k e S t a n d a r d C o l o r m a p                                 %
  210. %                                                                             %
  211. %                                                                             %
  212. %                                                                             %
  213. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  214. %
  215. %  Function XMakeStandardColormap creates an X11 Standard Colormap.
  216. %
  217. %  The format of the XMakeStandardColormap routine is:
  218. %
  219. %      XMakeStandardColormap(display,visual_info,resource_info,pixel_info,
  220. %        image,map_info)
  221. %
  222. %  A description of each parameter follows:
  223. %
  224. %    o display: Specifies a connection to an X server; returned from
  225. %      XOpenDisplay.
  226. %
  227. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  228. %      returned from XGetVisualInfo.
  229. %
  230. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  231. %
  232. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  233. %
  234. %    o image: Specifies a pointer to a Image structure;  returned from
  235. %      ReadImage.
  236. %
  237. %    o map_info: If a Standard Colormap type is specified, this structure is
  238. %      initialized with info from the Standard Colormap.
  239. %
  240. %
  241. */
  242. static int IntensityCompare(x,y)
  243. const void
  244. X  *x,
  245. X  *y;
  246. {
  247. X  DiversityPacket
  248. X    *color_1,
  249. X    *color_2;
  250. X
  251. X  color_1=(DiversityPacket *) x;
  252. X  color_2=(DiversityPacket *) y;
  253. X  return((int) Intensity(*color_2)-(int) Intensity(*color_1));
  254. }
  255. X
  256. static int PopularityCompare(x,y)
  257. const void
  258. X  *x,
  259. X  *y;
  260. {
  261. X  DiversityPacket
  262. X    *color_1,
  263. X    *color_2;
  264. X
  265. X  color_1=(DiversityPacket *) x;
  266. X  color_2=(DiversityPacket *) y;
  267. X  return((int) color_2->count-(int) color_1->count);
  268. }
  269. X
  270. void XMakeStandardColormap(display,visual_info,resource_info,pixel_info,image,
  271. X  map_info)
  272. Display
  273. X  *display;
  274. X
  275. XXVisualInfo
  276. X  *visual_info;
  277. X
  278. XXResourceInfo
  279. X  *resource_info;
  280. X
  281. XXPixelInfo
  282. X  *pixel_info;
  283. X
  284. Image
  285. X  *image;
  286. X
  287. XXStandardColormap
  288. X  *map_info;
  289. {
  290. X  Colormap
  291. X    colormap;
  292. X
  293. X  int
  294. X    status;
  295. X
  296. X  register int
  297. X    i;
  298. X
  299. X  unsigned int
  300. X    gray_value,
  301. X    number_colors,
  302. X    retain_colors;
  303. X
  304. X  XColor
  305. X    color,
  306. X    *colors,
  307. X    *p;
  308. X
  309. X  if (resource_info->map_type != (char *) NULL)
  310. X    {
  311. X      /*
  312. X        Standard Colormap is already defined (i.e. xstdcmap).
  313. X      */
  314. X      if (pixel_info->pixels != (unsigned long *) NULL)
  315. X        (void) free((char *) pixel_info->pixels);
  316. X      XGetPixelInfo(display,visual_info,map_info,resource_info,image,
  317. X        pixel_info);
  318. X      return;
  319. X    }
  320. X  if ((visual_info->class != DirectColor) && (visual_info->class != TrueColor))
  321. X    if ((image->class == DirectClass) ||
  322. X        (image->colors > visual_info->colormap_size))
  323. X      {
  324. X        /*
  325. X          Image has more colors than the visual supports.
  326. X        */
  327. X        QuantizeImage(image,(unsigned int) visual_info->colormap_size,
  328. X          resource_info->tree_depth,resource_info->dither,
  329. X          resource_info->colorspace,False);
  330. X        image->class=DirectClass;  /* promote to DirectClass */
  331. X      }
  332. X  /*
  333. X    Free previous and create new colormap.
  334. X  */
  335. X  XFreeStandardColormap(display,visual_info,pixel_info,map_info);
  336. X  colormap=XDefaultColormap(display,visual_info->screen);
  337. X  if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  338. X    colormap=XCreateColormap(display,
  339. X      XRootWindow(display,visual_info->screen),visual_info->visual,
  340. X      visual_info->class == DirectColor ? AllocAll : AllocNone);
  341. X  if (colormap == (Colormap) NULL)
  342. X    Error("unable to create colormap",(char *) NULL);
  343. X  /*
  344. X    Initialize the Standard Colormap attributes.
  345. X  */
  346. X  map_info->colormap=colormap;
  347. X  map_info->red_max=visual_info->red_mask;
  348. X  map_info->red_mult=map_info->red_max > 0 ? 1 : 0;
  349. X  if (map_info->red_max > 0)
  350. X    while ((map_info->red_max & 0x01) == 0)
  351. X    {
  352. X      map_info->red_max>>=1;
  353. X      map_info->red_mult<<=1;
  354. X    }
  355. X  map_info->green_max=visual_info->green_mask;
  356. X  map_info->green_mult=map_info->green_max > 0 ? 1 : 0;
  357. X  if (map_info->green_max > 0)
  358. X    while ((map_info->green_max & 0x01) == 0)
  359. X    {
  360. X      map_info->green_max>>=1;
  361. X      map_info->green_mult<<=1;
  362. X    }
  363. X  map_info->blue_max=visual_info->blue_mask;
  364. X  map_info->blue_mult=map_info->blue_max > 0 ? 1 : 0;
  365. X  if (map_info->blue_max > 0)
  366. X    while ((map_info->blue_max & 0x01) == 0)
  367. X    {
  368. X      map_info->blue_max>>=1;
  369. X      map_info->blue_mult<<=1;
  370. X    }
  371. X  map_info->base_pixel=0;
  372. X  XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel_info);
  373. X  /*
  374. X    Allocating colors in server colormap is based on visual class.
  375. X  */
  376. X  switch (visual_info->class)
  377. X  {
  378. X    case StaticGray:
  379. X    case StaticColor:
  380. X    {
  381. X      /*
  382. X        Define Standard Colormap for StaticGray or StaticColor visual.
  383. X      */
  384. X      number_colors=image->colors;
  385. X      colors=(XColor *) malloc(visual_info->colormap_size*sizeof(XColor));
  386. X      if (colors == (XColor *) NULL)
  387. X        Error("unable to create colormap","memory allocation failed");
  388. X      p=colors;
  389. X      color.flags=DoRed | DoGreen | DoBlue;
  390. X      if (visual_info->class == StaticColor)
  391. X        for (i=0; i < image->colors; i++)
  392. X        {
  393. X          color.red=(unsigned short) (image->colormap[i].red << 8);
  394. X          color.green=(unsigned short) (image->colormap[i].green << 8);
  395. X          color.blue=(unsigned short) (image->colormap[i].blue << 8);
  396. X          status=XAllocColor(display,colormap,&color);
  397. X          if (status == 0)
  398. X            {
  399. X              colormap=XCopyColormapAndFree(display,colormap);
  400. X              XAllocColor(display,colormap,&color);
  401. X            }
  402. X          pixel_info->pixels[i]=color.pixel;
  403. X          *p++=color;
  404. X        }
  405. X      else
  406. X        for (i=0; i < image->colors; i++)
  407. X        {
  408. X          gray_value=Intensity(image->colormap[i]);
  409. X          color.red=(unsigned short) (gray_value << 8);
  410. X          color.green=(unsigned short) (gray_value << 8);
  411. X          color.blue=(unsigned short) (gray_value << 8);
  412. X          status=XAllocColor(display,colormap,&color);
  413. X          if (status == 0)
  414. X            {
  415. X              colormap=XCopyColormapAndFree(display,colormap);
  416. X              XAllocColor(display,colormap,&color);
  417. X            }
  418. X          pixel_info->pixels[i]=color.pixel;
  419. X          *p++=color;
  420. X        }
  421. X      break;
  422. X    }
  423. X    case GrayScale:
  424. X    case PseudoColor:
  425. X    {
  426. X      unsigned int
  427. X        colormap_type;
  428. X
  429. X      /*
  430. X        Define Standard Colormap for GrayScale or PseudoColor visual.
  431. X      */
  432. X      number_colors=image->colors;
  433. X      colors=(XColor *) malloc(visual_info->colormap_size*sizeof(XColor));
  434. X      if (colors == (XColor *) NULL)
  435. X        Error("unable to create colormap","memory allocation failed");
  436. X      /*
  437. X        Determine if image colors will "fit" into X server colormap.
  438. X      */
  439. X      colormap_type=resource_info->colormap;
  440. X      status=XAllocColorCells(display,colormap,False,
  441. X        (unsigned long *) NULL,0,pixel_info->pixels,image->colors);
  442. X      if (status != 0)
  443. X        colormap_type=PrivateColormap;
  444. X      if (colormap_type == SharedColormap)
  445. X        {
  446. X          DiversityPacket
  447. X            *diversity;
  448. X
  449. X          register RunlengthPacket
  450. X            *q;
  451. X
  452. X          unsigned short
  453. X            index;
  454. X
  455. X          /*
  456. X            Define Standard colormap for shared GrayScale or PseudoColor visual:
  457. X          */
  458. X          diversity=(DiversityPacket *)
  459. X            malloc(image->colors*sizeof(DiversityPacket));
  460. X          if (diversity == (DiversityPacket *) NULL)
  461. X            Error("unable to create colormap","memory allocation failed");
  462. X          for (i=0; i < image->colors; i++)
  463. X          {
  464. X            diversity[i].red=image->colormap[i].red;
  465. X            diversity[i].green=image->colormap[i].green;
  466. X            diversity[i].blue=image->colormap[i].blue;
  467. X            diversity[i].index=(unsigned short) i;
  468. X            diversity[i].count=0;
  469. X          }
  470. X          q=image->pixels;
  471. X          for (i=0; i < image->packets; i++)
  472. X          {
  473. X            diversity[q->index].count+=(q->length+1);
  474. X            q++;
  475. X          }
  476. X          /*
  477. X            Sort colors by decreasing intensity.
  478. X          */
  479. X          (void) qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
  480. X            IntensityCompare);
  481. X          for (i=0; i < image->colors; i+=Max(image->colors >> 4,2))
  482. X            diversity[i].count<<=4;  /* increase this colors popularity */
  483. X          diversity[image->colors-1].count<<=4;
  484. X          (void) qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
  485. X            PopularityCompare);
  486. X          /*
  487. X            Allocate colors.
  488. X          */
  489. X          p=colors;
  490. X          color.flags=DoRed | DoGreen | DoBlue;
  491. X          if (visual_info->class == PseudoColor)
  492. X            for (i=0; i < image->colors; i++)
  493. X            {
  494. X              index=diversity[i].index;
  495. X              color.red=(unsigned short) (image->colormap[index].red << 8);
  496. X              color.green=(unsigned short) (image->colormap[index].green << 8);
  497. X              color.blue=(unsigned short) (image->colormap[index].blue << 8);
  498. X              status=XAllocColor(display,colormap,&color);
  499. X              if (status == 0)
  500. X                break;
  501. X              pixel_info->pixels[index]=color.pixel;
  502. X              *p++=color;
  503. X            }
  504. X          else
  505. X            for (i=0; i < image->colors; i++)
  506. X            {
  507. X              index=diversity[i].index;
  508. X              gray_value=Intensity(image->colormap[index]);
  509. X              color.red=(unsigned short) (gray_value << 8);
  510. X              color.green=(unsigned short) (gray_value << 8);
  511. X              color.blue=(unsigned short) (gray_value << 8);
  512. X              status=XAllocColor(display,colormap,&color);
  513. X              if (status == 0)
  514. X                break;
  515. X              pixel_info->pixels[index]=color.pixel;
  516. X              *p++=color;
  517. X            }
  518. X          if (i < image->colors)
  519. X            {
  520. X              register int
  521. X                j;
  522. X
  523. X              XColor
  524. X                *server_colors;
  525. X
  526. X              /*
  527. X                Read X server colormap.
  528. X              */
  529. X              server_colors=(XColor *)
  530. X                malloc(visual_info->colormap_size*sizeof(XColor));
  531. X              if (server_colors == (XColor *) NULL)
  532. X                Error("unable to create colormap","memory allocation failed");
  533. X              for (j=0; j < visual_info->colormap_size; j++)
  534. X                server_colors[j].pixel=(unsigned long) j;
  535. X              XQueryColors(display,colormap,server_colors,
  536. X                (int) Min(visual_info->colormap_size,256));
  537. X              /*
  538. X                Select remaining colors from X server colormap.
  539. X              */
  540. X              if (visual_info->class == PseudoColor)
  541. X                for (; i < image->colors; i++)
  542. X                {
  543. X                  index=diversity[i].index;
  544. X                  color.red=(unsigned short) (image->colormap[index].red << 8);
  545. X                  color.green=(unsigned short)
  546. X                    (image->colormap[index].green << 8);
  547. X                  color.blue=(unsigned short)
  548. X                    (image->colormap[index].blue << 8);
  549. X                  XBestPixel(server_colors,(unsigned int)
  550. X                    Min(visual_info->colormap_size,256),&color);
  551. X                  XAllocColor(display,colormap,&server_colors[color.pixel]);
  552. X                  pixel_info->pixels[index]=color.pixel;
  553. X                  *p++=color;
  554. X                }
  555. X              else
  556. X                for (; i < image->colors; i++)
  557. X                {
  558. X                  index=diversity[i].index;
  559. X                  gray_value=Intensity(image->colormap[index]);
  560. X                  color.red=(unsigned short) (gray_value << 8);
  561. X                  color.green=(unsigned short) (gray_value << 8);
  562. X                  color.blue=(unsigned short) (gray_value << 8);
  563. X                  XBestPixel(server_colors,(unsigned int)
  564. X                    Min(visual_info->colormap_size,256),&color);
  565. X                  XAllocColor(display,colormap,&server_colors[color.pixel]);
  566. X                  pixel_info->pixels[index]=color.pixel;
  567. X                  *p++=color;
  568. X                }
  569. X              if (image->colors < visual_info->colormap_size)
  570. X                {
  571. X                  /*
  572. X                    Fill up colors array-- more choices for pen colors.
  573. X                  */
  574. X                  retain_colors=
  575. X                    Min(visual_info->colormap_size-image->colors,256);
  576. X                  for (i=0; i < retain_colors; i++)
  577. X                    *p++=server_colors[i];
  578. X                  number_colors+=retain_colors;
  579. X                }
  580. X              (void) free((char *) server_colors);
  581. X            }
  582. X          (void) free((char *) diversity);
  583. X          break;
  584. X        }
  585. X      /*
  586. X        Define Standard colormap for private GrayScale or PseudoColor visual.
  587. X      */
  588. X      if (status == 0)
  589. X        {
  590. X          /*
  591. X            Not enough colormap entries in the colormap-- Create a new colormap.
  592. X          */
  593. X          colormap=XCreateColormap(display,
  594. X            XRootWindow(display,visual_info->screen),visual_info->visual,
  595. X            AllocNone);
  596. X          if (colormap == (Colormap) NULL)
  597. X            Error("unable to create colormap",(char *) NULL);
  598. X          map_info->colormap=colormap;
  599. X          if (image->colors < visual_info->colormap_size)
  600. X            {
  601. X              /*
  602. X                Retain colors from the default colormap to help lessens the
  603. X                effects of colormap flashing.
  604. X              */
  605. X              retain_colors=Min(visual_info->colormap_size-image->colors,256);
  606. X              p=colors+image->colors;
  607. X              for (i=0; i < retain_colors; i++)
  608. X              {
  609. X                p->pixel=(unsigned long) i;
  610. X                p++;
  611. X              }
  612. X              XQueryColors(display,
  613. X                XDefaultColormap(display,visual_info->screen),
  614. X                colors+image->colors,(int) retain_colors);
  615. X              /*
  616. X                Transfer colors from default to private colormap.
  617. X              */
  618. X              XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
  619. X                pixel_info->pixels,retain_colors);
  620. X              p=colors+image->colors;
  621. X              for (i=0; i < retain_colors; i++)
  622. X              {
  623. X                p->pixel=pixel_info->pixels[i];
  624. X                p++;
  625. X              }
  626. X              XStoreColors(display,colormap,colors+image->colors,retain_colors);
  627. X              number_colors+=retain_colors;
  628. X            }
  629. X          XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
  630. X            pixel_info->pixels,image->colors);
  631. X        }
  632. X      /*
  633. X        Store the image colormap.
  634. X      */
  635. X      p=colors;
  636. X      color.flags=DoRed | DoGreen | DoBlue;
  637. X      if (visual_info->class == PseudoColor)
  638. X        for (i=0; i < image->colors; i++)
  639. X        {
  640. X          color.red=(unsigned short) (image->colormap[i].red << 8);
  641. X          color.green=(unsigned short) (image->colormap[i].green << 8);
  642. X          color.blue=(unsigned short) (image->colormap[i].blue << 8);
  643. X          color.pixel=pixel_info->pixels[i];
  644. X          *p++=color;
  645. X        }
  646. X      else
  647. X        for (i=0; i < image->colors; i++)
  648. X        {
  649. X          gray_value=Intensity(image->colormap[i]);
  650. X          color.red=(unsigned short) (gray_value << 8);
  651. X          color.green=(unsigned short) (gray_value << 8);
  652. X          color.blue=(unsigned short) (gray_value << 8);
  653. X          color.pixel=pixel_info->pixels[i];
  654. X          *p++=color;
  655. X        }
  656. X      XStoreColors(display,colormap,colors,image->colors);
  657. X      break;
  658. X    }
  659. X    case TrueColor:
  660. X    case DirectColor:
  661. X    default:
  662. X    {
  663. X      unsigned int
  664. X        linear_colormap;
  665. X
  666. X      /*
  667. X        Define Standard Colormap for TrueColor or DirectColor visual.
  668. X      */
  669. X      number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
  670. X        (map_info->green_max*map_info->green_mult)+
  671. X        (map_info->blue_max*map_info->blue_mult)+1);
  672. X      linear_colormap=
  673. X        ((map_info->red_max+1) == visual_info->colormap_size) &&
  674. X        ((map_info->green_max+1) == visual_info->colormap_size) &&
  675. X        ((map_info->blue_max+1) == visual_info->colormap_size);
  676. X      if (linear_colormap)
  677. X        number_colors=visual_info->colormap_size;
  678. X      /*
  679. X        Allocate color array.
  680. X      */
  681. X      colors=(XColor *) malloc(number_colors*sizeof(XColor));
  682. X      if (colors == (XColor *) NULL)
  683. X        Error("unable to create colormap","memory allocation failed");
  684. X      /*
  685. X        Initialize linear color ramp.
  686. X      */
  687. X      p=colors;
  688. X      color.flags=DoRed | DoGreen | DoBlue;
  689. X      if (linear_colormap)
  690. X        for (i=0; i < number_colors; i++)
  691. X        {
  692. X          color.blue=(unsigned short) 0;
  693. X          if (map_info->blue_max > 0)
  694. X            color.blue=(unsigned short)
  695. X              (((i % map_info->green_mult)*65535)/map_info->blue_max);
  696. X          color.green=color.blue;
  697. X          color.red=color.blue;
  698. X          color.pixel=XStandardPixel(map_info,color,16);
  699. X          *p++=color;
  700. X        }
  701. X      else
  702. X        for (i=0; i < number_colors; i++)
  703. X        {
  704. X          color.red=(unsigned short) 0;
  705. X          if (map_info->red_max > 0)
  706. X            color.red=(unsigned short)
  707. X              (((i/map_info->red_mult)*65535)/map_info->red_max);
  708. X          color.green=(unsigned short) 0;
  709. X          if (map_info->green_max > 0)
  710. X            color.green=(unsigned short) ((((i/map_info->green_mult) %
  711. X              (map_info->green_max+1))*65535)/map_info->green_max);
  712. X          color.blue=(unsigned short) 0;
  713. X          if (map_info->blue_max > 0)
  714. X            color.blue=(unsigned short)
  715. X              (((i % map_info->green_mult)*65535)/map_info->blue_max);
  716. X          color.pixel=XStandardPixel(map_info,color,16);
  717. X          *p++=color;
  718. X        }
  719. X      if ((visual_info->class == DirectColor) &&
  720. X          (colormap != XDefaultColormap(display,visual_info->screen)))
  721. X        XStoreColors(display,colormap,colors,number_colors);
  722. X      else
  723. X        for (i=0; i < number_colors; i++)
  724. X          XAllocColor(display,colormap,&colors[i]);
  725. X      break;
  726. X    }
  727. X  }
  728. X  if ((visual_info->class != DirectColor) && (visual_info->class != TrueColor))
  729. X    {
  730. X      /*
  731. X        Set background/border/foreground/pen pixels.
  732. X      */
  733. X      status=XAllocColor(display,colormap,&pixel_info->background_color);
  734. X      if (status == 0)
  735. X        XBestPixel(colors,number_colors,&pixel_info->background_color);
  736. X      status=XAllocColor(display,colormap,&pixel_info->foreground_color);
  737. X      if (status == 0)
  738. X        XBestPixel(colors,number_colors,&pixel_info->foreground_color);
  739. X      status=XAllocColor(display,colormap,&pixel_info->border_color);
  740. X      if (status == 0)
  741. X        XBestPixel(colors,number_colors,&pixel_info->border_color);
  742. X      for (i=0; i < MaxNumberPens; i++)
  743. X      {
  744. X        status=XAllocColor(display,colormap,&pixel_info->pen_color[i]);
  745. X        if (status == 0)
  746. X          XBestPixel(colors,number_colors,&pixel_info->pen_color[i]);
  747. X        pixel_info->pixels[image->colors+i]=pixel_info->pen_color[i].pixel;
  748. X      }
  749. X      pixel_info->colors=image->colors+MaxNumberPens;
  750. X    }
  751. X  (void) free((char *) colors);
  752. X  if (resource_info->debug)
  753. X    {
  754. X      (void) fprintf(stderr,"Standard Colormap:\n");
  755. X      (void) fprintf(stderr,"  colormap id: 0x%lx\n",map_info->colormap);
  756. X      (void) fprintf(stderr,"  red, green, blue max: %lu %lu %lu\n",
  757. X        map_info->red_max,map_info->green_max,map_info->blue_max);
  758. X      (void) fprintf(stderr,"  red, green, blue mult: %lu %lu %lu\n",
  759. X        map_info->red_mult,map_info->green_mult,map_info->blue_mult);
  760. X    }
  761. }
  762. X
  763. /*
  764. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  765. %                                                                             %
  766. %                                                                             %
  767. %                                                                             %
  768. %   X M a k e W i n d o w                                                     %
  769. %                                                                             %
  770. %                                                                             %
  771. %                                                                             %
  772. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  773. %
  774. %  Function XMakeWindow creates an X11 window.
  775. %
  776. %  The format of the XMakeWindow routine is:
  777. %
  778. %      XMakeWindow(display,parent,argv,argc,class_hint,manager_hints,property,
  779. %        window_info)
  780. %
  781. %  A description of each parameter follows:
  782. %
  783. %    o display: Specifies a connection to an X server; returned from
  784. %      XOpenDisplay.
  785. %
  786. %    o parent: Specifies the parent window_info.
  787. %
  788. %    o argv: Specifies the application's argument list.
  789. %
  790. %    o argc: Specifies the number of arguments.
  791. %
  792. %    o class_hint: Specifies a pointer to a X11 XClassHint structure.
  793. %
  794. %    o manager_hints: Specifies a pointer to a X11 XWMHints structure.
  795. %
  796. %    o property: A property to define on the window_info.
  797. %
  798. %    o window_info: Specifies a pointer to a X11 XWindowInfo structure.
  799. %
  800. %
  801. */
  802. void XMakeWindow(display,parent,argv,argc,class_hint,manager_hints,property,
  803. X  window_info)
  804. Display
  805. X  *display;
  806. X
  807. Window
  808. X  parent;
  809. X
  810. char
  811. X  **argv;
  812. X
  813. int
  814. X  argc;
  815. X
  816. XXClassHint
  817. X  *class_hint;
  818. X
  819. XXWMHints
  820. X  *manager_hints;
  821. X
  822. Atom
  823. X  property;
  824. X
  825. XXWindowInfo
  826. X  *window_info;
  827. {
  828. #define MinWindowSize  64
  829. X
  830. X  int
  831. X    status;
  832. X
  833. X  XSizeHints
  834. X    *size_hints;
  835. X
  836. X  XTextProperty
  837. X    icon_name,
  838. X    window_name;
  839. X
  840. X  /*
  841. X    Set window_info hints.
  842. X  */
  843. X  size_hints=XAllocSizeHints();
  844. X  if (size_hints == (XSizeHints *) NULL)
  845. X    Error("unable to make window_info","memory allocation failed");
  846. X  size_hints->flags=window_info->flags;
  847. X  size_hints->x=window_info->x;
  848. X  size_hints->y=window_info->y;
  849. X  size_hints->width=window_info->width;
  850. X  size_hints->height=window_info->height;
  851. X  if (!window_info->immutable)
  852. X    {
  853. X      /*
  854. X        Window size can be changed.
  855. X      */
  856. X      size_hints->min_width=window_info->min_width;
  857. X      size_hints->min_height=window_info->min_height;
  858. X      size_hints->flags|=PMinSize;
  859. X    }
  860. X  else
  861. X    {
  862. X      /*
  863. X        Window size cannot be changed.
  864. X      */
  865. X      size_hints->min_width=window_info->width;
  866. X      size_hints->min_height=window_info->height;
  867. X      size_hints->max_width=window_info->width;
  868. X      size_hints->max_height=window_info->height;
  869. X      size_hints->flags|=PMinSize | PMaxSize;
  870. X    }
  871. X  size_hints->flags|=PResizeInc;
  872. X  size_hints->width_inc=window_info->width_inc;
  873. X  size_hints->height_inc=window_info->height_inc;
  874. #ifndef PRE_R4_ICCCM
  875. X  size_hints->flags|=PBaseSize;
  876. X  size_hints->base_width=size_hints->min_width;
  877. X  size_hints->base_height=size_hints->min_height;
  878. #endif
  879. X  if (window_info->geometry != (char *) NULL)
  880. X    {
  881. X      char
  882. X        default_geometry[2048];
  883. X
  884. X      int
  885. X        flags,
  886. X        gravity;
  887. X
  888. X      /*
  889. X        User specified geometry.
  890. X      */
  891. X      (void) sprintf(default_geometry,"%dx%d",size_hints->width,
  892. X        size_hints->height);
  893. X      flags=XWMGeometry(display,window_info->screen,window_info->geometry,
  894. X        default_geometry,window_info->border_width,size_hints,&size_hints->x,
  895. X        &size_hints->y,&size_hints->width,&size_hints->height,&gravity);
  896. X      window_info->x=size_hints->x;
  897. X      window_info->y=size_hints->y;
  898. X      if ((flags & WidthValue) && (flags & HeightValue))
  899. X        size_hints->flags|=USSize;
  900. X      if ((flags & XValue) && (flags & YValue))
  901. X        size_hints->flags|=USPosition;
  902. #ifndef PRE_R4_ICCCM
  903. X      size_hints->win_gravity=gravity;
  904. X      size_hints->flags|=PWinGravity;
  905. #endif
  906. X    }
  907. X  if (window_info->id == (Window) NULL)
  908. X    window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
  909. X      window_info->width,window_info->height,window_info->border_width,
  910. X      window_info->depth,InputOutput,window_info->visual_info->visual,
  911. X      window_info->mask,&window_info->attributes);
  912. X  else
  913. X    {
  914. X      unsigned int
  915. X        mask;
  916. X
  917. X      XEvent
  918. X        discard_event;
  919. X
  920. X      XWindowChanges
  921. X        window_info_changes;
  922. X
  923. X      /*
  924. X        Window already exists;  change relevant attributes.
  925. X      */
  926. X      XChangeWindowAttributes(display,window_info->id,window_info->mask,
  927. X        &window_info->attributes);
  928. X      XSync(display,False);
  929. X      while (XCheckTypedWindowEvent(display,window_info->id,ConfigureNotify,
  930. X        &discard_event));
  931. X      window_info_changes.x=window_info->x;
  932. X      window_info_changes.y=window_info->y;
  933. X      window_info_changes.width=window_info->width;
  934. X      window_info_changes.height=window_info->height;
  935. X      mask=CWWidth | CWHeight;
  936. X      if (window_info->flags & USPosition)
  937. X        mask|=CWX | CWY;
  938. X      XReconfigureWMWindow(display,window_info->id,window_info->screen,mask,
  939. X        &window_info_changes);
  940. X    }
  941. X  if (window_info->id == (Window) NULL)
  942. X    Error("unable to create window",window_info->name);
  943. X  status=XStringListToTextProperty(&window_info->name,1,&window_name);
  944. X  if (status == 0)
  945. X    Error("unable to create text property",window_info->name);
  946. X  if (window_info->icon_name == (char *) NULL)
  947. X    icon_name=window_name;
  948. X  else
  949. X    {
  950. X      status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
  951. X      if (status == 0)
  952. X        Error("unable to create text property",window_info->icon_name);
  953. X    }
  954. X  if (window_info->icon_geometry != (char *) NULL)
  955. X    {
  956. X      int
  957. X        flags,
  958. X        gravity,
  959. X        height,
  960. X        width;
  961. X
  962. X      /*
  963. X        User specified icon geometry.
  964. X      */
  965. X      size_hints->flags|=USPosition;
  966. X      flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
  967. X        (char *) NULL,0,size_hints,&manager_hints->icon_x,
  968. X        &manager_hints->icon_y,&width,&height,&gravity);
  969. X      if ((flags & XValue) && (flags & YValue))
  970. X        manager_hints->flags|=IconPositionHint;
  971. X    }
  972. X  XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
  973. X    size_hints,manager_hints,class_hint);
  974. X  XSetWMProtocols(display,window_info->id,&property,1);
  975. X  XFree((void *) size_hints);
  976. }
  977. X
  978. /*
  979. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  980. %                                                                             %
  981. %                                                                             %
  982. %                                                                             %
  983. %   X P o p U p A l e r t                                                     %
  984. %                                                                             %
  985. %                                                                             %
  986. %                                                                             %
  987. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  988. %
  989. %  Function XPopupAlert displays a popup window with an alert to the user.
  990. %  The function returns when the user presses a button or key.
  991. %
  992. %  The format of the XPopupAlert routine is:
  993. %
  994. %    XPopupAlert(display,window,message,qualifier)
  995. %
  996. %  A description of each parameter follows:
  997. %
  998. %    o display: Specifies a connection to an X server;  returned from
  999. %      XOpenDisplay.
  1000. %
  1001. %    o window: Specifies a pointer to a XWindowInfo structure.
  1002. %
  1003. %    o message: Specifies the message to display before terminating the
  1004. %      program.
  1005. %
  1006. %    o qualifier: Specifies any qualifier to the message.
  1007. %
  1008. %
  1009. */
  1010. void XPopupAlert(display,window,message,qualifier)
  1011. Display
  1012. X  *display;
  1013. X
  1014. XXWindowInfo
  1015. X  *window;
  1016. X
  1017. char
  1018. X  *message,
  1019. X  *qualifier;
  1020. {
  1021. X  char
  1022. X    text[2048];
  1023. X
  1024. X  int
  1025. X    i,
  1026. X    state,
  1027. X    x,
  1028. X    y;
  1029. X
  1030. X  unsigned int
  1031. X    height,
  1032. X    mask;
  1033. X
  1034. X  Window
  1035. X    root_window;
  1036. X
  1037. X  XEvent
  1038. X    event;
  1039. X
  1040. X  XFontStruct
  1041. X    *font_info;
  1042. X
  1043. X  /*
  1044. X    Position and map popup window.
  1045. X  */
  1046. X  (void) sprintf(text,"%s",message);
  1047. X  if (qualifier != (char *) NULL)
  1048. X    {
  1049. X      (void) strcat(text," (");
  1050. X      (void) strcat(text,qualifier);
  1051. X      (void) strcat(text,")");
  1052. X    }
  1053. X  font_info=window->font_info;
  1054. X  window->width=XTextWidth(font_info,text,strlen(text))+
  1055. X    4*font_info->max_bounds.width;
  1056. X  height=font_info->ascent+font_info->descent;
  1057. X  window->height=2*height;
  1058. X  XQueryPointer(display,XRootWindow(display,window->screen),&root_window,
  1059. X    &root_window,&i,&i,&window->x,&window->y,&mask);
  1060. X  x=Min(window->x,XDisplayWidth(display,window->screen)-window->width);
  1061. X  y=Min(window->y,XDisplayHeight(display,window->screen)-window->height);
  1062. X  XMoveResizeWindow(display,window->id,x,y,window->width,window->height);
  1063. X  XMapRaised(display,window->id);
  1064. X  XClearWindow(display,window->id);
  1065. X  /*
  1066. X    Display message in popup window.
  1067. X  */
  1068. X  x=2*font_info->max_bounds.width;
  1069. X  y=font_info->ascent+(height >> 1);
  1070. X  XDrawString(display,window->id,window->graphic_context,x,y,text,strlen(text));
  1071. X  XBell(display,0);
  1072. X  /*
  1073. X    Wait for a key press.
  1074. X  */
  1075. X  state=DefaultState;
  1076. X  do
  1077. X  {
  1078. X    /*
  1079. X      Wait for next event.
  1080. X    */
  1081. X    XMaskEvent(display,ButtonPressMask | KeyPressMask | VisibilityChangeMask,
  1082. X      &event);
  1083. X    switch (event.type)
  1084. X    {
  1085. X      case ButtonPress:
  1086. X      case KeyPress:
  1087. X      {
  1088. X        state|=ExitState;
  1089. X        break;
  1090. X      }
  1091. X      case VisibilityNotify:
  1092. X      {
  1093. X        XMapRaised(display,window->id);
  1094. X        break;
  1095. X      }
  1096. X      default:
  1097. X        break;
  1098. X    }
  1099. X  } while (!(state & ExitState));
  1100. X  XWithdrawWindow(display,window->id,window->screen);
  1101. }
  1102. X
  1103. /*
  1104. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1105. %                                                                             %
  1106. %                                                                             %
  1107. %                                                                             %
  1108. %   X P o p U p M e n u                                                       %
  1109. %                                                                             %
  1110. %                                                                             %
  1111. %                                                                             %
  1112. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1113. %
  1114. %  Function XPopupMenu maps a menu and returns the command pointed to by the
  1115. %  user when the button is released.
  1116. %
  1117. %  The format of the XPopupMenu routine is:
  1118. %
  1119. %    selection_number=XPopupMenu(display,window,x,y,menu_title,menu_selections,
  1120. %      number_selections,item)
  1121. %
  1122. %  A description of each parameter follows:
  1123. %
  1124. %    o selection_number: Specifies the number of the selection that the
  1125. %      user choose.
  1126. %
  1127. %    o display: Specifies a connection to an X server;  returned from
  1128. %      XOpenDisplay.
  1129. %
  1130. %    o window: Specifies a pointer to a XWindowInfo structure.
  1131. %
  1132. %    o x: Specifies an unsigned integer representing the root offset in the
  1133. %      x-direction.
  1134. %
  1135. %    o y: Specifies an unsigned integer representing the root offset in the
  1136. %      x-direction.
  1137. %
  1138. %    o menu_title: Specifies a character string that describes the menu
  1139. %      selections.
  1140. %
  1141. %    o menu_selections: Specifies a pointer to one or more strings that
  1142. %      make up the choices in the menu.
  1143. %
  1144. %    o number_selections: Specifies the number of choices in the menu.
  1145. %
  1146. %    o item: Specifies a character array.  The item selected from the menu
  1147. %      is returned here.
  1148. %
  1149. %
  1150. */
  1151. int XPopupMenu(display,window,x,y,menu_title,menu_selections,number_selections,
  1152. X  item)
  1153. Display
  1154. X  *display;
  1155. X
  1156. XXWindowInfo
  1157. X  *window;
  1158. X
  1159. int
  1160. X  x,
  1161. X  y;
  1162. X
  1163. char
  1164. X  *menu_title,
  1165. X  **menu_selections;
  1166. X
  1167. unsigned int
  1168. X  number_selections;
  1169. X
  1170. char
  1171. X  *item;
  1172. {
  1173. X  typedef struct _Selection
  1174. X  {
  1175. X    int
  1176. X      id,
  1177. X      x,
  1178. X      y;
  1179. X
  1180. X    unsigned int
  1181. X      width,
  1182. X      height;
  1183. X  } Selection;
  1184. X
  1185. X  GC
  1186. X    graphic_context;
  1187. X
  1188. X  int
  1189. X    id,
  1190. X    state;
  1191. X
  1192. X  Selection
  1193. X    selection;
  1194. X
  1195. X  unsigned int
  1196. X    height,
  1197. X    title_height,
  1198. X    width;
  1199. X
  1200. X  XEvent
  1201. X    event;
  1202. X
  1203. X  XFontStruct
  1204. X    *font_info;
  1205. X
  1206. X  /*
  1207. X    Size and position menu window under current pointer location and map.
  1208. X  */
  1209. X  font_info=window->font_info;
  1210. X  window->width=XTextWidth(font_info,menu_title,strlen(menu_title));
  1211. X  for (selection.id=0; selection.id < number_selections; selection.id++)
  1212. X  {
  1213. X    width=XTextWidth(font_info,menu_selections[selection.id],
  1214. X      strlen(menu_selections[selection.id]));
  1215. X    if (width > window->width)
  1216. X      window->width=width;
  1217. X  }
  1218. X  window->width+=4*font_info->max_bounds.width;
  1219. X  title_height=(font_info->descent+font_info->ascent)*2;
  1220. X  height=font_info->ascent+font_info->descent;
  1221. X  window->height=title_height+number_selections*(height+(height >> 2));
  1222. X  width=window->width+2*window->border_width;
  1223. X  window->x=x-(int) width/2;
  1224. X  if (window->x < 0)
  1225. X    window->x=0;
  1226. X  else
  1227. X    if (window->x > (XDisplayWidth(display,window->screen)-width))
  1228. X      window->x=XDisplayWidth(display,window->screen)-width;
  1229. X  height=window->height+2*window->border_width;
  1230. X  window->y=y-(int) window->border_width;
  1231. X  if (window->y < 0)
  1232. X    window->y=0;
  1233. X  else
  1234. X    if (window->y > (XDisplayHeight(display,window->screen)-height))
  1235. X      window->y=XDisplayHeight(display,window->screen)-height;
  1236. X  XMoveResizeWindow(display,window->id,window->x,window->y,window->width,
  1237. X    window->height);
  1238. X  XMapRaised(display,window->id);
  1239. X  XClearWindow(display,window->id);
  1240. X  /*
  1241. X    Draw title.
  1242. X  */
  1243. X  width=XTextWidth(font_info,menu_title,strlen(menu_title));
  1244. X  height=font_info->ascent+font_info->descent;
  1245. X  graphic_context=window->graphic_context;
  1246. X  XDrawString(display,window->id,graphic_context,
  1247. X    (int) (window->width-width) >> 1,(int) (font_info->ascent*3) >> 1,
  1248. X    menu_title,strlen(menu_title));
  1249. X  XDrawLine(display,window->id,graphic_context,0,title_height-(height >> 3),
  1250. X    window->width,title_height-(height >> 3));
  1251. X  /*
  1252. X    Draw menu selections.
  1253. X  */
  1254. X  selection.x=2*font_info->max_bounds.width;
  1255. X  selection.y=title_height+font_info->ascent+(height >> 3);
  1256. X  selection.width=window->width;
  1257. X  selection.height=height+(height >> 2);
  1258. X  for (selection.id=0; selection.id < number_selections; selection.id++)
  1259. X  {
  1260. X    XDrawString(display,window->id,graphic_context,selection.x,selection.y,
  1261. X      menu_selections[selection.id],strlen(menu_selections[selection.id]));
  1262. X    selection.y+=(int) selection.height;
  1263. X  }
  1264. X  /*
  1265. X    Highlight menu as pointer moves;  return item on button release.
  1266. X  */
  1267. X  selection.id=(-1);
  1268. X  state=DefaultState;
  1269. X  do
  1270. X  {
  1271. X    /*
  1272. X      Wait for next event.
  1273. X    */
  1274. X    XMaskEvent(display,ButtonPressMask | ButtonMotionMask | ButtonReleaseMask |
  1275. X      EnterWindowMask | LeaveWindowMask | VisibilityChangeMask,&event);
  1276. X    switch (event.type)
  1277. X    {
  1278. X      case ButtonPress:
  1279. X        break;
  1280. X      case ButtonRelease:
  1281. X      {
  1282. X        /*
  1283. X          Exit menu.
  1284. X        */
  1285. X        *item='\0';
  1286. X        state|=ExitState;
  1287. X        break;
  1288. X      }
  1289. X      case EnterNotify:
  1290. X      {
  1291. X        if (event.xcrossing.window != window->id)
  1292. X          break;
  1293. X        id=((event.xcrossing.y-title_height)/(int) selection.height);
  1294. X        if ((id < 0) || (id >= number_selections))
  1295. X          break;
  1296. X        /*
  1297. X          Highlight this selection.
  1298. X        */
  1299. X        selection.id=id;
  1300. X        selection.y=title_height+font_info->ascent+(height >> 3)+
  1301. X          selection.id*selection.height;
  1302. X        XFillRectangle(display,window->id,graphic_context,0,selection.y-
  1303. X          font_info->ascent-(height >> 3),selection.width,selection.height);
  1304. X        XDrawString(display,window->id,window->highlight_context,selection.x,
  1305. X          selection.y,menu_selections[selection.id],
  1306. X          strlen(menu_selections[selection.id]));
  1307. X        break;
  1308. X      }
  1309. X      case LeaveNotify:
  1310. X      {
  1311. X        if (event.xcrossing.window != window->id)
  1312. X          break;
  1313. X        if ((selection.id >= 0) && (selection.id < number_selections))
  1314. X          {
  1315. X            /*
  1316. X              Unhighlight last selection.
  1317. X            */
  1318. X            XClearArea(display,window->id,0,selection.y-font_info->ascent-
  1319. X              (height >> 3),selection.width,selection.height,False);
  1320. X            XDrawString(display,window->id,graphic_context,selection.x,
  1321. X              selection.y,menu_selections[selection.id],
  1322. X              strlen(menu_selections[selection.id]));
  1323. X          }
  1324. X        selection.id=(-1);
  1325. X        break;
  1326. X      }
  1327. X      case MotionNotify:
  1328. X      {
  1329. X        if (event.xmotion.window != window->id)
  1330. X          break;
  1331. X        /*
  1332. X          Determine if pointer has moved to a new selection.
  1333. X        */
  1334. X        id=(event.xmotion.y-title_height)/(int) selection.height;
  1335. X        if ((selection.id >= 0) && (selection.id < number_selections))
  1336. X          {
  1337. X            /*
  1338. X              Unhighlight last selection.
  1339. X            */
  1340. X            if (id == selection.id)
  1341. X              break;
  1342. X            XClearArea(display,window->id,0,selection.y-font_info->ascent-
  1343. X              (height >> 3),selection.width,selection.height,False);
  1344. X            XDrawString(display,window->id,graphic_context,selection.x,
  1345. X              selection.y,menu_selections[selection.id],
  1346. X              strlen(menu_selections[selection.id]));
  1347. X          }
  1348. X        selection.id=id;
  1349. X        if ((id < 0) || (id >= number_selections))
  1350. X          break;
  1351. X        /*
  1352. X          Highlight this selection.
  1353. X        */
  1354. X        selection.y=title_height+font_info->ascent+(height >> 3)+selection.id*
  1355. X          selection.height;
  1356. X        XFillRectangle(display,window->id,graphic_context,0,selection.y-
  1357. X          font_info->ascent-(height >> 3),selection.width,selection.height);
  1358. X        XDrawString(display,window->id,window->highlight_context,selection.x,
  1359. X          selection.y,menu_selections[selection.id],
  1360. X          strlen(menu_selections[selection.id]));
  1361. X        break;
  1362. X      }
  1363. X      case VisibilityNotify:
  1364. X      {
  1365. X        XMapRaised(display,window->id);
  1366. X        break;
  1367. X      }
  1368. X      default:
  1369. X        break;
  1370. X    }
  1371. X  } while (!(state & ExitState));
  1372. X  XWithdrawWindow(display,window->id,window->screen);
  1373. X  if ((selection.id < 0) || (selection.id >= number_selections))
  1374. X    return(-1);
  1375. X  (void) strcpy(item,menu_selections[selection.id]);
  1376. X  return(selection.id);
  1377. }
  1378. X
  1379. /*
  1380. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1381. %                                                                             %
  1382. %                                                                             %
  1383. %                                                                             %
  1384. %   X P o p U p Q u e r y                                                     %
  1385. %                                                                             %
  1386. %                                                                             %
  1387. %                                                                             %
  1388. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1389. %
  1390. %  Function XPopupQuery displays a popup window with a query to the user.  The
  1391. %  user keys their reply and presses return to exit.  The typed text is
  1392. %  returned as the reply function parameter.
  1393. %
  1394. %  The format of the XPopupQuery routine is:
  1395. %
  1396. %    XPopupQuery(display,window,query,reply)
  1397. %
  1398. %  A description of each parameter follows:
  1399. %
  1400. %    o display: Specifies a connection to an X server;  returned from
  1401. %      XOpenDisplay.
  1402. %
  1403. %    o window: Specifies a pointer to a XWindowInfo structure.
  1404. %
  1405. %    o query: Specifies a pointer to the query to present to the user.
  1406. %
  1407. %    o reply: The response from the user is returned in this parameter.
  1408. %
  1409. %
  1410. */
  1411. void XPopupQuery(display,window,query,reply)
  1412. Display
  1413. X  *display;
  1414. X
  1415. XXWindowInfo
  1416. X  *window;
  1417. X
  1418. char
  1419. X  *query,
  1420. X  *reply;
  1421. {
  1422. X  char
  1423. X    *p,
  1424. X    text[2048];
  1425. X
  1426. X  Cursor
  1427. X    cursor;
  1428. X
  1429. X  GC
  1430. X    graphic_context;
  1431. X
  1432. X  int
  1433. X    i,
  1434. X    state,
  1435. X    x,
  1436. X    y;
  1437. X
  1438. X  unsigned int
  1439. X    height,
  1440. X    mask;
  1441. X
  1442. X  Window
  1443. X    root_window;
  1444. X
  1445. X  XEvent
  1446. X    event;
  1447. X
  1448. X  XFontStruct
  1449. X    *font_info;
  1450. X
  1451. X  /*
  1452. X    Position and map popup window.
  1453. X  */
  1454. X  (void) sprintf(text,"%s %s",query,reply);
  1455. X  font_info=window->font_info;
  1456. X  window->width=XTextWidth(font_info,text,strlen(text))+
  1457. X    22*font_info->max_bounds.width;
  1458. X  height=font_info->ascent+font_info->descent;
  1459. X  window->height=2*height;
  1460. X  XQueryPointer(display,XRootWindow(display,window->screen),&root_window,
  1461. X    &root_window,&i,&i,&window->x,&window->y,&mask);
  1462. X  x=Min(window->x,XDisplayWidth(display,window->screen)-window->width);
  1463. X  y=Min(window->y,XDisplayHeight(display,window->screen)-window->height);
  1464. X  XMoveResizeWindow(display,window->id,x,y,window->width,window->height);
  1465. X  XMapRaised(display,window->id);
  1466. X  XClearWindow(display,window->id);
  1467. X  /*
  1468. X    Display query in popup window.
  1469. X  */
  1470. X  graphic_context=window->graphic_context;
  1471. X  x=2*font_info->max_bounds.width;
  1472. X  y=font_info->ascent+(height >> 1);
  1473. X  XDrawString(display,window->id,graphic_context,x,y,query,strlen(query));
  1474. X  x+=XTextWidth(font_info,query,strlen(query))+font_info->max_bounds.width;
  1475. X  /*
  1476. X    Display reply in popup window.
  1477. X  */
  1478. X  XDrawString(display,window->id,graphic_context,x,y,reply,strlen(reply));
  1479. X  x+=XTextWidth(font_info,reply,strlen(reply));
  1480. X  /*
  1481. X    Begin editing the reply.
  1482. X  */
  1483. X  state=DefaultState;
  1484. X  cursor=XCreateFontCursor(display,XC_pencil);
  1485. X  XRecolorCursor(display,cursor,&window->pixel_info->background_color,
  1486. X    &window->pixel_info->foreground_color);
  1487. X  XDefineCursor(display,window->id,cursor);
  1488. X  p=reply+strlen(reply);
  1489. X  do
  1490. X  {
  1491. X    if ((x+font_info->max_bounds.width) >= window->width)
  1492. X      {
  1493. X        /*
  1494. X          Resize popup window.
  1495. X        */
  1496. X        (void) sprintf(text,"%s %s",query,reply);
  1497. X        window->width=XTextWidth(window->font_info,text,strlen(text))+
  1498. X          22*window->font_info->max_bounds.width;
  1499. X        XResizeWindow(display,window->id,window->width,window->height);
  1500. X        /*
  1501. X          Display reply in popup window.
  1502. X        */
  1503. X        x=2*font_info->max_bounds.width;
  1504. X        XDrawString(display,window->id,graphic_context,x,y,query,strlen(query));
  1505. X        x+=XTextWidth(font_info,query,strlen(query))+
  1506. X          font_info->max_bounds.width;
  1507. X        XDrawString(display,window->id,graphic_context,x,y,reply,strlen(reply));
  1508. X        x+=XTextWidth(font_info,reply,strlen(reply));
  1509. X      }
  1510. X    /*
  1511. X      Display text cursor.
  1512. X    */
  1513. X    *p='\0';
  1514. X    XDrawString(display,window->id,graphic_context,x,y,"_",1);
  1515. X    /*
  1516. X      Wait for next event.
  1517. X    */
  1518. X    XMaskEvent(display,ButtonPressMask | KeyPressMask | VisibilityChangeMask,
  1519. X      &event);
  1520. X    /*
  1521. X      Erase text cursor.
  1522. X    */
  1523. X    XClearArea(display,window->id,x,y-font_info->ascent,
  1524. X      (unsigned int) font_info->max_bounds.width,height,False);
  1525. X    switch (event.type)
  1526. X    {
  1527. X      case ButtonPress:
  1528. X      {
  1529. X        Atom
  1530. X          type;
  1531. X
  1532. X        int
  1533. X          format,
  1534. X          status;
  1535. X
  1536. X        unsigned char
  1537. X          *data;
  1538. X
  1539. X        unsigned long
  1540. X          after,
  1541. X          length;
  1542. X
  1543. X        if ((event.xbutton.button == Button3) &&
  1544. X            (event.xbutton.state & Mod1Mask))
  1545. X          {
  1546. X            /*
  1547. X              Convert Alt-Button3 to Button2.
  1548. X            */
  1549. X            event.xbutton.button=Button2;
  1550. X            event.xbutton.state&=(~Mod1Mask);
  1551. X          }
  1552. X        if (event.xbutton.button != Button2)
  1553. X          break;
  1554. X        /*
  1555. X          Obtain response from cut buffer.
  1556. X        */
  1557. X        status=XGetWindowProperty(display,XRootWindow(display,0),XA_CUT_BUFFER0,
  1558. X          0L,2047L,False,XA_STRING,&type,&format,&length,&after,&data);
  1559. X        if ((status != Success) || (type != XA_STRING) || (format == 32) ||
  1560. X            (length == 0))
  1561. X          break;
  1562. X        /*
  1563. X          Append cut buffer to reply.
  1564. X        */
  1565. X        (void) strncpy(p,(char *) data,(int) length);
  1566. X        XFree((void *) data);
  1567. X        XDrawString(display,window->id,graphic_context,x,y,p,(int) length);
  1568. X        x+=XTextWidth(font_info,p,(unsigned int) length);
  1569. X        p+=length;
  1570. X        *p='\0';
  1571. X        break;
  1572. X      }
  1573. X      case KeyPress:
  1574. X      {
  1575. X        static char
  1576. X          command[2048];
  1577. X
  1578. X        static KeySym
  1579. X          key_symbol;
  1580. X
  1581. X        /*
  1582. X          Respond to a user key press.
  1583. X        */
  1584. X        *command='\0';
  1585. X        XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
  1586. X          &key_symbol,(XComposeStatus *) NULL);
  1587. X        if (key_symbol == XK_Control_L)
  1588. X          {
  1589. X            state|=ControlState;
  1590. X            break;
  1591. X          }
  1592. X        if (state & ControlState)
  1593. X          switch (key_symbol)
  1594. X          {
  1595. X            case XK_u:
  1596. X            case XK_U:
  1597. SHAR_EOF
  1598. true || echo 'restore of ImageMagick/X.c failed'
  1599. fi
  1600. echo 'End of ImageMagick part 11'
  1601. echo 'File ImageMagick/X.c is continued in part 12'
  1602. echo 12 > _shar_seq_.tmp
  1603. exit 0
  1604.  
  1605. exit 0 # Just in case...
  1606. -- 
  1607.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1608. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1609.  "It's intuitively obvious to the |
  1610.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1611.