home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / pexdraw / part04 < prev    next >
Encoding:
Text File  |  1993-06-07  |  60.6 KB  |  2,139 lines

  1. Newsgroups: comp.sources.x
  2. From: jch@okimicro.oki.com (Jan Hardenbergh)
  3. Subject: v20i014:  pexdraw - A PEX drawing program, Part04/14
  4. Message-ID: <1993Jun8.150059.18794@sparky.imd.sterling.com>
  5. X-Md4-Signature: ca092ed08086a9e179a05405d24ee4c1
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 8 Jun 1993 15:00:59 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: jch@okimicro.oki.com (Jan Hardenbergh)
  12. Posting-number: Volume 20, Issue 14
  13. Archive-name: pexdraw/part04
  14. Environment: X11R5, PEX
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  plcube.c util/pexutcmap.c
  21. # Wrapped by chris@sparky on Tue Jun  8 09:46:32 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 4 (of 14)."'
  25. if test -f 'plcube.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'plcube.c'\"
  27. else
  28.   echo shar: Extracting \"'plcube.c'\" \(12619 characters\)
  29.   sed "s/^X//" >'plcube.c' <<'END_OF_FILE'
  30. X#ifdef SCCS
  31. Xstatic char sccsid[]="@(#)plcube.c    1.2 Oki 93/05/25";
  32. X#endif
  33. X/*
  34. X * plcube.c - PEXlib / PEXIC Cube
  35. X   cc -o plcube plcube.c -lPEX5 -lm -lX11                    -lnsl
  36. X   
  37. X            Copyright (c) 1992, 1993 by 
  38. X            Oki Electric Industry Co., Ltd.
  39. X            All Rights Reserved
  40. X    
  41. X * Permission to use, copy, modify, and distribute this software and its
  42. X * documentation for any purpose and without fee is hereby granted,
  43. X * provided that the above copyright notice appear in all copies and that
  44. X * both that copyright notice and this permission notice appear in
  45. X * supporting documentation, and that the name of Oki not be
  46. X * used in advertising or publicity pertaining to distribution of the
  47. X * software without specific, written prior permission. Oki
  48. X * makes no representations about the suitability of this software for any
  49. X * purpose.  It is provided "as is" without express or implied warranty.
  50. X*/
  51. X/* 27-APR-93 made into structure stuffer - PEXlib version */
  52. X/* 12-MAY-92 debugged letters */
  53. X/* 17-JUN-91 trueblue.c - find true color visual for PEX testing */
  54. X/* 17-NOV-90 visual hacking */
  55. X
  56. X#define NeedFunctionPrototypes 1
  57. X
  58. X#include <X11/Xlib.h>
  59. X#include <X11/PEX5/PEXlib.h>
  60. X
  61. X#define SET_POINT(p,a,b,c) {(p)->x=(a);(p)->y=(b);(p)->z=(c);}
  62. X
  63. X#define RADIAN(x) ((x)*(3.1415927 / 180.0))
  64. X
  65. XPEXColorRGB red     = {1,0,0};
  66. XPEXColorRGB green   = {0,1,0};
  67. XPEXColorRGB blue    = {0,0,1};
  68. XPEXColorRGB cyan    = {0,1,1};
  69. XPEXColorRGB magenta = {1,0,1};
  70. XPEXColorRGB yellow  = {1,1,0};
  71. X
  72. XDisplay        *theDisplay;
  73. XPEXStructure     theStrux;
  74. X
  75. Xmain (argc, argv)
  76. X     int argc;
  77. X     char  *argv[];
  78. X{
  79. X  char            *displayString = (char *)0;
  80. X  PEXExtensionInfo    *info_return;
  81. X  char            err_msg[PEXErrorStringLength];
  82. X  int                   i;
  83. X  PEXCoord p[2];
  84. X  PEXCoord verts[30], *pts;
  85. X  PEXVector normals[30], *ns;
  86. X  PEXArrayOfFacetData fData;
  87. X  PEXArrayOfVertex vData;
  88. X
  89. X  PEXVector shift, scale;
  90. X  PEXMatrix bldmat;
  91. X  PEXCoord  pt;
  92. X  double x_ang, y_ang, z_ang;
  93. X
  94. X  for ( i = 1; i<argc; i++ ) {
  95. X    if ((strncmp(argv[i],"-display",strlen(argv[i]))) == 0) {
  96. X      if (++i > argc) { printf("not enough args"); exit(1); }
  97. X      displayString = argv[i];
  98. X    } else if ((strncmp(argv[i],"-strux",strlen(argv[i]))) == 0) {
  99. X      if (++i > argc) { printf("not enough args"); exit(1); }
  100. X      theStrux = atoi(argv[i]);
  101. X    }
  102. X  }
  103. X
  104. X  /*
  105. X   * Open the display and initialize the PEX extension.
  106. X   *  - this is a pexdraw structure stuffer, pexdraw creates a structure and
  107. X   *    uses the system call to execute this program.
  108. X   */
  109. X  
  110. X  if (!(theDisplay = XOpenDisplay(displayString)))
  111. X    {
  112. X      printf ( "Could not open display %s\n",displayString);
  113. X      exit (1);
  114. X    }
  115. X  
  116. X  if (PEXInitialize(theDisplay, &info_return, PEXErrorStringLength, err_msg))
  117. X    {
  118. X      printf ("%s\n", err_msg);
  119. X      exit (1);        
  120. X    }
  121. X
  122. X  /* need the line because we cannot select */
  123. X  PEXSetLineColorIndex( theDisplay, theStrux, PEXOCStore, 2);
  124. X  p[0].x = 0; p[0].y = 0; p[0].z = 0;
  125. X  p[1].x = -1; p[1].y = -1; p[1].z = -1;
  126. X  PEXPolyline(theDisplay, theStrux, PEXOCStore, 2, p );
  127. X
  128. X/*
  129. X * make a cube, use PEXlib to generate facet normals.
  130. X *
  131. X *                          ( )-----( )
  132. X *                           |     / |
  133. X *                           |   /   |
  134. X *                           | /     |
  135. X *  (4)-----(*)-----(8)-----(A)-----($)
  136. X *   | \     |     / |     / |     / |
  137. X *   |   \   |   /   |   /   |   /   |
  138. X *   |     \ | /     | /     | /     |
  139. X *  (2)-----(+)-----(9)-----(B)-----(*)
  140. X *   | \     |
  141. X *   |   \   |
  142. X *   |     \ |
  143. X *  (0)-----(1)
  144. X *
  145. X * * doubled point 5,6 13,14
  146. X * + points 3&7
  147. X */
  148. X
  149. X#define CUBE 0.4
  150. X
  151. X  pts = verts;
  152. X  ns = normals;
  153. X
  154. X  pts->x = 0.0;  pts->y = 0.0; pts->z = 0.0; pts++; /* 0 */
  155. X  pts->x = CUBE;  pts->y = 0.0; pts->z = 0.0; pts++;
  156. X  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++; /* 2 */
  157. X  pts->x = CUBE;  pts->y = CUBE; pts->z = 0.0; pts++;
  158. X  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++;
  159. X  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  160. X  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  161. X  pts->x = CUBE;  pts->y = CUBE; pts->z = 0.0; pts++;
  162. X  pts->x = CUBE;  pts->y = 0.0; pts->z = CUBE; pts++; /* 8 */
  163. X  pts->x = CUBE;  pts->y = 0.0; pts->z = 0.0; pts++; /* 9 == 1 */
  164. X  pts->x = 0.0;  pts->y = 0.0; pts->z = CUBE; pts++;
  165. X  pts->x = 0.0;  pts->y = 0.0; pts->z = 0.0; pts++; /* B == 0 */
  166. X  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  167. X  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++;
  168. X  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++;
  169. X  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  170. X  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  171. X  pts->x = 0.0;  pts->y = 0.0; pts->z = CUBE; pts++; /* A */
  172. X  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  173. X  pts->x = CUBE;  pts->y = 0.0; pts->z = CUBE; pts++;
  174. X
  175. X  fData.normal = normals;
  176. X  vData.no_data = verts;
  177. X
  178. X  PEXGeoNormTriangleStrip( PEXGANormal, PEXGANone, PEXColorTypeRGB, fData,
  179. X              20, vData );
  180. X  
  181. X  PEXTriangleStrip(  theDisplay, theStrux, PEXOCStore,
  182. X                     PEXGANormal, PEXGANone, PEXColorTypeRGB, fData,
  183. X                     20, vData );
  184. X
  185. X/*************************************************************************
  186. X * Cube is done, paste the letters on, start with the Red P.
  187. X */
  188. X    shift.x = 0.1;
  189. X    shift.y = 0.03;
  190. X    shift.z = 0.41;
  191. X    PEXTranslate( &shift, bldmat );
  192. X
  193. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  194. X                      PEXPreConcatenate, bldmat);
  195. X  PEXSetSurfaceColor(  theDisplay, theStrux, PEXOCStore,
  196. X                       PEXColorTypeRGB, (PEXColor *)&red );
  197. X  PutP();
  198. X
  199. X/* Green E */
  200. X
  201. X    pt.x = 0.0;
  202. X    pt.y = 0.0;
  203. X    pt.z = 0.0;
  204. X    shift.x = 0;
  205. X    shift.y = -0.04; /* controls distance to face of cube */
  206. X    shift.z = -0.37; 
  207. X    scale.x = 1.0;
  208. X    scale.y = 1.0;
  209. X    scale.z = 1.0;
  210. X    x_ang = RADIAN(90);
  211. X    y_ang = 0;
  212. X    z_ang = 0;
  213. X    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);
  214. X
  215. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  216. X                      PEXPreConcatenate, bldmat);
  217. X  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore,
  218. X                      PEXColorTypeRGB, (PEXColor *)&green );  
  219. X  PutE();
  220. X
  221. X/* Blue X */
  222. X
  223. X    pt.x = 0.0;
  224. X    pt.y = 0.0;
  225. X    pt.z = 0.0;
  226. X    shift.x = 0.31; /* controls distance to face of cube */
  227. X    shift.y = 0.0;  /* .37 - y from E */
  228. X    shift.z = -0.07;
  229. X    scale.x = 1.0;
  230. X    scale.y = 1.0;
  231. X    scale.z = 1.0;
  232. X    x_ang = 0;
  233. X    y_ang = RADIAN(90);
  234. X    z_ang = 0;
  235. X    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);
  236. X
  237. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  238. X                      PEXPreConcatenate, bldmat);
  239. X  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
  240. X                      PEXColorTypeRGB, (PEXColor *)&blue );
  241. X  PutX();
  242. X
  243. X/* cyan P for the opposite side */
  244. X
  245. X    pt.x = 0;
  246. X    pt.y = 0;
  247. X    pt.z = 0;
  248. X    shift.x = CUBE - 0.08;
  249. X    shift.y = -0.05;  /* distance to face of cube */
  250. X    shift.z = -0.33;  /* controls X */
  251. X    scale.x = 1.0;
  252. X    scale.y = 1.0;
  253. X    scale.z = 1.0;
  254. X    x_ang = RADIAN(90);
  255. X    y_ang = -RADIAN(90);
  256. X    z_ang = 0;
  257. X
  258. X  PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);
  259. X
  260. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  261. X                      PEXPreConcatenate, bldmat);
  262. X  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
  263. X                      PEXColorTypeRGB, (PEXColor *)&cyan );
  264. X  PutP();
  265. X
  266. X/* magenta E */
  267. X
  268. X    pt.x = 0.0;
  269. X    pt.y = 0.0;
  270. X    pt.z = 0.0;
  271. X    shift.x = 0;
  272. X    shift.y = -0.04; /* controls distance to face of cube */
  273. X    shift.z = -0.37; 
  274. X    scale.x = 1.0;
  275. X    scale.y = 1.0;
  276. X    scale.z = 1.0;
  277. X    x_ang = RADIAN(90);
  278. X    y_ang = 0;
  279. X    z_ang = 0;
  280. X    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);
  281. X
  282. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  283. X                      PEXPreConcatenate, bldmat);
  284. X  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore,
  285. X                      PEXColorTypeRGB, (PEXColor *)&magenta );  
  286. X  PutE();
  287. X
  288. X/* Finally, a Yellow X */
  289. X
  290. X    pt.x = 0.0;
  291. X    pt.y = 0.0;
  292. X    pt.z = 0.0;
  293. X    shift.x = -0.1; /* controls distance to face of cube */
  294. X    shift.y = 0.0;  /* .37 - y from E */
  295. X    shift.z = -0.1;
  296. X    scale.x = 1.0;
  297. X    scale.y = 1.0;
  298. X    scale.z = 1.0;
  299. X    x_ang = 0;
  300. X    y_ang = RADIAN(90);
  301. X    z_ang = 0;
  302. X    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);
  303. X
  304. X  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
  305. X                      PEXPreConcatenate, bldmat);
  306. X  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
  307. X                      PEXColorTypeRGB, (PEXColor *)&yellow );
  308. X  PutX();
  309. X  XSync(theDisplay,0);  /* Must Sync to force this stuff out be fore we exit */
  310. X}
  311. X
  312. X/*************************************************************************
  313. X * The P polygon, with the lower gap closed to match the PEX cube.
  314. X *  Followed by the E and X. The "facedness" of all of these needs to
  315. X *  be touched up.
  316. X */
  317. XPutP()
  318. X{
  319. X  PEXCoord points[30], *pts;
  320. X
  321. X  pts = points;
  322. X
  323. X  pts->x = 0.0;  pts->y = 0.02; pts->z = 0.0; pts++;
  324. X  pts->x = 0.0;  pts->y = 0.19; pts->z = 0.0; pts++;
  325. X  pts->x = 0.11;  pts->y = 0.19; pts->z = 0.0; pts++;
  326. X  pts->x = 0.14;  pts->y = 0.20; pts->z = 0.0; pts++;
  327. X  pts->x = 0.16;  pts->y = 0.21; pts->z = 0.0; pts++;
  328. X  pts->x = 0.17;  pts->y = 0.23; pts->z = 0.0; pts++;
  329. X  pts->x = 0.17;  pts->y = 0.26; pts->z = 0.0; pts++;
  330. X  pts->x = 0.16;  pts->y = 0.28; pts->z = 0.0; pts++;
  331. X  pts->x = 0.14;  pts->y = 0.29; pts->z = 0.0; pts++;
  332. X  pts->x = 0.11;  pts->y = 0.30; pts->z = 0.0; pts++;
  333. X  pts->x = 0.06;  pts->y = 0.30; pts->z = 0.0; pts++;
  334. X  pts->x = 0.06;  pts->y = 0.21; pts->z = 0.0; pts++;
  335. X  pts->x = 0.0;  pts->y = 0.21; pts->z = 0.0; pts++;
  336. X  pts->x = 0.0;  pts->y = 0.32; pts->z = 0.0; pts++;
  337. X  pts->x = 0.14;  pts->y = 0.32; pts->z = 0.0; pts++;
  338. X  pts->x = 0.18;  pts->y = 0.31; pts->z = 0.0; pts++;
  339. X  pts->x = 0.20;  pts->y = 0.30; pts->z = 0.0; pts++;
  340. X  pts->x = 0.22;  pts->y = 0.28; pts->z = 0.0; pts++;
  341. X  pts->x = 0.23;  pts->y = 0.26; pts->z = 0.0; pts++;
  342. X  pts->x = 0.23;  pts->y = 0.23; pts->z = 0.0; pts++;
  343. X  pts->x = 0.22;  pts->y = 0.21; pts->z = 0.0; pts++;
  344. X  pts->x = 0.20;  pts->y = 0.19; pts->z = 0.0; pts++;
  345. X  pts->x = 0.18;  pts->y = 0.18; pts->z = 0.0; pts++;
  346. X  pts->x = 0.14;  pts->y = 0.17; pts->z = 0.0; pts++;
  347. X  pts->x = 0.06;  pts->y = 0.17; pts->z = 0.0; pts++;
  348. X  pts->x = 0.06;  pts->y = 0.02; pts->z = 0.0; pts++;
  349. X  pts->x = 0.0;  pts->y = 0.02; pts->z = 0.0; pts++;
  350. X
  351. X  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
  352. X                PEXShapeComplex, True, 27, points );
  353. X}
  354. X
  355. XPutE()
  356. X{
  357. X  PEXCoord points[30], *pts;
  358. X
  359. X  pts = points;
  360. X
  361. X  pts->x = 0.0; pts->y = 0.02; pts->z = 0; pts++;
  362. X  pts->x = 0.0; pts->y = 0.19; pts->z = 0; pts++;
  363. X  pts->x = 0.21; pts->y = 0.19; pts->z = 0; pts++;
  364. X  pts->x = 0.21; pts->y = 0.17; pts->z = 0; pts++;
  365. X  pts->x = 0.06; pts->y = 0.17; pts->z = 0; pts++;
  366. X  pts->x = 0.06; pts->y = 0.04; pts->z = 0; pts++;
  367. X  pts->x = 0.21; pts->y = 0.04; pts->z = 0; pts++;
  368. X  pts->x = 0.21; pts->y = 0.02; pts->z = 0; pts++;
  369. X  pts->x = 0.0; pts->y = 0.02; pts->z = 0; pts++;
  370. X
  371. X  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
  372. X                PEXShapeComplex, True, 9, points );
  373. X
  374. X  pts = points;
  375. X
  376. X  pts->x = 0.0; pts->y = 0.21; pts->z = 0; pts++;
  377. X  pts->x = 0.0; pts->y = 0.32; pts->z = 0; pts++;
  378. X  pts->x = 0.21; pts->y = 0.32; pts->z = 0; pts++;
  379. X  pts->x = 0.21; pts->y = 0.30; pts->z = 0; pts++;
  380. X  pts->x = 0.06; pts->y = 0.30; pts->z = 0; pts++;
  381. X  pts->x = 0.06; pts->y = 0.21; pts->z = 0; pts++;
  382. X  pts->x = 0.0; pts->y = 0.21; pts->z = 0; pts++;
  383. X
  384. X  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
  385. X                PEXShapeComplex, True, 7, points );
  386. X}
  387. X
  388. XPutX()
  389. X{
  390. X  PEXCoord points[30], *pts;
  391. X
  392. X  pts = points;
  393. X
  394. X pts->x = 0.00;  pts->y = 0.02; pts->z = 0.0; pts++;
  395. X pts->x = 0.10;  pts->y = 0.17; pts->z = 0.0; pts++;
  396. X pts->x = 0.00;  pts->y = 0.32; pts->z = 0.0; pts++;
  397. X pts->x = 0.06;  pts->y = 0.32; pts->z = 0.0; pts++;
  398. X pts->x = 0.14;  pts->y = 0.20; pts->z = 0.0; pts++;
  399. X pts->x = 0.02;  pts->y = 0.02; pts->z = 0.0; pts++;
  400. X pts->x = 0.00;  pts->y = 0.02; pts->z = 0.0; pts++;
  401. X
  402. X  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
  403. X                PEXShapeComplex, True, 7, points );
  404. X  pts = points;
  405. X
  406. X pts->x = 0.20;  pts->y = 0.02; pts->z = 0.0; pts++;
  407. X pts->x = 0.12;  pts->y = 0.14; pts->z = 0.0; pts++;
  408. X pts->x = 0.24;  pts->y = 0.32; pts->z = 0.0; pts++;
  409. X pts->x = 0.26;  pts->y = 0.32; pts->z = 0.0; pts++;
  410. X pts->x = 0.16;  pts->y = 0.17; pts->z = 0.0; pts++;
  411. X pts->x = 0.26;  pts->y = 0.02; pts->z = 0.0; pts++;
  412. X pts->x = 0.20;  pts->y = 0.02; pts->z = 0.0; pts++;
  413. X
  414. X  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
  415. X                PEXShapeComplex, True, 7, points );
  416. X}
  417. X
  418. END_OF_FILE
  419.   if test 12619 -ne `wc -c <'plcube.c'`; then
  420.     echo shar: \"'plcube.c'\" unpacked with wrong size!
  421.   fi
  422.   # end of 'plcube.c'
  423. fi
  424. if test -f 'util/pexutcmap.c' -a "${1}" != "-c" ; then 
  425.   echo shar: Will not clobber existing file \"'util/pexutcmap.c'\"
  426. else
  427.   echo shar: Extracting \"'util/pexutcmap.c'\" \(44664 characters\)
  428.   sed "s/^X//" >'util/pexutcmap.c' <<'END_OF_FILE'
  429. X/******************************************************************************/
  430. X/*                                                                            */
  431. X/*  (c) Copyright Hewlett-Packard Company, 1992, Fort Collins, Colorado       */
  432. X/*                                                                            */
  433. X/*                            All Rights Reserved                             */
  434. X/*                                                                            */
  435. X/*  Permission to use, copy, modify, and distribute this software and its     */
  436. X/*  documentation for any purpose and without fee is hereby granted,          */
  437. X/*  provided that the above copyright notices appear in all copies and that   */
  438. X/*  both the copyright notices and this permission notice appear in           */
  439. X/*  supporting documentation, and that the name of Hewlett-Packard not be     */
  440. X/*  used in advertising or publicity pertaining to distribution of the        */
  441. X/*  software without specific, written prior permission.                      */
  442. X/*                                                                            */
  443. X/*  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS         */
  444. X/*  SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
  445. X/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Hewlett-Packard    */
  446. X/*  shall not be liable for errors contained herein or direct, indirect,      */
  447. X/*  special, incidental or consequential damages in connection with the       */
  448. X/*  furnishing, performance or use of this software.                          */
  449. X/*                                                                            */
  450. X/******************************************************************************/
  451. X
  452. X/******************************************************************************/
  453. X/*                                                                            */
  454. X/* $Source: /users/waitz/work/tmp/RCS/pexutcmap.c,v $                            */
  455. X/* $Date: 93/04/01 13:31:17 $                                                 */
  456. X/* $Revision: 1.3 $                                                   */
  457. X/*                                                                            */
  458. X/* Description:                                                               */
  459. X/*   Main interface implementation file for PEXUt colormap/visual utilities.  */
  460. X/*                                                                            */
  461. X/* Notes:                                                                     */
  462. X/*                                                                            */
  463. X/******************************************************************************/
  464. X
  465. X
  466. X#include <math.h>
  467. X#include <stdio.h>
  468. X#include <stdlib.h>
  469. X
  470. X#include <X11/Xlib.h>
  471. X#include <X11/Xutil.h>
  472. X#include <X11/Xatom.h>
  473. X#include <X11/PEX5/PEXlib.h>
  474. X#include "pexutext.h"
  475. X
  476. X#include "pexutcmap.h"
  477. X#include "pexutcmapint.h"
  478. X#include "pexutcmaphp.h"
  479. X
  480. X
  481. X/*
  482. X    This structure describes each of the standard colormap 
  483. X    properties to be searched when choosing a Visual, in
  484. X    priority order.  Changing the interoperability convention
  485. X    should be a simple matter of adding or shuffling these entries.
  486. X*/
  487. X
  488. Xstatic interop_property_type interop_properties[]={
  489. X    { True, True, XA_RGB_BEST_MAP, "" },
  490. X    { True, True, XA_RGB_DEFAULT_MAP, "" },
  491. X};
  492. X
  493. X#define NUM_INTEROP_PROPERTIES \
  494. X    (sizeof(interop_properties)/sizeof(interop_property_type))
  495. X
  496. X
  497. X
  498. X
  499. Xint PEXUtFindVisual (
  500. X        display,
  501. X        screen,
  502. X        criteria,
  503. X        vis_info_return,
  504. X        cmap_info_return,
  505. X        capx_info_return,
  506. X        unmet_criteria_return,
  507. X        std_prop_atom_return
  508. X        )
  509. X
  510. X        Display                *display;
  511. X        int                screen;
  512. X        PEXUtVisualCriteria        *criteria;
  513. X        XVisualInfo            *vis_info_return;
  514. X        XStandardColormap        *cmap_info_return;
  515. X        PEXColorApproxEntry        *capx_info_return;
  516. X        unsigned int            *unmet_criteria_return;
  517. X        Atom                *std_prop_atom_return;
  518. X
  519. X/*
  520. X    Algorithm:
  521. X
  522. X    Section I:        Initialize and process input criteria masks.
  523. X
  524. X    Section II:       Fetch information from the server.
  525. X
  526. X    Section III:      Build information blocks about all the Visuals
  527. X            that are supported by PEX.
  528. X
  529. X    Section IV:    Evaluate candidates (Visuals that meet hard criteria).
  530. X
  531. X    Section V:    Copy or generate return information.
  532. X*/
  533. X{
  534. X    PEXUtVisualCriteria    local_criteria;
  535. X
  536. X    PEXExtensionInfo    *ext_info;
  537. X    int            target_depth;
  538. X    unsigned long        target_count = 0;
  539. X    PEXRenderingTarget    *targets = NULL;
  540. X
  541. X    XVisualInfo           vis_template;
  542. X    unsigned int          vis_mask;
  543. X    int            visual_count = 0;
  544. X    XVisualInfo        *visuals = NULL;
  545. X
  546. X    int            property_counts[NUM_INTEROP_PROPERTIES];
  547. X    Atom            property_atoms[NUM_INTEROP_PROPERTIES];
  548. X    XStandardColormap    *property_data[NUM_INTEROP_PROPERTIES];
  549. X
  550. X    int            overlay_count = 0;
  551. X    overlay_visuals_type    *overlay_data = NULL;
  552. X
  553. X    int            visual_info_count = 0;
  554. X    visual_info_type    *visual_info = NULL;
  555. X    visual_info_type    *p_info; 
  556. X
  557. X    int            met_hard_count;
  558. X    int            min_unmet_criteria_count;
  559. X    int            soft_criteria_count;
  560. X    int            supported_visual_count;
  561. X    visual_info_type    *p_chosen_info, *p_min_unmet;
  562. X
  563. X    int            visual_index;
  564. X    int            target_index;
  565. X    int            prop_index;
  566. X    int            entry_index;
  567. X
  568. X    int            result;
  569. X    int            color_approx_type;
  570. X
  571. X
  572. X    /*
  573. X        This macro is used to clean up in case of an early exit.
  574. X    */
  575. X#define FREE_ALLOCATED_RESOURCES {                    \
  576. X        int i;                            \
  577. X        if (target_count) XFree (targets);                \
  578. X        if (visual_count > 0) XFree (visuals);            \
  579. X        for (i=0; i<NUM_INTEROP_PROPERTIES; i++)            \
  580. X        if (property_counts[i] > 0) XFree (property_data[i]);    \
  581. X        if (overlay_count > 0) XFree (overlay_data);        \
  582. X        if (visual_info_count > 0) free (visual_info);        \
  583. X    }
  584. X
  585. X
  586. X    /*
  587. X    -----------------------------------------------------------------------
  588. X    Section I:        Initialize and process input criteria masks.
  589. X    -----------------------------------------------------------------------
  590. X    */
  591. X
  592. X    /*
  593. X        Initialize property data arrays to empty.
  594. X    */
  595. X
  596. X    for (prop_index=0; prop_index<NUM_INTEROP_PROPERTIES; prop_index++) {
  597. X
  598. X        property_counts[prop_index] = 0;
  599. X        property_data[prop_index] = NULL;
  600. X        property_atoms[prop_index] = None;
  601. X    }
  602. X
  603. X
  604. X    /*
  605. X        Copy the caller's criteria structure and clean up the masks
  606. X        (eliminate unsupported bits and overlaps).
  607. X    */
  608. X
  609. X    local_criteria = *criteria;
  610. X    local_criteria.hard_criteria_mask &= PEXUtAllCriteria;
  611. X    local_criteria.soft_criteria_mask &= PEXUtAllCriteria;
  612. X    local_criteria.soft_criteria_mask &= ~(local_criteria.hard_criteria_mask);
  613. X
  614. X    /*
  615. X    -----------------------------------------------------------------------
  616. X    Section II:       Fetch information from the server.
  617. X    -----------------------------------------------------------------------
  618. X    */
  619. X
  620. X    /*
  621. X        Get PEX extension info.
  622. X    */
  623. X
  624. X    if (NULL == (ext_info = PEXGetExtensionInfo (display)))
  625. X        return PEXUtPEXFailure;
  626. X
  627. X
  628. X    /*
  629. X        Get list of supported targets from PEX.
  630. X        If depth is specified as a hard criterion, use it as a filter.
  631. X    */
  632. X
  633. X    if ((ext_info->major_version == 5) &&
  634. X        (ext_info->minor_version >= 1)) {
  635. X
  636. X        if (local_criteria.hard_criteria_mask & PEXUtDepth)
  637. X        target_depth = local_criteria.depth;
  638. X        else
  639. X        target_depth = 0;
  640. X
  641. X        if (! PEXMatchRenderingTargets (display, 
  642. X                    RootWindow(display, screen),
  643. X                    target_depth, PEXWindowDrawable, NULL,
  644. X                    32, &target_count, &targets)) {
  645. X        FREE_ALLOCATED_RESOURCES
  646. X        return PEXUtPEXFailure;
  647. X        }
  648. X
  649. X        if (target_count == 0) {
  650. X        FREE_ALLOCATED_RESOURCES
  651. X        *unmet_criteria_return = local_criteria.hard_criteria_mask
  652. X                    | local_criteria.soft_criteria_mask;
  653. X        return PEXUtCriteriaFailure;
  654. X        }
  655. X    }
  656. X
  657. X
  658. X    /*
  659. X        Get list of visuals for the screen.
  660. X        If depth and/or visual class are specified as hard criteria, 
  661. X        use them as filters.
  662. X    */
  663. X
  664. X    vis_template.screen = screen;
  665. X    vis_mask = VisualScreenMask;
  666. X
  667. X    if (local_criteria.hard_criteria_mask & PEXUtDepth) {
  668. X        vis_template.depth = local_criteria.depth;
  669. X        vis_mask |= VisualDepthMask;
  670. X    }
  671. X
  672. X    if (local_criteria.hard_criteria_mask & PEXUtVisualClass) {
  673. X        vis_template.class = local_criteria.visual_class;
  674. X        vis_mask |= VisualClassMask;
  675. X    }
  676. X
  677. X    if (NULL == (visuals = XGetVisualInfo (display, vis_mask, &vis_template,
  678. X                        &visual_count))) {
  679. X        FREE_ALLOCATED_RESOURCES
  680. X        return PEXUtXFailure;
  681. X    }
  682. X
  683. X
  684. X    /*
  685. X        For each property in the list of properties specified by
  686. X        the interoperability conventions, get the value of the property.
  687. X    */
  688. X    if ((PEXUtStandardColormapProperty|PEXUtSharableColormap) &
  689. X        (local_criteria.hard_criteria_mask | 
  690. X        local_criteria.soft_criteria_mask)) {
  691. X
  692. X        for (prop_index=0; 
  693. X        prop_index<NUM_INTEROP_PROPERTIES; 
  694. X        prop_index++) {
  695. X
  696. X        result = pexut_get_standard_cmap_property (display, screen, 
  697. X                    &(interop_properties[prop_index]),
  698. X                    &(property_atoms[prop_index]), 
  699. X                    &(property_counts[prop_index]), 
  700. X                    &(property_data[prop_index]));
  701. X        if (result != PEXUtSuccess) {
  702. X            FREE_ALLOCATED_RESOURCES
  703. X            return PEXUtXFailure;
  704. X        }
  705. X        }
  706. X    }
  707. X
  708. X
  709. X    /*
  710. X        Get the value of the SERVER_OVERLAY_VISUALS property, if supported.
  711. X    */
  712. X
  713. X    if (PEXUtLayer &
  714. X        (local_criteria.hard_criteria_mask | 
  715. X        local_criteria.soft_criteria_mask)) {
  716. X
  717. X        result = pexut_get_overlay_visuals_property (display, screen, 
  718. X                        &overlay_count, &overlay_data);
  719. X        if (result != PEXUtSuccess) {
  720. X        FREE_ALLOCATED_RESOURCES
  721. X        return PEXUtXFailure;
  722. X        }
  723. X    }
  724. X    
  725. X
  726. X    /*
  727. X    -----------------------------------------------------------------------
  728. X    Section III:      Build information blocks about all the Visuals
  729. X            that are supported by PEX.
  730. X    -----------------------------------------------------------------------
  731. X    */
  732. X
  733. X    /*
  734. X        Allocate information blocks for all visuals.  (Could filter here
  735. X        and only allocate space for visuals listed in target data, but
  736. X        might take longer than just allocating space for all visuals.)
  737. X    */
  738. X
  739. X    visual_info_count = visual_count;
  740. X    visual_info = (visual_info_type *) 
  741. X            malloc (visual_info_count * sizeof(visual_info_type));
  742. X
  743. X    if (visual_info == NULL) {
  744. X        visual_info_count = 0;
  745. X        FREE_ALLOCATED_RESOURCES
  746. X        return PEXUtAllocFailure;
  747. X    }
  748. X
  749. X
  750. X    /*
  751. X        For the remaining visuals, build an information structure
  752. X        for each one.  Keep track of how well each one meets the
  753. X        hard and soft criteria.  
  754. X
  755. X        Count the number that meet all the hard criteria.
  756. X    */
  757. X
  758. X    met_hard_count = 0;
  759. X    p_chosen_info = NULL;
  760. X
  761. X    min_unmet_criteria_count = 999;
  762. X    p_min_unmet = NULL;
  763. X    soft_criteria_count = 
  764. X        pexut_count_bits_in_mask (local_criteria.soft_criteria_mask);
  765. X
  766. X    p_info = visual_info;
  767. X    supported_visual_count = 0;
  768. X    for (visual_index=0; visual_index<visual_count; visual_index++) {
  769. X
  770. X        int found;
  771. X        int supported;
  772. X        unsigned int order_rating;
  773. X        float temp;
  774. X        int unmet_criteria_count;
  775. X
  776. X
  777. X        /*
  778. X        If we have target data, determine support for the Visual from 
  779. X        that data.  Assign a rating based on the relative position in 
  780. X        the target data.
  781. X
  782. X        Otherwise, assume support.
  783. X        */
  784. X
  785. X        order_rating = 0;
  786. X
  787. X        if (target_count) {
  788. X        supported = False;
  789. X        for (target_index=0; 
  790. X            target_index<target_count; 
  791. X            target_index++) {
  792. X
  793. X            if (visuals[visual_index].visualid == 
  794. X            XVisualIDFromVisual (targets[target_index].visual)) {
  795. X            supported = True;
  796. X            break;
  797. X            }
  798. X        }
  799. X        }
  800. X        else
  801. X        supported = True;
  802. X
  803. X        if (supported) {
  804. X
  805. X        p_info->unmet_hard_criteria = 0;
  806. X        p_info->unmet_soft_criteria = 0;
  807. X        p_info->order_rating = order_rating;
  808. X
  809. X
  810. X        /*
  811. X            Search the colormap properties for the first match with 
  812. X            the visual.  The property data is used in evaluating color 
  813. X            criteria as well as the standard colormap property 
  814. X            criterion.
  815. X
  816. X            If we get property data, and we did not have target data 
  817. X            from which to give an order rating, then give a rating 
  818. X            depending on the relative position of the property entry, 
  819. X            including the possibility of a search
  820. X            process that involves more than one property.
  821. X        */
  822. X
  823. X        p_info->property_ptr = NULL;
  824. X        p_info->property_atom = None;
  825. X
  826. X        if ((PEXUtStandardColormapProperty|PEXUtSharableColormap) &
  827. X            (local_criteria.hard_criteria_mask | 
  828. X            local_criteria.soft_criteria_mask)) {
  829. X
  830. X            found = False;
  831. X            for (prop_index=0; 
  832. X            prop_index<NUM_INTEROP_PROPERTIES; 
  833. X            prop_index++) {
  834. X
  835. X            for (entry_index=0; 
  836. X                entry_index < property_counts[prop_index]; 
  837. X                entry_index++) {
  838. X
  839. X                if (property_data[prop_index][entry_index].visualid
  840. X                == visuals[visual_index].visualid) {
  841. X
  842. X                found = True;
  843. X                p_info->property_ptr = 
  844. X                    &(property_data[prop_index][entry_index]);
  845. X                p_info->property_atom = 
  846. X                    property_atoms[prop_index];
  847. X                break;
  848. X                }
  849. X            }
  850. X            if (found) break;
  851. X            }
  852. X
  853. X            if ((PEXUtStandardColormapProperty &
  854. X            (local_criteria.hard_criteria_mask | 
  855. X            local_criteria.soft_criteria_mask)) &&
  856. X            (found != local_criteria.standard_colormap_property)) {
  857. X            p_info->unmet_hard_criteria |= 
  858. X                (local_criteria.hard_criteria_mask 
  859. X                & PEXUtStandardColormapProperty);
  860. X            p_info->unmet_soft_criteria |= 
  861. X                (local_criteria.soft_criteria_mask 
  862. X                & PEXUtStandardColormapProperty);
  863. X            }
  864. X        }
  865. X
  866. X        /*
  867. X            Depth is not currently used for any rating.
  868. X        */
  869. X
  870. X        if (PEXUtDepth &
  871. X            (local_criteria.hard_criteria_mask | 
  872. X            local_criteria.soft_criteria_mask)) {
  873. X
  874. X            if (visuals[visual_index].depth != local_criteria.depth) {
  875. X            p_info->unmet_hard_criteria |= 
  876. X                (local_criteria.hard_criteria_mask & PEXUtDepth);
  877. X            p_info->unmet_soft_criteria |= 
  878. X                (local_criteria.soft_criteria_mask & PEXUtDepth);
  879. X            }
  880. X        }
  881. X
  882. X        /*
  883. X            Color criteria are complicated, since they interact with 
  884. X            property information.  This procedure not only evaluates 
  885. X            whether or not criteria are met, but also assigns a rating 
  886. X            based on available color resolution and the 
  887. X            sharable_colormap criterion.
  888. X        */
  889. X
  890. X        result = pexut_evaluate_color_criteria (display, 
  891. X            &local_criteria, &(visuals[visual_index]), p_info);
  892. X        if (result != PEXUtSuccess) {
  893. X            FREE_ALLOCATED_RESOURCES
  894. X            return result;
  895. X        }
  896. X
  897. X        if (PEXUtVisualClass &
  898. X            (local_criteria.hard_criteria_mask | 
  899. X            local_criteria.soft_criteria_mask)) {
  900. X
  901. X            if (visuals[visual_index].class != 
  902. X            local_criteria.visual_class) {
  903. X
  904. X            p_info->unmet_hard_criteria |= 
  905. X                (local_criteria.hard_criteria_mask 
  906. X                & PEXUtVisualClass);
  907. X            p_info->unmet_soft_criteria |= 
  908. X                (local_criteria.soft_criteria_mask 
  909. X                & PEXUtVisualClass);
  910. X            }
  911. X        }
  912. X
  913. X        /*
  914. X            The Visual class is always a factor in rating:
  915. X            static Visuals are preferred over dynamic Visuals,
  916. X            all else being equal.
  917. X        */
  918. X
  919. X        if ((visuals[visual_index].class == TrueColor) ||
  920. X            (visuals[visual_index].class == StaticColor) ||
  921. X            (visuals[visual_index].class == StaticGray))
  922. X            p_info->class_rating = MAX_CLASS_RATING;
  923. X        else
  924. X            p_info->class_rating = 0;
  925. X
  926. X        /*
  927. X            Layer is not currently used for any rating.
  928. X        */
  929. X
  930. X        if (PEXUtLayer &
  931. X            (local_criteria.hard_criteria_mask | 
  932. X            local_criteria.soft_criteria_mask)) {
  933. X
  934. X            found = False;
  935. X            for (prop_index=0; 
  936. X            prop_index < overlay_count; 
  937. X            prop_index++) {
  938. X
  939. X            if (overlay_data[prop_index].visualid == 
  940. X                visuals[visual_index].visualid) {
  941. X                found = True;
  942. X                break;
  943. X            }
  944. X            }
  945. X
  946. X            if ((!found) || 
  947. X            (((overlay_data[prop_index].layer == 1)? 
  948. X                PEXUtOverlay:PEXUtImage)
  949. X                != local_criteria.layer)) {
  950. X            p_info->unmet_hard_criteria |= 
  951. X                (local_criteria.hard_criteria_mask & PEXUtLayer);
  952. X            p_info->unmet_soft_criteria |= 
  953. X                (local_criteria.soft_criteria_mask & PEXUtLayer);
  954. X            }
  955. X        }
  956. X
  957. X        /*
  958. X            Determining double-buffering capability is a complicated 
  959. X            affair.  This procedure attempts to assess whether 
  960. X            criteria are met and assign a rating.
  961. X        */
  962. X
  963. X        result = pexut_evaluate_double_buffering_capability (display, 
  964. X                &local_criteria, &(visuals[visual_index]), p_info);
  965. X        if (result != PEXUtSuccess) {
  966. X            FREE_ALLOCATED_RESOURCES
  967. X            return result;
  968. X        }
  969. X
  970. X        /*
  971. X            Determining support for color approximation types is 
  972. X            straightforward but is done in a subprocedure in order 
  973. X            to centralize it.  This procedure attempts to assess 
  974. X            whether criteria are met and assign a rating.
  975. X        */
  976. X
  977. X        result = pexut_evaluate_color_approx_type (display, 
  978. X                &local_criteria, &(visuals[visual_index]), p_info);
  979. X        if (result != PEXUtSuccess) {
  980. X            FREE_ALLOCATED_RESOURCES
  981. X            return result;
  982. X        }
  983. X
  984. X
  985. X        /*
  986. X            At this point, all the criteria have been evaluated for 
  987. X            this Visual.  If it met all the hard criteria, it is a 
  988. X            candidate for success, and we give a rating based on how 
  989. X            many soft criteria have also been met.  We keep a pointer 
  990. X            to the last Visual that met all hard criteria, so we
  991. X            can avoid some work if there turns out to be only one.
  992. X
  993. X            If not, we still keep track of the Visual that came 
  994. X            closest to meeting all the hard criteria.
  995. X        */
  996. X
  997. X        if (p_info->unmet_hard_criteria == 0) {
  998. X            met_hard_count++;
  999. X
  1000. X            p_info->visual_ptr = &(visuals[visual_index]);
  1001. X            p_chosen_info = p_info;
  1002. X
  1003. X            if (soft_criteria_count) {
  1004. X            unmet_criteria_count = 
  1005. X             pexut_count_bits_in_mask (p_info->unmet_soft_criteria);
  1006. X            p_info->soft_rating = (int) 
  1007. X                        ((((float) (soft_criteria_count 
  1008. X                              - unmet_criteria_count))
  1009. X                         /((float) soft_criteria_count))
  1010. X                        * MAX_SOFT_RATING);
  1011. X            }
  1012. X            else
  1013. X            p_info->soft_rating = 0;
  1014. X        }
  1015. X        else {
  1016. X            unmet_criteria_count = 
  1017. X            pexut_count_bits_in_mask (p_info->unmet_hard_criteria);
  1018. X
  1019. X            if (unmet_criteria_count < min_unmet_criteria_count) {
  1020. X            min_unmet_criteria_count = unmet_criteria_count;
  1021. X            p_min_unmet = p_info;
  1022. X            }
  1023. X        }
  1024. X
  1025. X        p_info++;
  1026. X        supported_visual_count++;
  1027. X        }
  1028. X    }
  1029. X
  1030. X
  1031. X    /*
  1032. X    -----------------------------------------------------------------------
  1033. X    Section IV:    Evaluate candidates (Visuals that meet hard criteria).
  1034. X    -----------------------------------------------------------------------
  1035. X    */
  1036. X
  1037. X    /*
  1038. X        If no Visual has met the hard criteria, we have failed.
  1039. X        We will return the criteria information for the Visual that 
  1040. X        came closest to being accepted.
  1041. X    */
  1042. X
  1043. X    if (met_hard_count == 0) {
  1044. X
  1045. X        *unmet_criteria_return = p_min_unmet->unmet_hard_criteria |
  1046. X                     p_min_unmet->unmet_soft_criteria;
  1047. X        FREE_ALLOCATED_RESOURCES
  1048. X        return PEXUtCriteriaFailure;
  1049. X    }
  1050. X
  1051. X
  1052. X    /*
  1053. X        If more than one Visual has met the hard criteria, make a pass 
  1054. X        to choose the best one.  
  1055. X    */
  1056. X
  1057. X    if (met_hard_count > 1) {
  1058. X
  1059. X        unsigned int overall_rating;
  1060. X        unsigned int max_rating = 0;
  1061. X
  1062. X        p_info = visual_info;
  1063. X        p_chosen_info = p_info;
  1064. X        for (visual_index=0; 
  1065. X        visual_index<supported_visual_count; 
  1066. X        visual_index++) {
  1067. X
  1068. X        if (p_info->unmet_hard_criteria == 0) {
  1069. X
  1070. X            overall_rating = pexut_compute_overall_rating (p_info);
  1071. X            if (overall_rating > max_rating) {
  1072. X            max_rating = overall_rating;
  1073. X            p_chosen_info = p_info;
  1074. X            }
  1075. X        }
  1076. X
  1077. X        p_info++;
  1078. X        }
  1079. X    }
  1080. X
  1081. X
  1082. X    /*
  1083. X    -----------------------------------------------------------------------
  1084. X    Section V:    Copy or generate return information.
  1085. X    -----------------------------------------------------------------------
  1086. X    */
  1087. X
  1088. X    /*
  1089. X        If we have chosen a Visual, and we've got standard colormap 
  1090. X        information, and the caller requested it, we'll return that 
  1091. X        and the atom for the property.
  1092. X
  1093. X        If we have chosen a Visual, but we don't have standard colormap
  1094. X        information yet, then synthesize the info from the visual.
  1095. X        This is just an "educated" guess at what kind of color ramp
  1096. X        might be supported by PEX on the visual.
  1097. X    */
  1098. X
  1099. X    if (((PEXUtStandardColormapProperty|PEXUtSharableColormap) &
  1100. X        (local_criteria.hard_criteria_mask | 
  1101. X        local_criteria.soft_criteria_mask)) &&
  1102. X        (local_criteria.standard_colormap_property || 
  1103. X        local_criteria.sharable_colormap) &&
  1104. X        (p_chosen_info->property_ptr != NULL)) {
  1105. X
  1106. X        *cmap_info_return = *(p_chosen_info->property_ptr);
  1107. X        *std_prop_atom_return = p_chosen_info->property_atom;
  1108. X        color_approx_type = PEXColorSpace;
  1109. X    }
  1110. X    else {
  1111. X        pexut_synthesize_cmap_from_visual (p_chosen_info->visual_ptr, 
  1112. X                        cmap_info_return);
  1113. X        *std_prop_atom_return = None;
  1114. X        color_approx_type = -1;
  1115. X    }
  1116. X
  1117. X    *vis_info_return = *(p_chosen_info->visual_ptr);
  1118. X
  1119. X    if (((PEXUtColorApproxType) &
  1120. X        (local_criteria.hard_criteria_mask | 
  1121. X        local_criteria.soft_criteria_mask)) &&
  1122. X        (!(PEXUtColorApproxType & p_chosen_info->unmet_soft_criteria)))
  1123. X        color_approx_type = local_criteria.color_approx_type;
  1124. X
  1125. X    pexut_load_color_approx_from_std_cmap (color_approx_type, 
  1126. X                    vis_info_return, cmap_info_return, 
  1127. X                    capx_info_return);
  1128. X
  1129. X    *unmet_criteria_return = p_chosen_info->unmet_soft_criteria;
  1130. X    FREE_ALLOCATED_RESOURCES
  1131. X
  1132. X    if (*unmet_criteria_return)
  1133. X        return PEXUtQualifiedSuccess;
  1134. X    else
  1135. X        return PEXUtSuccess;
  1136. X
  1137. X#undef FREE_ALLOCATED_RESOURCES
  1138. X
  1139. X} /* PEXUtFindVisual */
  1140. X
  1141. X
  1142. Xint PEXUtGetStandardColormapInfo (
  1143. X        display,
  1144. X        vis_info,
  1145. X        cmap_info_return,
  1146. X        capx_info_return,
  1147. X        std_prop_atom_return
  1148. X        )
  1149. X
  1150. X        Display                *display;
  1151. X        XVisualInfo            *vis_info;
  1152. X        XStandardColormap        *cmap_info_return;
  1153. X        PEXColorApproxEntry        *capx_info_return;
  1154. X        Atom                *std_prop_atom_return;
  1155. X{
  1156. X
  1157. X    int            entry_count;
  1158. X    Atom            property_atom;
  1159. X    XStandardColormap    *property_data;
  1160. X
  1161. X    int            prop_index;
  1162. X    int            entry_index;
  1163. X    int            result;
  1164. X
  1165. X
  1166. X    /*
  1167. X        For each property in the list of properties specified by
  1168. X        the interoperability conventions, get the value of the 
  1169. X        property, and search it for the specified visual.
  1170. X    */
  1171. X
  1172. X    for (prop_index=0; prop_index<NUM_INTEROP_PROPERTIES; prop_index++) {
  1173. X
  1174. X        result = pexut_get_standard_cmap_property (display, 
  1175. X                        vis_info->screen, 
  1176. X                        &(interop_properties[prop_index]),
  1177. X                        &property_atom,
  1178. X                        &entry_count,
  1179. X                        &property_data);
  1180. X
  1181. X        if (result != PEXUtSuccess) {
  1182. X        return result;
  1183. X        }
  1184. X
  1185. X        for (entry_index=0; entry_index < entry_count; entry_index++) {
  1186. X
  1187. X        if (property_data[entry_index].visualid == vis_info->visualid) {
  1188. X
  1189. X            *cmap_info_return = property_data[entry_index];
  1190. X            pexut_load_color_approx_from_std_cmap (PEXColorSpace, 
  1191. X                                vis_info, 
  1192. X                                cmap_info_return, 
  1193. X                                capx_info_return);
  1194. X            XFree (property_data);
  1195. X            *std_prop_atom_return = property_atom;
  1196. X            return PEXUtSuccess;
  1197. X        }
  1198. X        }
  1199. X
  1200. X        if (entry_count > 0)
  1201. X        XFree (property_data);
  1202. X    }
  1203. X
  1204. X    /*
  1205. X        If the visual was not found in any property, synthesize colormap 
  1206. X        info from the visual.  In other words, make an educated guess.
  1207. X    */
  1208. X
  1209. X    pexut_synthesize_cmap_from_visual (vis_info, cmap_info_return);
  1210. X    pexut_load_color_approx_from_std_cmap (-1, vis_info, 
  1211. X                        cmap_info_return, 
  1212. X                        capx_info_return);
  1213. X    *std_prop_atom_return = None;
  1214. X    return PEXUtSuccess;
  1215. X
  1216. X} /* PEXUtGetStandardColormapInfo */
  1217. X
  1218. X
  1219. Xint PEXUtVerifyColorApproximation (
  1220. X        display,
  1221. X        capx_info,
  1222. X        vis_info
  1223. X        )
  1224. X
  1225. X        Display                *display;
  1226. X        PEXColorApproxEntry        *capx_info;
  1227. X        XVisualInfo            *vis_info;
  1228. X{
  1229. X    int            result;
  1230. X    int            return_value;
  1231. X    Window            window;
  1232. X    int            inquiry_supported;
  1233. X
  1234. X    /*
  1235. X        Create a temporary unmapped window in the visual.
  1236. X    */
  1237. X    pexut_create_temporary_window (display, vis_info, &window);
  1238. X
  1239. X
  1240. X    /*
  1241. X        Verify that specified approx type is supported
  1242. X        using PEXGetEnumTypeInfo.  If not, return failure.
  1243. X    */
  1244. X
  1245. X    result = pexut_verify_color_approx_type (display, window, 
  1246. X                        capx_info->type);
  1247. X    if (result != PEXUtSuccess) {
  1248. X        pexut_destroy_temporary_window (display, vis_info, window);
  1249. X        return result;
  1250. X    }
  1251. X
  1252. X    inquiry_supported = False;
  1253. X
  1254. X    {
  1255. X        int            enum_types[1];
  1256. X        unsigned long     *count;
  1257. X        PEXEnumTypeDesc    *enum_data;
  1258. X        int            enum_index;
  1259. X
  1260. X        /*
  1261. X        Verify that the QueryColorApprox escape is supported
  1262. X        using PEXGetEnumTypeInfo.  If not, we just can't verify
  1263. X        support.
  1264. X        */
  1265. X
  1266. X        enum_types[0] = PEXETEscape;
  1267. X        if (!PEXGetEnumTypeInfo (display, window, 1, enum_types, 
  1268. X                    PEXETIndex, &count, &enum_data)) {
  1269. X
  1270. X        pexut_destroy_temporary_window (display, vis_info, window);
  1271. X        return PEXUtPEXFailure;
  1272. X        }
  1273. X        else {
  1274. X
  1275. X        for (enum_index = 0; enum_index < *count; enum_index++) {
  1276. X            if ((short) enum_data[enum_index].index == 
  1277. X            (short) PEXETEscapeQueryColorApprox) {
  1278. X            inquiry_supported = True;
  1279. X            break;
  1280. X            }
  1281. X        }
  1282. X        PEXFreeEnumInfo (1, count, enum_data);
  1283. X        }
  1284. X    }
  1285. X
  1286. X    if (inquiry_supported) {
  1287. X
  1288. X        PEXEscapeQueryColorApproxData    query;
  1289. X        PEXEscapeQueryColorApproxReplyData    *reply;
  1290. X        unsigned long             reply_length;
  1291. X
  1292. X        query.drawable = window;
  1293. X        query.capx = *capx_info;
  1294. X
  1295. X        reply = (PEXEscapeQueryColorApproxReplyData *)
  1296. X            PEXEscapeWithReply (display, PEXEscapeQueryColorApprox, 
  1297. X                    sizeof(query), ((char *) &query), 
  1298. X                    &reply_length);
  1299. X
  1300. X        if (reply != NULL) {
  1301. X
  1302. X        if (reply->capx_is_supported)
  1303. X            return_value = PEXUtSuccess;
  1304. X        else
  1305. X            return_value = PEXUtCriteriaFailure;
  1306. X
  1307. X        XFree ((char *) reply);
  1308. X        }
  1309. X        else {
  1310. X        pexut_destroy_temporary_window (display, vis_info, window);
  1311. X        return PEXUtPEXFailure;
  1312. X        }
  1313. X    }
  1314. X    else {
  1315. X        /* Can't determine support or non-support. */
  1316. X        return_value = PEXUtQualifiedSuccess;
  1317. X    }
  1318. X
  1319. X
  1320. X    /*
  1321. X        Destroy the temporary window.
  1322. X    */
  1323. X
  1324. X    pexut_destroy_temporary_window (display, vis_info, window);
  1325. X
  1326. X
  1327. X    return return_value;
  1328. X    
  1329. X} /* PEXUtVerifyColorApproximation */
  1330. X
  1331. X
  1332. Xint PEXUtCreateWriteableColormap (
  1333. X        display,
  1334. X        vis_info,
  1335. X        capx_info,
  1336. X        colormap_id_return
  1337. X        )
  1338. X
  1339. X        Display                *display;
  1340. X        XVisualInfo            *vis_info;
  1341. X        PEXColorApproxEntry        *capx_info;
  1342. X        Colormap            *colormap_id_return;
  1343. X{
  1344. X    int     result;
  1345. X
  1346. X    result = PEXUtXFailure;
  1347. X    switch (vis_info->class) {
  1348. X
  1349. X    case PseudoColor:    
  1350. X    case GrayScale:    
  1351. X        result = pexut_create_one_channel_map (display, vis_info, 
  1352. X                        capx_info, colormap_id_return);
  1353. X        break;
  1354. X
  1355. X    case DirectColor:    
  1356. X        result = pexut_create_three_channel_map (display, vis_info, 
  1357. X                        capx_info, colormap_id_return);
  1358. X        break;
  1359. X
  1360. X    case StaticColor:
  1361. X    case TrueColor:
  1362. X    case StaticGray:
  1363. X        result = pexut_create_read_only_map (display, vis_info, 
  1364. X                        capx_info, colormap_id_return);
  1365. X        break;
  1366. X    }
  1367. X
  1368. X    return result;
  1369. X    
  1370. X} /* PEXUtCreateWriteableColormap */
  1371. X
  1372. X
  1373. Xint PEXUtModifyColormapForVendorDependencies (
  1374. X        display,
  1375. X        colormap_id,
  1376. X        vis_info,
  1377. X        capx_info
  1378. X        )
  1379. X
  1380. X        Display                *display;
  1381. X        Colormap            colormap_id;
  1382. X        XVisualInfo            *vis_info;
  1383. X        PEXColorApproxEntry        *capx_info;
  1384. X{
  1385. X    PEXExtensionInfo    *ext_info;
  1386. X    int            result;
  1387. X
  1388. X    /*
  1389. X        Get PEX extension info.
  1390. X    */
  1391. X
  1392. X    if (NULL == (ext_info = PEXGetExtensionInfo (display)))
  1393. X        return PEXUtPEXFailure;
  1394. X
  1395. X    result = PEXUtUnmodifiedResource;
  1396. X    if (!strcmp(ext_info->vendor_name, "Hewlett-Packard Company")) {
  1397. X        result = pexut_modify_colormap_for_HP_dependencies (
  1398. X                    display, colormap_id, 
  1399. X                    vis_info, capx_info);
  1400. X    }
  1401. X    /*
  1402. X    else if (!strcmp(ext_info->vendor_name, "vendor_2")) {
  1403. X        result = pexut_modify_colormap_for_vendor_2_dependencies (
  1404. X                    display, colormap_id, 
  1405. X                    vis_info, capx_info);
  1406. X    }
  1407. X    */
  1408. X
  1409. X    return result;
  1410. X
  1411. X} /* PEXUtModifyColormapForVendorDependencies */
  1412. X
  1413. X
  1414. Xint PEXUtCopyColormapAsReadOnly (
  1415. X        display,
  1416. X        source_cmap_id,
  1417. X        vis_info,
  1418. X        capx_info,
  1419. X        cmap_id_return
  1420. X        )
  1421. X
  1422. X        Display                *display;
  1423. X        Colormap            source_cmap_id;
  1424. X        XVisualInfo            *vis_info;
  1425. X        PEXColorApproxEntry        *capx_info;
  1426. X        Colormap            *cmap_id_return;
  1427. X
  1428. X/*
  1429. X    NOTE:      There is an assumption in this code that if XAllocColor does 
  1430. X        not find an existing cell that matches the RGB, that it
  1431. X        allocates the lowest unallocated cell available, i.e. it
  1432. X        works from pixel zero towards higher values.
  1433. X
  1434. X            
  1435. X    Algorithm:
  1436. X
  1437. X    Section I:    Allocate a new Colormap and allocate all the cells.
  1438. X
  1439. X    Section II:    Compute the number of cells in the color approximation
  1440. X            region.  Fetch all the cells of the source Colormap.
  1441. X
  1442. X    Section III:    Free and reallocate as read-only the regions above
  1443. X            and below the color approximation region if it is
  1444. X            partial.  The color approximation region must be left
  1445. X            read-write because XAllocColor might find matches in
  1446. X            the cells outside the region and so would leave
  1447. X            unallocated cells inside the region.  Later XAllocColor
  1448. X            calls can then corrupt the color approximation ramp.
  1449. X
  1450. X            Freeing and reallocating the color approximation 
  1451. X            region first doesn't work either because then 
  1452. X            XAllocColor calls for the lower region find matches 
  1453. X            within the color ramp, and so leave holes in the 
  1454. X            lower region that is often already in use by other 
  1455. X            clients.  Later XAllocColor calls then write these
  1456. X            cells and cause color flashing in the human interface.
  1457. X
  1458. X    Section IV:    Free and allocate the entire Colormap as read-only
  1459. X            if the color approximation region consumes the entire
  1460. X            Colormap.  This is safe because no unallocated cells
  1461. X            will be left.  If the color approximation region
  1462. X            was partial, then write the region with the source
  1463. X            colors.
  1464. X*/
  1465. X{
  1466. X    Colormap    cmap_id;
  1467. X    int        num_reds, num_greens, num_blues, num_colors;
  1468. X    int        red_shift, green_shift, blue_shift;
  1469. X    int        vis_red_shift, vis_green_shift, vis_blue_shift;
  1470. X    unsigned long    temp;
  1471. X    unsigned long    *pixels, pixel_value, *p_pixel;
  1472. X    XColor        *source_colors, *p_color, screen_def;
  1473. X    int        result;
  1474. X
  1475. X
  1476. X    /*
  1477. X        Nothing to do for read-only Visuals.
  1478. X    */
  1479. X
  1480. X    if ((vis_info->class == StaticGray) ||
  1481. X        (vis_info->class == StaticColor) ||
  1482. X        (vis_info->class == TrueColor)) {
  1483. X
  1484. X        *cmap_id_return = source_cmap_id;
  1485. X        return PEXUtSuccess;
  1486. X    }
  1487. X
  1488. X    /*
  1489. X    -----------------------------------------------------------------------
  1490. X    Section I:    Allocate a new Colormap and allocate all the cells.
  1491. X    -----------------------------------------------------------------------
  1492. X    */
  1493. X
  1494. X    /*
  1495. X        Allocate new colormap with AllocNone.
  1496. X        Allocate all the cells as read/write using XAllocColorCells.
  1497. X    */
  1498. X
  1499. X    cmap_id = XCreateColormap ( display, 
  1500. X                    RootWindow (display, vis_info->screen),
  1501. X                    vis_info->visual, AllocNone );
  1502. X    if (cmap_id == None)
  1503. X        return PEXUtXFailure;
  1504. X
  1505. X    pixels = (unsigned long *) 
  1506. X            malloc (vis_info->colormap_size * sizeof(unsigned long));
  1507. X    if (pixels == NULL) {
  1508. X        XFreeColormap (display, cmap_id);
  1509. X        return PEXUtAllocFailure;
  1510. X    }
  1511. X
  1512. X    result = XAllocColorCells ( display, cmap_id, True,
  1513. X                    (unsigned long *) NULL, 0, 
  1514. X                    pixels, vis_info->colormap_size);
  1515. X    if (! result) {
  1516. X        free (pixels);
  1517. X        XFreeColormap (display, cmap_id);
  1518. X        return PEXUtXFailure;
  1519. X    }
  1520. X
  1521. X
  1522. X    /*
  1523. X    -----------------------------------------------------------------------
  1524. X    Section II:    Compute the number of cells in the color approximation
  1525. X        region.  Fetch all the cells of the source Colormap.
  1526. X    -----------------------------------------------------------------------
  1527. X    */
  1528. X    /*
  1529. X        Compute the number of cells in the ramp region.
  1530. X    */
  1531. X
  1532. X    if ((vis_info->class == GrayScale) ||
  1533. X        (vis_info->class == PseudoColor)) {
  1534. X
  1535. X        if (capx_info->type == PEXColorRange) {
  1536. X
  1537. X        num_colors = capx_info->max1 + 1;
  1538. X        }
  1539. X        else { /* assume PEXColorSpace */
  1540. X
  1541. X        num_reds = capx_info->max1 + 1;
  1542. X        num_greens = capx_info->max2 + 1;
  1543. X        num_blues = capx_info->max3 + 1;
  1544. X        num_colors = num_reds * num_greens * num_blues;
  1545. X        }
  1546. X    }
  1547. X    else { /* assume DirectColor  */
  1548. X
  1549. X        num_reds = capx_info->max1 + 1;
  1550. X        num_greens = capx_info->max2 + 1;
  1551. X        num_blues = capx_info->max3 + 1;
  1552. X        num_colors = num_reds;
  1553. X        if (num_greens > num_colors) num_colors = num_greens;
  1554. X        if (num_blues > num_colors) num_colors = num_blues;
  1555. X
  1556. X        for (red_shift = 0, temp = capx_info->mult1;
  1557. X        temp > 1; red_shift++, temp >>= 1);
  1558. X        vis_red_shift = 0;
  1559. X        temp = vis_info->red_mask;
  1560. X        while (!(temp & 0x1)) {
  1561. X        vis_red_shift++;
  1562. X        temp >>= 1;
  1563. X        }
  1564. X
  1565. X        for (green_shift = 0, temp = capx_info->mult2;
  1566. X        temp > 1; green_shift++, temp >>= 1);
  1567. X        vis_green_shift = 0;
  1568. X        temp = vis_info->green_mask;
  1569. X        while (!(temp & 0x1)) {
  1570. X        vis_green_shift++;
  1571. X        temp >>= 1;
  1572. X        }
  1573. X
  1574. X        for (blue_shift = 0, temp = capx_info->mult3;
  1575. X        temp > 1; blue_shift++, temp >>= 1);
  1576. X        vis_blue_shift = 0;
  1577. X        temp = vis_info->blue_mask;
  1578. X        while (!(temp & 0x1)) {
  1579. X        vis_blue_shift++;
  1580. X        temp >>= 1;
  1581. X        }
  1582. X
  1583. X        if ((red_shift != vis_red_shift) ||
  1584. X        (green_shift != vis_green_shift) ||
  1585. X        (blue_shift != vis_blue_shift)) {
  1586. X
  1587. X        free (pixels);
  1588. X        XFreeColormap (display, cmap_id);
  1589. X        return PEXUtXFailure;
  1590. X        }
  1591. X    }
  1592. X
  1593. X    if (capx_info->base_pixel >= vis_info->colormap_size) {
  1594. X        free (pixels);
  1595. X        XFreeColormap (display, cmap_id);
  1596. X        return PEXUtXFailure;
  1597. X    }
  1598. X    if (capx_info->base_pixel + num_colors > vis_info->colormap_size)
  1599. X        num_colors = vis_info->colormap_size - capx_info->base_pixel;
  1600. X
  1601. X
  1602. X    /*
  1603. X        Fetch all the cells in the source colormap.
  1604. X    */
  1605. X
  1606. X    if ((source_colors = (XColor *) malloc 
  1607. X        (vis_info->colormap_size * sizeof(XColor))) == NULL) {
  1608. X
  1609. X        free (pixels);
  1610. X        XFreeColormap (display, cmap_id);
  1611. X        return PEXUtAllocFailure;
  1612. X    }
  1613. X
  1614. X    for (pixel_value = 0, p_color = source_colors; 
  1615. X        pixel_value < vis_info->colormap_size;
  1616. X        pixel_value++, p_color++) {
  1617. X
  1618. X        if (vis_info->class == DirectColor) {
  1619. X
  1620. X        p_color->pixel = (pixel_value << red_shift);
  1621. X        p_color->pixel |= (pixel_value << green_shift);
  1622. X        p_color->pixel |= (pixel_value << blue_shift);
  1623. X        }
  1624. X        else {
  1625. X        p_color->pixel = pixel_value;
  1626. X        }
  1627. X        p_color->flags = DoRed | DoGreen | DoBlue;
  1628. X    }
  1629. X    XQueryColors (display, source_cmap_id, source_colors, 
  1630. X            vis_info->colormap_size);
  1631. X
  1632. X
  1633. X    /*
  1634. X    -----------------------------------------------------------------------
  1635. X    Section III:    Free and reallocate as read-only the regions above
  1636. X            and below the color approximation region if it is
  1637. X            partial.  The color approximation region must be left
  1638. X            read-write because XAllocColor might find matches in
  1639. X            the cells outside the region and so would leave
  1640. X            unallocated cells inside the region.  Later XAllocColor
  1641. X            calls can then corrupt the color approximation ramp.
  1642. X
  1643. X            Freeing and reallocating the color approximation 
  1644. X            region first doesn't work either because then 
  1645. X            XAllocColor calls for the lower region find matches 
  1646. X            within the color ramp, and so leave holes in the 
  1647. X            lower region that is often already in use by other 
  1648. X            clients.  Later XAllocColor calls then write these
  1649. X            cells and cause color flashing in the human interface.
  1650. X    -----------------------------------------------------------------------
  1651. X    */
  1652. X
  1653. X    /*
  1654. X        Free cells above the ramp region and allocate those colors.
  1655. X    */
  1656. X
  1657. X    if ((capx_info->base_pixel + num_colors) < vis_info->colormap_size) {
  1658. X
  1659. X        for (pixel_value = (capx_info->base_pixel + num_colors), 
  1660. X        p_pixel = pixels;
  1661. X        pixel_value < vis_info->colormap_size;
  1662. X        pixel_value++, p_pixel++)  {
  1663. X
  1664. X        if (vis_info->class == DirectColor) {
  1665. X
  1666. X            *p_pixel = (pixel_value << red_shift);
  1667. X            *p_pixel |= (pixel_value << green_shift);
  1668. X            *p_pixel |= (pixel_value << blue_shift);
  1669. X        }
  1670. X        else {
  1671. X            *p_pixel = pixel_value;
  1672. X        }
  1673. X        }
  1674. X
  1675. X        XFreeColors (display, cmap_id, pixels, 
  1676. X            (vis_info->colormap_size - 
  1677. X                (capx_info->base_pixel + num_colors)), 
  1678. X            0);
  1679. X
  1680. X        for (pixel_value = (capx_info->base_pixel + num_colors), 
  1681. X        p_color = source_colors + (capx_info->base_pixel + num_colors);
  1682. X        pixel_value < vis_info->colormap_size;
  1683. X        pixel_value++, p_color++) {
  1684. X
  1685. X        screen_def = *p_color;
  1686. X        if (!XAllocColor (display, cmap_id, &screen_def)) {
  1687. X            free (pixels);
  1688. X            free (source_colors);
  1689. X            XFreeColormap (display, cmap_id);
  1690. X            return PEXUtXFailure;
  1691. X        }
  1692. X        }
  1693. X    }
  1694. X
  1695. X    /*
  1696. X        Free cells below the ramp region and allocate those colors.
  1697. X    */
  1698. X
  1699. X    if (capx_info->base_pixel > 0) {
  1700. X
  1701. X        for (pixel_value = 0, p_pixel = pixels;
  1702. X        pixel_value < capx_info->base_pixel;
  1703. X        pixel_value++, p_pixel++)  {
  1704. X
  1705. X        if (vis_info->class == DirectColor) {
  1706. X
  1707. X            *p_pixel = (pixel_value << red_shift);
  1708. X            *p_pixel |= (pixel_value << green_shift);
  1709. X            *p_pixel |= (pixel_value << blue_shift);
  1710. X        }
  1711. X        else {
  1712. X            *p_pixel = pixel_value;
  1713. X        }
  1714. X        }
  1715. X
  1716. X        XFreeColors (display, cmap_id, pixels, 
  1717. X            capx_info->base_pixel, 0);
  1718. X
  1719. X        for (pixel_value = 0,
  1720. X        p_color = source_colors;
  1721. X        pixel_value < capx_info->base_pixel;
  1722. X        pixel_value++, p_color++) {
  1723. X
  1724. X        screen_def = *p_color;
  1725. X        if (!XAllocColor (display, cmap_id, &screen_def)) {
  1726. X            free (pixels);
  1727. X            free (source_colors);
  1728. X            XFreeColormap (display, cmap_id);
  1729. X            return PEXUtXFailure;
  1730. X        }
  1731. X        }
  1732. X    }
  1733. X
  1734. X
  1735. X    /*
  1736. X    -----------------------------------------------------------------------
  1737. X    Section IV:        Free and allocate the entire Colormap as read-only
  1738. X            if the color approximation region consumes the entire
  1739. X            Colormap.  This is safe because no unallocated cells
  1740. X            will be left.  If the color approximation region
  1741. X            was partial, then write the region with the source
  1742. X            colors.
  1743. X    -----------------------------------------------------------------------
  1744. X    */
  1745. X    /*
  1746. X        If the ramp consumes the entire map,
  1747. X        free cells in the ramp region and allocate those colors read-only.
  1748. X    */
  1749. X
  1750. X    if (num_colors == vis_info->colormap_size) {
  1751. X
  1752. X        for (pixel_value = capx_info->base_pixel, p_pixel = pixels;
  1753. X        pixel_value < (capx_info->base_pixel + num_colors);
  1754. X        pixel_value++, p_pixel++)  {
  1755. X
  1756. X        if (vis_info->class == DirectColor) {
  1757. X
  1758. X            *p_pixel = (pixel_value << red_shift);
  1759. X            *p_pixel |= (pixel_value << green_shift);
  1760. X            *p_pixel |= (pixel_value << blue_shift);
  1761. X        }
  1762. X        else {
  1763. X            *p_pixel = pixel_value;
  1764. X        }
  1765. X        }
  1766. X
  1767. X        XFreeColors (display, cmap_id, pixels, 
  1768. X                num_colors, 0);
  1769. X
  1770. X        for (pixel_value = capx_info->base_pixel,
  1771. X        p_color = source_colors + capx_info->base_pixel;
  1772. X        pixel_value < (capx_info->base_pixel + num_colors);
  1773. X        pixel_value++, p_color++) {
  1774. X
  1775. X        screen_def = *p_color;
  1776. X        if (!XAllocColor (display, cmap_id, &screen_def)) {
  1777. X            free (pixels);
  1778. X            free (source_colors);
  1779. X            XFreeColormap (display, cmap_id);
  1780. X            return PEXUtXFailure;
  1781. X        }
  1782. X        }
  1783. X    }
  1784. X    else {
  1785. X        /*
  1786. X        Write out the colors in the region to the new colormap.
  1787. X        */
  1788. X
  1789. X        XStoreColors (display, cmap_id, 
  1790. X                source_colors + capx_info->base_pixel, 
  1791. X                num_colors);
  1792. X    }
  1793. X
  1794. X
  1795. X    /*
  1796. X        Free the allocated storage.
  1797. X        Caller must free the source colormap.
  1798. X    */
  1799. X
  1800. X    free (pixels);
  1801. X    free (source_colors);
  1802. X
  1803. X    *cmap_id_return = cmap_id;
  1804. X    return PEXUtSuccess;
  1805. X
  1806. X} /* PEXUtCopyColormapAsReadOnly */
  1807. X
  1808. X
  1809. Xint PEXUtCreateColormap (
  1810. X        display,
  1811. X        vis_info,
  1812. X        capx_info,
  1813. X        colormap_id_return
  1814. X        )
  1815. X
  1816. X        Display                *display;
  1817. X        XVisualInfo            *vis_info;
  1818. X        PEXColorApproxEntry        *capx_info;
  1819. X        Colormap            *colormap_id_return;
  1820. X{
  1821. X    int        result;
  1822. X    Colormap    writeable_cmap_id;
  1823. X    Colormap    readonly_cmap_id;
  1824. X    
  1825. X
  1826. X    result = PEXUtCreateWriteableColormap (display, vis_info,
  1827. X                      capx_info, &writeable_cmap_id);
  1828. X    if (result != PEXUtSuccess)
  1829. X        return result;
  1830. X
  1831. X    result = PEXUtModifyColormapForVendorDependencies (
  1832. X                    display, writeable_cmap_id,
  1833. X                    vis_info, capx_info);
  1834. X
  1835. X    if ((result != PEXUtUnmodifiedResource) &&
  1836. X        (result != PEXUtModifiedResource))
  1837. X        return result;
  1838. X
  1839. X    result = PEXUtCopyColormapAsReadOnly (display, writeable_cmap_id,
  1840. X                        vis_info, capx_info,
  1841. X                        &readonly_cmap_id);
  1842. X    if (result != PEXUtSuccess)
  1843. X        return result;
  1844. X
  1845. X    if (readonly_cmap_id != writeable_cmap_id)
  1846. X        XFreeColormap (display, writeable_cmap_id);
  1847. X    *colormap_id_return = readonly_cmap_id;
  1848. X    return PEXUtSuccess;
  1849. X
  1850. X} /* PEXUtCreateColormap */
  1851. X
  1852. X
  1853. Xint PEXUtCreateWindow (
  1854. X        display,
  1855. X        screen,
  1856. X        window_info,
  1857. X        vis_info,
  1858. X        window_return,
  1859. X        background_color_return
  1860. X        )
  1861. X
  1862. X        Display                *display;
  1863. X        int                screen;
  1864. X        PEXUtWindowSpecification    *window_info;
  1865. X        XVisualInfo            *vis_info;
  1866. X        Window                *window_return;
  1867. X        XColor                *background_color_return;
  1868. X{
  1869. X    unsigned long         window_mask;
  1870. X    XSetWindowAttributes     window_attrs;
  1871. X    int            result;
  1872. X
  1873. X    unsigned long        pixel_value;
  1874. X    XColor            screen_def;
  1875. X    XColor            exact_def;
  1876. X    int            need_color;
  1877. X
  1878. X
  1879. X    /*
  1880. X        Check the window specification.
  1881. X    */
  1882. X
  1883. X    if (( !(window_info->attr_mask & CWColormap)) ||
  1884. X        (window_info->attrs.colormap == None))
  1885. X        return PEXUtXFailure;
  1886. X
  1887. X
  1888. X    /*
  1889. X        Look up colors for background and border.
  1890. X    */
  1891. X
  1892. X    window_mask = window_info->attr_mask;
  1893. X    window_attrs = window_info->attrs;
  1894. X
  1895. X    if ( !(window_info->attr_mask & CWBackPixel)) {
  1896. X
  1897. X        need_color = True;
  1898. X        if (XParseColor (display, window_attrs.colormap, 
  1899. X                window_info->background_color_name, &exact_def)) {
  1900. X
  1901. X        screen_def = exact_def;
  1902. X
  1903. X        if (XAllocColor (display, window_attrs.colormap, &screen_def)) {
  1904. X            pixel_value = screen_def.pixel;
  1905. X            *background_color_return = screen_def;
  1906. X            need_color = False;
  1907. X        }
  1908. X        }
  1909. X
  1910. X        if (need_color) {
  1911. X
  1912. X        if (XAllocNamedColor (display, window_attrs.colormap, "Black", 
  1913. X                    &screen_def, &exact_def)) {
  1914. X            pixel_value = screen_def.pixel;
  1915. X            *background_color_return = screen_def;
  1916. X        }
  1917. X        else {
  1918. X            pixel_value = 0;
  1919. X            background_color_return->pixel = pixel_value;
  1920. X            background_color_return->red = 0;
  1921. X            background_color_return->green = 0;
  1922. X            background_color_return->blue = 0;
  1923. X        }
  1924. X        }
  1925. X        window_attrs.background_pixel = pixel_value;
  1926. X        window_mask |= CWBackPixel;
  1927. X    }
  1928. X
  1929. X    if ( !(window_info->attr_mask & CWBorderPixel)) {
  1930. X
  1931. X        need_color = True;
  1932. X        if (XParseColor (display, window_attrs.colormap, 
  1933. X                window_info->border_color_name, &exact_def)) {
  1934. X
  1935. X        screen_def = exact_def;
  1936. X
  1937. X        if (XAllocColor (display, window_attrs.colormap, &screen_def)) {
  1938. X            pixel_value = screen_def.pixel;
  1939. X            need_color = False;
  1940. X        }
  1941. X        }
  1942. X
  1943. X        if (need_color) {
  1944. X
  1945. X        if (XAllocNamedColor (display, window_attrs.colormap, "White", 
  1946. X                    &screen_def, &exact_def))
  1947. X            pixel_value = screen_def.pixel;
  1948. X        else
  1949. X            pixel_value = 0;
  1950. X        }
  1951. X        window_attrs.border_pixel = pixel_value;
  1952. X        window_mask |= CWBorderPixel;
  1953. X    }
  1954. X
  1955. X
  1956. X    /*
  1957. X        Create the window.
  1958. X    */
  1959. X
  1960. X    *window_return = XCreateWindow (display, 
  1961. X                window_info->parent,
  1962. X                window_info->size_hints.x,
  1963. X                window_info->size_hints.y,
  1964. X                window_info->size_hints.width,
  1965. X                window_info->size_hints.height,
  1966. X                window_info->border_width,
  1967. X                vis_info->depth, 
  1968. X                InputOutput,
  1969. X                vis_info->visual,
  1970. X                window_mask,
  1971. X                &window_attrs);
  1972. X
  1973. X    if (*window_return == None)
  1974. X        return PEXUtXFailure;
  1975. X
  1976. X    XSetNormalHints (display, *window_return, &(window_info->size_hints));
  1977. X    XStoreName (display, *window_return, window_info->title);
  1978. X    XSync (display,0);
  1979. X
  1980. X    return PEXUtSuccess;
  1981. X
  1982. X} /* PEXUtCreateWindow */
  1983. X
  1984. X
  1985. Xint PEXUtCreateWindowAndColormap (
  1986. X        display,
  1987. X        screen,
  1988. X        criteria,
  1989. X        window_info,
  1990. X        window_return,
  1991. X        vis_info_return,
  1992. X        cmap_info_return,
  1993. X        capx_info_return,
  1994. X        unmet_criteria_return,
  1995. X        std_prop_atom_return,
  1996. X        background_color_return
  1997. X        )
  1998. X
  1999. X        Display                *display;
  2000. X        int                screen;
  2001. X        PEXUtVisualCriteria        *criteria;
  2002. X        PEXUtWindowSpecification    *window_info;
  2003. X        Window                *window_return;
  2004. X        XVisualInfo            *vis_info_return;
  2005. X        XStandardColormap        *cmap_info_return;
  2006. X        PEXColorApproxEntry        *capx_info_return;
  2007. X        unsigned int            *unmet_criteria_return;
  2008. X        Atom                *std_prop_atom_return;
  2009. X        XColor                *background_color_return;
  2010. X{
  2011. X    Colormap            cmap_id_from_property;
  2012. X    Colormap            created_cmap_id;
  2013. X    PEXUtWindowSpecification    local_window_info;
  2014. X    int                 result;
  2015. X    
  2016. X
  2017. X    /*
  2018. X        Find visual.
  2019. X    */
  2020. X
  2021. X    result = PEXUtFindVisual (    display, screen, criteria,
  2022. X                    vis_info_return,
  2023. X                    cmap_info_return,
  2024. X                    capx_info_return,
  2025. X                    unmet_criteria_return,
  2026. X                    std_prop_atom_return );
  2027. X
  2028. X    if ((result != PEXUtSuccess) && (result != PEXUtQualifiedSuccess))
  2029. X        return result;
  2030. X
  2031. X    cmap_id_from_property = cmap_info_return->colormap;
  2032. X
  2033. X
  2034. X    /*
  2035. X        Verify color approximation.
  2036. X    */
  2037. X
  2038. X    result = PEXUtVerifyColorApproximation (display, 
  2039. X                        capx_info_return, 
  2040. X                        vis_info_return);
  2041. X    if ((result != PEXUtSuccess) && (result != PEXUtQualifiedSuccess))
  2042. X        return result;
  2043. X
  2044. X
  2045. X    /*
  2046. X        If sharing, and the default Visual was chosen but there is
  2047. X        no Colormap ID from a property, then use the default Colormap.
  2048. X    */
  2049. X
  2050. X    if ((PEXUtSharableColormap &
  2051. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) &&
  2052. X        (vis_info_return->visual == DefaultVisual(display, screen))) {
  2053. X
  2054. X        if (cmap_id_from_property == None) {
  2055. X        cmap_id_from_property = DefaultColormap(display, screen);
  2056. X        cmap_info_return->colormap = cmap_id_from_property;
  2057. X        }
  2058. X    }
  2059. X
  2060. X        
  2061. X    /*
  2062. X        If no colormap ID in returned info, or not sharing,
  2063. X        create a colormap and modify it for vendor dependencies.
  2064. X        Then reallocate the same colors as read-only, so
  2065. X        XAllocColor has a chance of working.
  2066. X    */
  2067. X
  2068. X    if ((cmap_id_from_property == None) ||
  2069. X        (!(PEXUtSharableColormap &
  2070. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)))) {
  2071. X
  2072. X        result = PEXUtCreateColormap (display, vis_info_return,
  2073. X                      capx_info_return, &created_cmap_id);
  2074. X        if (result != PEXUtSuccess)
  2075. X        return result;
  2076. X
  2077. X        cmap_info_return->colormap = created_cmap_id;
  2078. X    }
  2079. X
  2080. X
  2081. X    /*
  2082. X        Load a local copy of the window info with an augmented set of items
  2083. X        and create the window.
  2084. X    */
  2085. X
  2086. X    local_window_info = *window_info;
  2087. X    local_window_info.attrs.colormap = cmap_info_return->colormap;
  2088. X    local_window_info.attr_mask |= CWColormap;
  2089. X    local_window_info.attr_mask &= ~(CWBackPixel|CWBorderPixel);
  2090. X
  2091. X    result = PEXUtCreateWindow (display, screen, &local_window_info, 
  2092. X                   vis_info_return, window_return, 
  2093. X                    background_color_return);
  2094. X
  2095. X    if (result == PEXUtSuccess) {
  2096. X        XMapWindow (display, *window_return);
  2097. X        XSync (display, 0);
  2098. X    }
  2099. X
  2100. X    return result;
  2101. X
  2102. X} /* PEXUtCreateWindowAndColormap */
  2103. END_OF_FILE
  2104.   if test 44664 -ne `wc -c <'util/pexutcmap.c'`; then
  2105.     echo shar: \"'util/pexutcmap.c'\" unpacked with wrong size!
  2106.   fi
  2107.   # end of 'util/pexutcmap.c'
  2108. fi
  2109. echo shar: End of archive 4 \(of 14\).
  2110. cp /dev/null ark4isdone
  2111. MISSING=""
  2112. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2113.     if test ! -f ark${I}isdone ; then
  2114.     MISSING="${MISSING} ${I}"
  2115.     fi
  2116. done
  2117. if test "${MISSING}" = "" ; then
  2118.     echo You have unpacked all 14 archives.
  2119.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2120.     echo "concatentating pexdraw.c ..."
  2121.     cat pexdrawc.? > pexdraw.c
  2122.     rm pexdrawc.?
  2123.     echo "concatentating pexdraw.uil ..."
  2124.     cat pexdrawu.? > pexdraw.uil
  2125.     rm pexdrawu.?
  2126.     echo "concatentating teapot.c ..."
  2127.     rm teapotc.?
  2128. else
  2129.     echo You still must unpack the following archives:
  2130.     echo "        " ${MISSING}
  2131. fi
  2132. exit 0
  2133. exit 0 # Just in case...
  2134. -- 
  2135.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  2136. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  2137.  "It's intuitively obvious to the |
  2138.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  2139.