home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / doc / tutorials / visuals / vis.nr < prev    next >
Encoding:
Text File  |  1991-08-15  |  36.8 KB  |  1,126 lines

  1. .\"    refer -e -n -p vis.refs -s vis.nr | eqn | pic | psroff -ms
  2. .EQ
  3. delim $$
  4. .EN
  5. .ds CH
  6. .de Ip
  7. .IP \(bu 3
  8. ..
  9. .de Qp
  10. .nr PS -2
  11. .nr VS -2
  12. .QP
  13. ..
  14. .de Qe
  15. .nr PS +2
  16. .nr VS +2
  17. ..
  18. .de RQ
  19. .br
  20. .di
  21. .nr NF 0
  22. .if \\n(dn-\\n(.t .nr NF 1
  23. .if \\n(TC .nr NF 1
  24. .if !\\n(NF .if \\n(TB .nr TB 0
  25. .nf
  26. .rs
  27. .nr TC 5
  28. .in 0
  29. .ls 1
  30. .if !\\n(TB \{\
  31. .    ev
  32. .    br
  33. .    ev 2
  34. .    KK
  35. .\}
  36. .ls
  37. .ce 0
  38. .if !\\n(TB .rm KK
  39. .if \\n(TB .da KJ
  40. .if \\n(TB \!.KD \\n(dn
  41. .if \\n(TB .KK
  42. .if \\n(TB .di
  43. .nr TC \\n(TB
  44. .if \\n(KN .fi
  45. .in
  46. .ev
  47. ..
  48. .\"    These macros should select a typewriter font if you have one.
  49. .de LS
  50. .LP
  51. .KS
  52. .LD
  53. .ft L
  54. .ta .6i 1.2i 1.8i 2.4i 3i 3.6i 4.2i
  55. ..
  56. .de LE
  57. .ft P
  58. .DE
  59. .KE
  60. ..
  61. .de Ls
  62. .nr PS -4
  63. .nr VS -6
  64. .LS
  65. ..
  66. .de Le
  67. .LE
  68. .nr PS +4
  69. .nr VS +6
  70. .LP
  71. ..
  72. .nr PO 1.25i
  73. .TL
  74. Visualizing X11 Clients
  75. .AU
  76. David Lemke
  77. David S. H. Rosenthal
  78. .AI
  79. Sun Microsystems
  80. 2550 Garcia Ave.
  81. Mountain View CA 94043
  82. .AB
  83. The color model of version 11 of the X Window System
  84. exposes a number of aspects of the underlying display.
  85. The concept it uses to represent these device-dependencies is the
  86. .I Visual ;
  87. there may be several Visuals available on a given display.
  88. We present example programs to illustrate the techniques required if
  89. an X client is to operate correctly across the entire range of possible
  90. combinations of Visuals.
  91. .AE
  92. .LP
  93. .DS C
  94. Copyright \(co 1988, 1991 by Sun Microsystems, Inc.\s-2\u*\d\s0
  95. .DE
  96. .FS
  97. *  Permission to use,  copy,  modify and distribute
  98. this document for any purpose and without fee is hereby
  99. granted,  provided that the above copyright notice and this permission
  100. notice appear in all copies,  and that the name of Sun Microsystems,  Inc. not be
  101. used in advertising or publicity pertaining to distribution of the software
  102. without specific,  written prior permission.  Sun Microsystems,  Inc. makes no
  103. representations about the suitability of the software described herein for
  104. any purpose.  It is provided "as is" without express or implied warranty.
  105. .br
  106. \(dg  The X Window System is a trademark of the Massachusetts Institute
  107. of Technology.
  108. .br
  109. This paper was originally presented at the Summer 1988 Usenix Conference.
  110. There were some errors in this version,
  111. and subsequent developments have obsoleted parts of it,
  112. so it has been updated.
  113. .FE
  114. .LP
  115. .Qp
  116. ``The polymorphic visions of the eyes and the spirit are contained in
  117. uniform lines of small or capital letters,  periods,  commas,  parentheses \-
  118. pages of signs packed as closely together as grains of sand representing
  119. the many-colored spectacle of the world on a surface that is always the
  120. same and always different,  like dunes shifted by the desert wind.''
  121. .sp
  122.     Italo Calvino,  \fISix Memos for the Next Millennium\fP
  123. .sp .25i
  124. .Qe
  125. .NH
  126. Introduction
  127. .LP
  128. A design objective of Version 11 of the X Window System\s-2\u\(dg\d\s0
  129. .[
  130. scheifler gettys transactions graphics 1987
  131. .]
  132. is to make it
  133. possible to write client programs that operate correctly across a wide
  134. range of displays.
  135. This objective is often referred to as ``device-independence'',
  136. but this is something of a misnomer.
  137. X11 abstracts the properties of popular display types into an object
  138. called a
  139. .I Visual ,
  140. and exposes to the client the existence of a number of
  141. Visuals.
  142. Visuals are divided into classes;
  143. each class representing the abstraction of a particular type of display hardware.
  144. .LP
  145. The implementor of an X11 server for a particular display must decide
  146. on the appropriate Visual classes to export to its clients.
  147. More than one Visual per screen may be exported
  148. to allow access to the full set of hardware capabilities.
  149. When a client connects to an X11 server,
  150. it must determine the Visuals the server is exporting and their classes,
  151. adapting its behavior to suit.
  152. Normally,  this will involve the client choosing one of the Visuals,  and changing
  153. appropriate initializations.
  154. .LP
  155. Simply adhering to the X11 protocol does not ensure that a client
  156. will operate correctly on all possible combinations of Visuals.
  157. The early X11 server implementations that were made available exported
  158. only a single Visual per screen,
  159. and these Visuals were of only two classes.
  160. As a result,  many existing X11 clients operate correctly on single-Visual
  161. screens of these two classes,
  162. but not on others.
  163. .LP
  164. Among these not-really-device-independent clients are the
  165. .B xwd
  166. and
  167. .B xwud
  168. programs in the X11R3 distribution.
  169. They ``dump'' to a file,  and ``undump'' from a file,
  170. the image of a window,  but they don't work across all combinations of Visuals.
  171. In particular,  they don't work:
  172. .Ip
  173. for TrueColor or DirectColor Visuals.
  174. .Ip
  175. if there are subwindows that have a different depth,  Visual,
  176. or colormap.
  177. .Ip
  178. if the default colormap of the screen being dumped to doesn't
  179. mimic the colormap of the window being dumped.
  180. .LP
  181. We first review the Visual concept,  and then present versions of
  182. the screen dump and undump clients that do work correctly across
  183. all Visuals.
  184. These clients are designed as teaching aids;
  185. they illustrate the techniques needed to make truly device-independent
  186. X11 clients,  but they:
  187. .Ip
  188. are as simple as possible,  and thus too inefficient for production use,
  189. .Ip
  190. ignore all the issues of interacting with window managers and other
  191. clients,
  192. .[
  193. rosenthal communication conventions 1988
  194. .]
  195. in the interests of clarity,
  196. .Ip
  197. and ignore our own advice about using a toolkit,
  198. .[
  199. rosenthal hello world 1988
  200. .]
  201. in order to focus on the underlying X11 mechanisms.
  202. .NH
  203. Visual Classes
  204. .LP
  205. An X client paints in a
  206. .I Drawable ,
  207. a rectangular array of numbers called
  208. pixel values,  using operations that alter the numbers,
  209. such as CopyArea and PolyLine.
  210. The only difference that affects the drawing process between one
  211. drawable and another is the
  212. .I depth ,
  213. the number of bits in each of the numbers.
  214. The Visual concept is irrelevant to this process;
  215. a useful model is to think of CPU access to a display bitmap,
  216. with the monitor turned off (see Figure 1).
  217. .KF
  218. .DS
  219. .PS 3.5i 2.5i
  220. line from 5.237,4.825 to 6.175,6.325
  221. line from 5.237,6.325 to 6.237,4.825
  222. line from 2.275,5.788 to 2.175,5.763 to 2.275,5.737
  223. line from 2.175,5.763 to 4.175,5.763
  224. line from 4.075,5.737 to 4.175,5.763 to 4.075,5.788
  225. line from 4.737,7.013 to 6.737,7.013 to 6.737,4.325 to 4.737,4.325 to 4.737,7.013
  226. line from 4.175,8.012 to 7.175,8.012 to 7.175,3.325 to 4.175,3.325 to 4.175,8.012
  227. line from 0.300,6.325 to 2.175,6.325 to 2.175,5.138 to 0.300,5.138 to 0.300,6.325
  228. .ps 7
  229. "Drawable" at 4.925,6.606 ljust
  230. "Memory" at 4.487,7.668 ljust
  231. "Pixel Values" at 2.387,5.918 ljust
  232. "CPU" at 0.925,5.731 ljust
  233. .PE
  234. .DE
  235. .DS C
  236. Figure 1:  The X11 Drawing Process
  237. .DE
  238. .KE
  239. .LP
  240. Some Drawables are
  241. .I Windows ,
  242. and these can be made visible by
  243. .I mapping
  244. them to the screen.
  245. When the client creates a Window,  it must be assigned one of the
  246. possible Visuals for the screen;
  247. this Visual will control the process by which the Window's pixels
  248. become visible when it is mapped.
  249. A useful model is to think of video refresh access to a display
  250. bitmap,  with the CPU halted (see Figure 2).
  251. .KF
  252. .DS
  253. .PS 3.5i 2.5i
  254. line from 6.612,5.763 to 7.112,6.888
  255. line from 6.612,6.888 to 7.112,5.763
  256. line from 0.988,5.075 to 1.988,7.075
  257. line from 0.988,7.075 to 1.988,5.075
  258. line from 3.612,7.325 to 4.862,7.325 to 4.862,5.263 to 3.612,5.263 to 3.612,7.325
  259. line from 2.550,6.325 to 3.425,6.325
  260. line from 3.325,6.300 to 3.425,6.325 to 3.325,6.350
  261. line from 0.800,7.763 to 2.300,7.763 to 2.300,4.763 to 0.800,4.763 to 0.800,7.763
  262. line from 5.925,6.325 to 6.425,5.575
  263. line from 5.925,6.325 to 6.425,7.263
  264. line from 6.425,7.263 to 7.237,7.263 to 7.237,5.575 to 6.425,5.575 to 6.425,7.263
  265. line from 4.987,6.325 to 5.925,6.325
  266. line from 5.825,6.300 to 5.925,6.325 to 5.825,6.350
  267. line from 3.487,7.763 to 4.987,7.763 to 4.987,4.825 to 3.487,4.825 to 3.487,7.763
  268. line from 0.550,8.075 to 2.550,8.075 to 2.550,4.513 to 0.550,4.513 to 0.550,8.075
  269. .ps 7
  270. "Colormap" at 3.737,7.106 ljust
  271. "Screen" at 6.512,7.106 ljust
  272. "Values" at 2.675,6.106 ljust
  273. "Pixel" at 2.675,6.481 ljust
  274. "RGB" at 5.112,6.418 ljust
  275. "Visual" at 3.550,7.543 ljust
  276. "Window" at 1.113,7.543 ljust
  277. "Memory" at 0.863,7.906 ljust
  278. .PE
  279. .DE
  280. .DS C
  281. Figure 2:  The X11 Display Process
  282. .DE
  283. .KE
  284. .LP
  285. Conceptually,
  286. when a screen pixel is to be refreshed the top-most Window's
  287. corresponding pixel value is read,  and used to index into a
  288. .I Colormap ,
  289. an object containing three arrays (red,  green and blue) of
  290. intensity values that models a video look-up table.
  291. The Visual for the window controls:
  292. .Ip
  293. How this indexing is done.
  294. .Ip
  295. Which of possibly many installed Colormaps is used.
  296. .Ip
  297. Whether and how the Colormap can be modified.
  298. .LP
  299. Visuals are divided into six classes,  modeling six different types
  300. of display hardware.  The classes,  and their effects on the pixel value
  301. to visible color mapping,  are:
  302. .Ip
  303. .I StaticGray .
  304. The pixel value indexes a predefined,  read-only colormap.
  305. For each colormap cell,  the red,  green and blue values
  306. are the same,  producing a gray image.
  307. .Ip
  308. .I StaticColor .
  309. The pixel values indexes a predefined,  read-only colormap.
  310. The red,  green and blue values for each cell are server-dependent.
  311. .Ip
  312. .I TrueColor .
  313. The pixel value is divided into sub-fields for red,  green and blue.
  314. Each sub-field separately indexes the appropriate primary of a
  315. predefined,  read-only colormap.
  316. The red,  green and blue values for each cell are server-dependent,
  317. and are selected to provide a nearly linear increasing ramp.
  318. .Ip
  319. .I GrayScale .
  320. The pixel value indexes a colormap which the client can alter,  subject
  321. to the restriction that the red,  green and blue values of each cell
  322. must always be the same,  producing a gray image.
  323. .Ip
  324. .I PseudoColor .
  325. The pixel value indexes a colormap which the client can alter.
  326. The red,  green and blue values of each cell can be selected arbitrarily.
  327. .Ip
  328. .I DirectColor .
  329. The pixel value is divided into sub-fields for red,  green and blue.
  330. Each sub-field separately indexes the appropriate primary of a
  331. colormap that the client can alter.
  332. .LP
  333. The early X11 server implementations provided two Visuals:
  334. .Ip
  335. Servers for monochrome displays exported a single StaticGray Visual of depth 1.
  336. .Ip
  337. Servers for color displays exported a single PseudoColor Visual of varying depth,
  338. typically 4 or 8.
  339. .LP
  340. These are the natural choices for simple workstation hardware,  but they made
  341. it easy for initial clients to ignore many of the problems of dealing
  342. with Visuals.
  343. .LP
  344. Already,  servers for common hardware such as the MIT sample
  345. server for the DEC QDSS display
  346. and the X11/NeWS
  347. .[
  348. schaufler design overview 1988
  349. .]
  350. server on Sun color hardware are exporting multiple Visuals.
  351. The QDSS server's default Visual is PseudoColor,
  352. but it also exports a StaticColor Visual.
  353. The X11/NeWS server's default is a StaticColor Visual,
  354. and it also exports a PseudoColor Visual.
  355. As X11 becomes available on more complex hardware,  multiple
  356. Visuals will become increasingly common.
  357. .LP
  358. Many current X11 clients make unwarranted assumptions about their Visuals.
  359. Among the most common such assumptions\s-2\u\(dg\d\s0
  360. .FS
  361. \(dg  The technical term for these erroneous assumptions is
  362. .I bugs .
  363. .FE
  364. are:
  365. .Ip
  366. That the default Visual is the only available Visual.
  367. Clients making this assumption may fail even though a
  368. Visual that could have supported them was available.
  369. .Ip
  370. That all Visuals with more than two Colormap cells are
  371. color.
  372. Clients making this assumption will behave strangely on
  373. some StaticGray and GrayScale Visuals.
  374. .Ip
  375. That all Visuals with more than two Colormap cells have
  376. writable Colormaps.
  377. Clients making this (very common) assumption will fail
  378. with Xlib errors on StaticColor and TrueColor Visuals.
  379. .Ip
  380. That Colormaps (and especially the default Colormap) are
  381. infinitely large,  so that attempts to allocate private cells
  382. in them will always succeed.
  383. .LP
  384. In fact,  the only clients that can ignore the question of Visuals
  385. are those that use the
  386. .I BlackPixel()
  387. and
  388. .I WhitePixel()
  389. macros to paint a black and white image in the default Visual;
  390. this will work on all servers though the colors may not actually
  391. be Black or White.
  392. .I All
  393. other clients must pay some attention to the details of the Visual(s)
  394. they are using.
  395. To demonstrate how to deal with these details,  we present versions
  396. of the screen dump and undump clients.
  397. .NH
  398. The ``dump'' Client
  399. .LP
  400. The objective of the screen dump client is to record the appearance
  401. of a specified rectangle of the screen so that it can be restored later,
  402. most likely on some other display device.
  403. Thus,  the stored representation of the rectangle must be device-independent.
  404. The simplest possible device-independent representation is the red,  green and
  405. blue (RGB) intensities of each pixel.
  406. .LP
  407. The only X11 protocol request that allows a client to read back the contents of
  408. a window is GetImage,  so the dump client clearly must be based on it.
  409. From the point of view of the screen dump client,  there are two problems
  410. with the specification of GetImage:
  411. .Ip
  412. It returns pixel values,  not RGB values.
  413. Pixel values are not device-independent,  and so cannot be used directly.
  414. .Ip
  415. Some of the values it returns may be garbage.
  416. .NH 2
  417. Converting pixel values to RGB
  418. .LP
  419. To transform the returned pixel values to RGB intensities,  the client must
  420. use the QueryColors request to look up the index in a specified Colormap.
  421. The Colormap to use will be given by the colormap attribute of the window
  422. in question.
  423. .LP
  424. The Visual to be used for this lookup is implicit.
  425. Since setting a window's colormap attribute to a Colormap that
  426. does not match the Visual of the window is an error,
  427. using the Colormap attribute of the window
  428. for the pixel value lookup implies using the correct Visual.
  429. .NH 2
  430. Obtaining Correct Data from GetImage
  431. .LP
  432. The problem of GetImage returning garbage is described in the X11
  433. protocol specification:
  434. .Qp
  435. ``If the window has a backing store, 
  436. then the backing-store contents are returned for regions of the window 
  437. that are obscured by noninferior windows;
  438. otherwise, the returned contents of such obscured regions are undefined.
  439. Also undefined are the returned contents of visible
  440. regions of inferiors of different depth than the specified window.''
  441. .[
  442. scheifler protocol 1988
  443. .]
  444. .Qe
  445. .LP
  446. There are therefore two reasons why some of the returned pixel values may be
  447. wrong:
  448. .Ip
  449. They may be obscured by non-inferior windows,  and the server may not
  450. be maintaining backing-store for the window.
  451. The backing-store attribute of a window is a hint to the server;
  452. there is no way for a client to discover whether the server is actually
  453. maintaining backing-store for any particular window at any particular time.
  454. .IP
  455. Thus,  unless it can be determined that a pixel in a window is
  456. .I not
  457. obscured by a non-inferior window,  that pixel value must be regarded as
  458. garbage.
  459. .Ip
  460. They may be in a visible region of an inferior of different depth.
  461. .IP
  462. Thus,  unless the pixel in question can be shown
  463. .I not
  464. to be in an inferior of different depth,  its value must be regarded as
  465. garbage.
  466. .LP
  467. In both these cases,  at some cost,  we can:
  468. .Ip
  469. unambiguously determine that a pixel value is good,
  470. .Ip
  471. assume that all others are garbage,
  472. .Ip
  473. and use GetImage on other windows to discover the correct values
  474. for these assumed-to-be-garbage pixels.
  475. .LP
  476. Unfortunately,  there is a third reason why the pixels may be garbage:
  477. .Qp
  478. ``When no valid contents are available for regions of a window
  479. and the regions are either visible or the server is maintaining backing store,
  480. the server automatically tiles the regions with the window's background
  481. unless the window has a background of 
  482. .B None .
  483. If the background is 
  484. .B None , 
  485. the previous screen contents from other windows of the same depth as the window
  486. are simply left in place if the contents come from the parent of the window
  487. or an inferior of the parent;
  488. otherwise, the initial contents of the exposed regions are undefined.''
  489. .[
  490. scheifler protocol 1988
  491. .]
  492. .Qe
  493. .LP
  494. In other words,  the pixels in areas whose top window has background
  495. .B None
  496. may not have been overwritten by any pixels drawn to the top window,
  497. they may simply have been left there when the window was mapped or
  498. exposed.
  499. .LP
  500. There is no way for a client to determine which pixels of a window have
  501. been updated by operations to that window (or its children).
  502. Thus there is no way to discover which pixels of a top window with
  503. background
  504. .B None
  505. are garbage,
  506. and even if there were there is no way to discover the correct pixel
  507. value or how to interpret it.
  508. The screen dump client simply has to live with the problem;
  509. its results cannot be guaranteed correct if any visible windows
  510. have background
  511. .B None .
  512. .LP
  513. There is one further problem.
  514. The protocol specification describes how a Pixmap or a single pixel
  515. value can be used as the border for a window.
  516. It does not specify which Visual and which Colormap are to be used to
  517. display these values.
  518. It appears that this is an oversight,  and that the Visual and the
  519. Colormap of the window are to be used to display its border.
  520. The dump client assumes this.
  521. .NH 2
  522. Dump Algorithm
  523. .LP
  524. We use the painter's algorithm,  creating an array of pixels to hold the
  525. output,  and painting the windows into it from the back forwards.
  526. .LP
  527. Each pixel in the output may be painted a number of times,  but the last
  528. time it is painted will be by the window on top at that pixel.
  529. Since this last pixel painted is not overlaid,
  530. we are assured that the pixels returned by GetImage will be good
  531. (subject to the background
  532. .B None
  533. problem).
  534. .LP
  535. Here is an outline of the algorithm;
  536. the code itself is shown in Appendix A:
  537. .Ip
  538. Create a data structure with one entry per pixel in the specified rectangle,
  539. and an empty list whose entries represent Colormaps in use.
  540. Each entry in the list is itself the head of a list of pixel values in use
  541. with that Colormap.
  542. .Ip
  543. GrabServer to prevent changes to the window tree while all this is going on.
  544. .Ip
  545. Start at the root,  and:
  546. .RS
  547. .Ip
  548. Use GetGeometry and GetWindowAttributes to find the details of
  549. the current window.
  550. .Ip
  551. If the current window is Viewable:
  552. .RS
  553. .Ip
  554. If the window's Colormap isn't in the list,  create an entry
  555. describing it,  and add it to the list.
  556. .Ip
  557. Use GetImage on the current window,  and for every pixel in
  558. the returned array:
  559. .RS
  560. .Ip
  561. Label every corresponding pixel in the data structure with the pixel value
  562. returned by GetImage,  and with this window's Colormap.
  563. .Ip
  564. If this is the first time we've seen this pixel value for this Colormap,
  565. use QueryColor to discover the RGB values that this window's Colormap
  566. maps the pixel value into,  and store the pixel value and RGB in the
  567. list of pixel values in use for this Colormap.
  568. .RE
  569. .Ip
  570. Use QueryTree to find the list of children of the current window and
  571. recurse,  starting with the head (bottom-most) of the list.
  572. .RE
  573. .RE
  574. .Ip
  575. UngrabServer,  we're finished with it.
  576. .Ip
  577. Write to the output the width and height of the rectangle,
  578. and the number of pixel values we've added to the Colormap lists
  579. (this is an upper bound on the number of the distinct colors
  580. in the output).
  581. .Ip
  582. For each pixel in the data structure we built:
  583. .RS
  584. .Ip
  585. Find the list entry for the Colormap the pixel is labelled with.
  586. .Ip
  587. In the list of pixel values in use for that Colormap,
  588. find the pixel value the pixel is labelled with.
  589. .Ip
  590. Write to the output the RGB value stored for its pixel value
  591. in the list of pixel values in use for the Colormap.
  592. .RE
  593. .NH 2
  594. Assessment of the Algorithm
  595. .LP
  596. This algorithm is about as simple as it can be while still getting
  597. the job done,  but it causes much more protocol traffic than is
  598. strictly required.
  599. .LP
  600. By making the very pessimistic assumption that a pixel overlaid by
  601. .I any
  602. other window is potentially garbage,
  603. it asks the server to return the value of each of these pixels
  604. more often than is essential.
  605. A more efficient algorithm would only regard pixels overlaid by non-inferiors
  606. or inferiors of different depth as potential garbage.
  607. .LP
  608. Space consumption may also be a problem.
  609. There are potentially up to $ 2 sup 32 $ different pixel values,
  610. and we must retain a list of each pixel value in use for every
  611. Colormap.
  612. Fortunately,
  613. the list of values in use cannot get longer than
  614. the $ [ w ~ times ~ h ] $ of the specified rectangle
  615. (in the case where every pixel in the rectangle is different),
  616. and will normally be much less.
  617. .NH
  618. The ``undump'' Client
  619. .LP
  620. The objective of the screen undump client is to
  621. restore the appearance of the rectangle of the screen that was
  622. dumped earlier.
  623. It may not in fact be possible to do this,  since the Visuals
  624. available to the undump program may not be capable of displaying
  625. all the colors in the original image.
  626. .LP
  627. The undump client has two main tasks:
  628. .Ip
  629. Choose an appropriate Visual and create a Colormap for it.
  630. .Ip
  631. Build an image in memory in which the RGB values have been
  632. converted to pixel values using the Colormap.
  633. .LP
  634. For each of these tasks,  we review the general problem and
  635. then focus on the specific features needed for the undump client.
  636. .NH 2
  637. Choosing a Visual
  638. .LP
  639. The server, during the connection handshake,  provides the following
  640. information for each Visual on each screen:
  641. .Ip
  642. The depth.
  643. .Ip
  644. The Visual class.
  645. .Ip
  646. The masks that identify the red,  green and blue sub-fields of the pixel
  647. value.
  648. .Ip
  649. The size (number of cells) of the Colormaps of the Visual.
  650. .Ip
  651. The number of bits in a red,  green or blue value that the server
  652. will regard as significant.
  653. .LP
  654. There can be no general rules for choosing a Visual;
  655. a particular application might regard any of these pieces of information
  656. as the most important factor.
  657. For example:
  658. .Ip
  659. Clients which want to play Colormap tricks,
  660. such as colormap animation,
  661. need writable Colormap cells,
  662. and thus a dynamic Visual.
  663. For them,  the class is the most important feature.
  664. .Ip
  665. Clients which require an exact color need a PseudoColor, DirectColor
  666. or TrueColor Visual.
  667. Other Visuals involve the server making an approximation to the requested
  668. RGB value.
  669. For these clients,  the class is the most important feature.
  670. .Ip
  671. Clients that
  672. .I really
  673. care about the exact color will also be interested in the number of
  674. significant bits,  which will tell them how closely the display can
  675. approximate the RGB value.
  676. .Ip
  677. Clients that require a certain number of colors to allow for contrast,
  678. but don't care about the exact colors,
  679. need a Visual with a Colormap large enough to hold the colors.
  680. For them,  the Colormap size is the most important feature.
  681. .LP
  682. Xlib
  683. .[
  684. gettys xlib 1988
  685. .]
  686. provides two utility routines to make selecting a suitable Visual easier,
  687. using the
  688. .I XVisualInfo
  689. structure shown in Figure 3.
  690. .KF
  691. .Ls
  692. .ta 8n 16n 24n 32n 40n
  693.     typedef struct {
  694.         Visual        *visual;
  695.         VisualID    visualid;
  696.         int        screen;
  697.         int        depth;
  698.         int        class;
  699.         unsigned long    red_mask;
  700.         unsigned long    green_mask;
  701.         unsigned long    blue_mask;
  702.         int        colormap_size;
  703.         int        bits_per_rgb;
  704.     } XVisualInfo;
  705. .Le
  706. .DS C
  707. Figure 3: The XVisualInfo Structure
  708. .DE
  709. .KE
  710. .LP
  711. A client that simply wants to select a Visual of a given depth and class
  712. can use
  713. .I XMatchVisualInfo() .
  714. The client provides a depth and a Visual class,  and an
  715. .I XVisualInfo
  716. structure describing one of the possibly many Visuals of that class
  717. and depth is returned.
  718. .LP
  719. A client that wants more detailed control over the selection of a Visual
  720. can use
  721. .I XGetVisualInfo() .
  722. The client constructs a template
  723. .I XVisualInfo
  724. structure,  filling in the fields it is interested in.
  725. An array of
  726. .I XVisualInfo
  727. structures is returned,
  728. one for each Visual that matches the specified fields.
  729. For example,  the code in Figure 4
  730. will find all PseudoColor Visuals with 256-entry
  731. Colormaps.
  732. .KF
  733. .Ls
  734. .ta 8n 16n 24n 32n 40n 48n 56n
  735.     {
  736.         XVisualInfo    vinfo_template,
  737.                 *vinfo_list;
  738.         int        num_matching_visuals;
  739.     
  740.         vinfo_template.class = PseudoColor;
  741.         vinfo_template.colormap_size = 256;
  742.     
  743.         vinfo_list = XGetVisualInfo(dpy,
  744.             VisualClassMask | VisualColormapSizeMask,
  745.             &vinfo_template, &num_matching_visuals);
  746.         if (vinfo_list == (VisualInfo *) 0) {
  747.             /* No such Visuals */
  748.         } else {
  749.             /* vinfo_list is an array of matches */
  750.         }
  751.     }
  752. .Le
  753. .DS C
  754. Figure 4:  Finding all 256-entry Colormap Visuals
  755. .DE
  756. .KE
  757. .LP
  758. In the case of the undump client,  we have a problem that is
  759. more complex than either of these two simple cases.
  760. We have a set of RGB values
  761. that we wish to display as well as the available Visuals will let
  762. us.
  763. We have an upper bound
  764. .I N
  765. on the number of colors,  but no other
  766. information about the colors\s-2\u\(dd\d\s0.
  767. .FS
  768. \(dd  Scanning the RGB values could generate other information,
  769. such as that all the R, G and B values were equal in a gray image.
  770. Doing so would make the code,  and the choice of a Visual too
  771. complex for a paper like this.
  772. .FE
  773. .LP
  774. Choosing a Visual capable of displaying
  775. .I N
  776. different RGB values takes four steps (the actual code is the
  777. routine
  778. .I FindVisual()
  779. in Appendix B):
  780. .Ip
  781. Rank the Visual classes in descending order of usability for
  782. our purposes:
  783. .RS
  784. .Ip
  785. TrueColor.
  786. A TrueColor Visual with large enough colormaps would be ideal
  787. for the dump client,  since it would not merely represent the
  788. required RGB values,  but it would not reserve private Colormap
  789. cells to do so.
  790. .Ip
  791. DirectColor & PseudoColor.
  792. These Visuals,  if their Colormaps are big enough,  can represent the
  793. RGB values we need,  but to do so they have to reserve private
  794. cells,  reducing the server resources available for other clients.
  795. .Ip
  796. StaticColor.
  797. A color Visual,  even though we have no control over the color values,
  798. is likely to make a better approximation than a GrayScale Visual which
  799. cannot display colors at all.
  800. .Ip
  801. GrayScale.
  802. This Visual,  if its Colormaps were big enough,  could make a monochrome
  803. approximation to the image better than a StaticGray Visual in which
  804. we would have no control over the shades of gray.
  805. .Ip
  806. StaticGray.
  807. If there's nothing else,  we'll have to make do with this.
  808. .RE
  809. .Ip
  810. Scan the list of Visuals returned by the server
  811. during the connection handshake,  and for each Visual class
  812. record the Visual with the largest Colormaps.
  813. Of course,  in the normal case,  only a few of the classes will
  814. exist,  and the others will be recorded as having a largest Colormap of
  815. size zero.
  816. .Ip
  817. In the rank order,  look for the smallest Visual with
  818. colormaps big enough to display the required number of colors.
  819. If one is available,  use it.
  820. .Ip
  821. Otherwise,  use the Visual with the largest Colormaps.
  822. Since none of the maps are big enough to display all the colors,
  823. the server will doing some approximation,
  824. and the bigger the map the better the approximation.
  825. .LP
  826. Note that we look for the
  827. .I smallest
  828. Visual that will do the job.
  829. This will ensure that the client uses no more resources than
  830. required to get its job done.
  831. .NH 2
  832. Converting RGB to pixel values
  833. .LP
  834. X provides three fundamentally different methods for converting RGB
  835. values to pixel values.  A client can:
  836. .Ip
  837. Request the server to perform the conversion and return a pixel value.
  838. The result is to associate a sharable,  read-only Colormap cell
  839. containing an approximation to the RGB values with the pixel value.
  840. .Ip
  841. Request the server to assign a writable Colormap cell and corresponding
  842. pixel value for the client's private use.
  843. The client can then set the Colormap cell to the RGB value.
  844. .Ip
  845. The client can predict the pixel value that will correspond to the
  846. RGB value,  using its knowledge of the contents of the Colormap.
  847. .LP
  848. The choice of a suitable method depends on the requirements of the
  849. application and on the class of the Visual it is using.
  850. .NH 3
  851. Server does conversion
  852. .LP
  853. The AllocColor request takes an RGB triple and a Colormap as an
  854. argument,  and returns a pixel index that points to a
  855. Colormap cell containing the best approximation the server can
  856. make to that RGB value,  and the actual RGB values that the cell
  857. contains.
  858. It does so by:
  859. .Ip
  860. If the Visual is static (StaticGray, StaticColor,  or TrueColor),
  861. it returns the cell in the map that is closest to the request RGB
  862. value.
  863. .Ip
  864. If the Visual is dynamic,  and the Colormap has free cells,  the
  865. server will allocate an cell,  mark it read-only,  and set it to
  866. the requested RGB value.
  867. If there are no free cells,
  868. the request will fail.
  869. .LP
  870. This technique can be used by applications except those for
  871. which the
  872. .I exact
  873. representation of a color is of primary importance,
  874. or which use very large numbers of colors.
  875. The reasons for preferring this method are that it will work on
  876. any Visual,  and that it makes the most efficient use of the
  877. server's resources.
  878. .LP
  879. Note,  however,  that since AllocColor returns a value,  it
  880. requires a round-trip to the server and is therefore slow.
  881. Note also that AllocColor may fail,
  882. if the Visual is dynamic and there are no free cells in the colormap.
  883. If it does fail,
  884. the normal response is to move the client's allocated cells from
  885. the full colormap to a newly created one using CopyColormapAndFree.
  886. .NH 3
  887. Client sets color
  888. .LP
  889. If the Visual is dynamic,
  890. clients can use AllocColorCells or AllocColorPlanes to reserve one
  891. or more pixel values for their private use.
  892. If the allocation succeeds,  the pixel values will point to private,
  893. writable Colormap cells.
  894. The client can then use StoreColors to set the RGB values of these
  895. cells to exactly the values it desires.
  896. .LP
  897. This technique is more efficient than AllocColor,
  898. because a round-trip to the server is needed only for the initial allocation
  899. rather than every time a color is modified.
  900. However,
  901. it should be used only if it essential to the application because
  902. .Ip
  903. it will work only on a dynamic Visual,
  904. .Ip
  905. it consumes server resources that no other client can use until they
  906. are released,
  907. .Ip
  908. it can fail and measures must be taken to cope with this possibility.
  909. .LP
  910. In general,  clients using this technique should create a private Colormap,
  911. perhaps using CopyColormapAndFree to preserve any pre-allocated cells.
  912. Ideally,
  913. the default Colormap for each Visual should be left for clients using the
  914. other techniques to maximize the sharing of resources.
  915. Unfortunately,  the protocol defines a default Colormap only for the Visual
  916. of the root window.
  917. .NH 3
  918. Client predicts pixel value
  919. .LP
  920. There are two circumstances in which a client can determine the pixel
  921. value corresponding to a given RGB value
  922. .I without
  923. a round-trip to the server.
  924. To do so,  it must have knowledge of the contents of the Colormap:
  925. .Ip
  926. If the Visual is TrueColor,
  927. the Colormap is known to provide linear ramps in each primary color.
  928. The R, G and B values can thus be adjusted to the match the corresponding
  929. sub-field mask,  and or-ed together to make the pixel value.
  930. .Ip
  931. If the Colormap is one of the set of ``standard'' Colormaps
  932. a similar calculation can be performed.
  933. Applications wishing to use one of these Colormaps look for a property
  934. describing it on the root window of the screen;
  935. if the property is not found the application creates a suitable Colormap
  936. and a property to describe it.
  937. .LP
  938. In particular,
  939. clients should find a property called RGB_DEFAULT_MAP on the root
  940. window of a multi-visual screen
  941. containing an array of XStandardColormap structures describing a
  942. default colormap for each visual,
  943. and the linear RGB ramps within it.
  944. They can use this to share colors with other applications on the screen;
  945. this is the preferred method for most clients.
  946. .NH 2
  947. The Undump Algorithm
  948. .LP
  949. Here is an outline of the algorithm;
  950. the code itself is shown in Appendix B:
  951. .Ip
  952. Read in the width,  height,  number of colors & RGB values.
  953. .Ip
  954. Choose an appropriate Visual
  955. .Ip
  956. Create a Colormap for the chosen Visual.
  957. .Ip
  958. Create an image in memory to hold the pixel values that will
  959. eventually appear in the window.
  960. .Ip
  961. For each pixel in the data:
  962. .RS
  963. .Ip
  964. Convert the RGB values for the pixel into a pixel value,
  965. using the AllocColor request.
  966. .Ip
  967. Store the pixel value into the corresponding location in the
  968. image.
  969. .RE
  970. .Ip
  971. Create and map a window which uses the Colormap.
  972. .Ip
  973. Paint any exposed part of the window with the pixel values
  974. from the image.
  975. .NH 2
  976. Assessment of the Algorithm
  977. .LP
  978. Once again,  this algorithm is about as simple as it can be
  979. and still get the job done.
  980. As a result,  it is grossly inefficient.
  981. It makes the pessimistic assumption that every pixel in the
  982. image is a different color,  and calls AllocColor to convert its RGB
  983. values into a pixel value.
  984. Of course,  it is likely that many pixels are the same color,
  985. and calling AllocColor only for every distinct color would reduce the
  986. traffic considerably.
  987. .LP
  988. One problem is that this client creates its own Colormap.
  989. If the default Colormap mechanism worked for multiple Visuals,
  990. we could have used the appropriate default Colormap.
  991. Ideally,  clients should share Colormaps to improve the chance they
  992. will appear in their correct colors.
  993. We should have used the RGB_DEFAULT_MAP or RGB_BEST_MAP properties
  994. to share a Colormap with other similar clients.
  995. .LP
  996. The client will work on every Visual type,  in most cases providing the
  997. best match available for the colors in the image.
  998. There is,  however,  one case in which the match will be less than
  999. optimal.
  1000. If the Visual is PseudoColor and is too small to accommodate the number
  1001. of colors in the image,
  1002. the first colors encountered in the right-to-left within top-to-bottom
  1003. scan of the image will get exact colors as new read-only cells
  1004. are allocated by AllocColor.
  1005. At some point,
  1006. the map will fill up,
  1007. and the next AllocColor call will fail.
  1008. Since we found the largest visual,
  1009. there is nothing to do but give up.
  1010. .LP
  1011. The Visual selection process has two problems.
  1012. For the TrueColor and DirectColor cases,
  1013. it pessimistically assumes that all the distinct colors in the image differ
  1014. only in one component,  and will thus overestimate the size of the Colormap
  1015. required.
  1016. For example,  suppose we have a blue image with 24 distinct colors;
  1017. all 24 have the same Red and Green values,  differing only in their Blue value.
  1018. We would need a Colormap with 24 entries for Blue,  but only 1-entry
  1019. maps for Red and Green.
  1020. In practice,  it is likely that the color distribution will be more even and
  1021. smaller maps would suffice.
  1022. .LP
  1023. Further,  it is complicated by the fact that the number of distinct colors
  1024. is only an upper bound.
  1025. Consider a dump of a screen with an 8-bit PseudoColor Visual and a 1-bit
  1026. StaticGray Visual.
  1027. Assume that the image in the PseudoColor Visual had 256 different colors,
  1028. two of which were white and black.
  1029. The dump client would not realize that the white and black of the StaticGray
  1030. Visual were the same as the white and black of the PseudoColor Visual
  1031. and would record the number of colors as 258.
  1032. Undumping to the same display,  it would regard the PseudoColor Visual as
  1033. inadequate to represent the 258 colors.
  1034. .LP
  1035. Better analysis of the set of RGB values to be displayed would solve both
  1036. problems,  but would make the program too complex for this paper.
  1037. .NH
  1038. Visuals and the Toolkit
  1039. .LP
  1040. The attention paid by the X Toolkit Intrinsics to the problem
  1041. of specifying Visuals is evident from the fact that the word Visual
  1042. does not appear in the index to the first version of the Intrinsics manual.
  1043. .[
  1044. toolkit intrinsics 1988
  1045. .]
  1046. In R4,
  1047. this was remedied.
  1048. .[
  1049. asente swick 1990
  1050. .]
  1051. .LP
  1052. The Window for a Widget is created during the process of 
  1053. .I realizing
  1054. the Widget,
  1055. and the Visual to use has to be selected as part of this process.
  1056. Different Widget classes will differ as to how they choose a Visual.
  1057. All Athena Widgets use CopyFromParent as their Visual selection,
  1058. deferring the choice to their parent.
  1059. The root of the Widget tree is a so-called Shell Widget,
  1060. which in the Intrinsics implementation itself by default inherits its Visual
  1061. from its parent,  in this case the root.
  1062. From R4 on,
  1063. Shell widgets have a XtNvisual resource than can be used to specify the
  1064. visual to be used by widgets within the shell's tree.
  1065. .LP
  1066. The core information,  which all Widgets possess,  includes a Colormap.
  1067. For the Athena Widgets,  this had better be a Colormap from the root's
  1068. Visual,  or Xlib errors will occur.
  1069. This Colormap is used to convert RGB values to pixels for the Widget,
  1070. using the AllocColor technique.
  1071. One might think that it would be possible to realize a Widget in a Visual
  1072. other than the root's by giving it a Colormap from that Visual,  but
  1073. this will not work.
  1074. .LP
  1075. A Widget class that needed some Visual other than its Shell's
  1076. would have to implement its own realize procedure,  and make the choice there.
  1077. The choice algorithm would be the same for all instances of the Widget,
  1078. but this does not mean that all instances would have to have the same Visual.
  1079. This sounds onerous,  but it is in fact the correct approach.
  1080. As we showed above,
  1081. the algorithm for choosing an appropriate Visual is application-specific;
  1082. it would not be possible to wire-in to the Intrinsics a single algorithm
  1083. that would satisfy everyone.
  1084. .NH
  1085. Conclusion
  1086. .LP
  1087. The X11 color model provides powerful access to the capabilities
  1088. of different types of display hardware.
  1089. Used carelessly,
  1090. this access can lead to programs which run only in the
  1091. environment in which they were developed.
  1092. .LP
  1093. All but the simplest X11 clients must take care to choose the most
  1094. suitable Visual for their purposes,
  1095. and to adapt their behavior to its capabilities.
  1096. We have presented the techniques for doing so for a simple
  1097. application,  but more complex applications will require a wider
  1098. range of techniques.
  1099. More work is needed to develop these.
  1100. .SH
  1101. Acknowledgements
  1102. .LP
  1103. Thanks are due to James Gosling,  who helped to develop our understanding
  1104. of these issues,  and who designed the multi-Visual and Colormap capabilities
  1105. of the X11/NeWS server,
  1106. to Jeff Vroom,  who spotted the problem of the default colormap,
  1107. to Bob Scheifler,  who clarified several obscure points,
  1108. and to the Usenix reviewers.
  1109. .[
  1110. $LIST$
  1111. .]
  1112. .SH
  1113. Appendix A: Dump Program
  1114. .LP
  1115. .Ls
  1116. .ta 8n 16n 24n 32n 40n 48n 56n 64n
  1117. .so xsd.c
  1118. .Le
  1119. .SH
  1120. Appendix B: Undump Program
  1121. .LP
  1122. .Ls
  1123. .ta 8n 16n 24n 32n 40n 48n 56n 64n
  1124. .so xsud.c
  1125. .Le
  1126.