File: xmhtml_prog.html

package info (click to toggle)
xmhtml 1.1.10-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,296 kB
  • sloc: ansic: 70,372; makefile: 480; sh: 176; perl: 36
file content (2154 lines) | stat: -rw-r--r-- 84,553 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
	<TITLE>XmHTML Programmers Guide</TITLE>
	<META HTTP-EQUIV="Keywords" CONTENT="XmHTML, HTML, Motif, Widget, Programming, Linux">
	<META HTTP-EQUIV="Reply-to" CONTENT="ripley@xs4all.nl">
	<META HTTP-EQUIV="Description" CONTENT="This document contains XmHTML's programmers Guide. XmHTML provides an interactive Motif widget capable of displaying HTML 3.2 text.">
	<META NAME="Author" CONTENT="Koen D'Hondt">
	<META NAME="Copyright" content="1995-1997 by Ripley Software Development">
	<META NAME="Source" content="$Source$">
	<META NAME="Revision" content="$Revision$">
<!--
	<META NAME="Font" content="helvetica">
	<base href="http://www.xs4all.nl/~ripley/eXode/">
-->
	<link rev="made" href="mailto:ripley@xs4all.nl">
	<link rel="home" href="http://www.xs4all.nl/~ripley">
	<link rel="index" href="XmHTML.html">
	<link rel="previous" href="legals.html">
	<link rel="down" href="parser_prog.html">
	<link rel="next" href="convenience.html">
	<link rel="copyright" href="copyrights.html">
	<link rel="TOC" href="progguide.html">
</HEAD>

<BODY BGCOLOR="#FFFFFF" TEXT="#000000">

<p>

<div align="right">
<b><font face="helvetica, arial" size="7">Chapter 2<br>
	XmHTML Widgets</font></b>
</div>
<p>&nbsp;<p>

Have you ever wanted to write an application capable of displaying HTML
documents, went out to find a Widget which offered HTML display capabilities
and finally give up on your wonderfull idea when no such widget seemed to
be available? Maybe you did find a HTML widget but were not satisfied with
its capabilities? With the XmHTML Widget described in this chapter you no
longer have to despair.
<p>

With the XmHTML Widget one can create applications that range from simple
HTML viewers to full-blown WWW browsers. The XmHTML Widget offers a widget
capable of displaying HTML documents and, as one would expect, allows full
interactive use of HTML documents thru various callback resources and 
convenience functions. Besides of being able to display HTML documents, 
displaying of plain text and images is also supported.
<p>

XmHTML widgets provide the following mechanisms for program control:
<p>

<ul>
<li>Resources that access the widget's content and can alter it's appearance.
<li>Callback resources that allow navigation through and between HTML documents
	when hyperlinks are activated.
<li>Callback resources that provide both visual and content information about
	the widget's text.
<li>Keyboard management methods that control output (paging style).
<li>Convenience routines allowing quick and easy ways to load images, scroll
	through the widget's text and access document information.
</ul>
<p>

XmHTML widgets implement the full HTML 3.2 standard as well as a few
extensions. The chapter on <a href="extensions.html">HTML Extensions</a> 
lists the supported extensions. One supported extension that is worthwhile to
mention is the <font face="fixed">&lt;FRAMESET&gt;</font> extension.
<p>

The current implementation of the XmHTML widget does have its limitations
though. The most important features lacking in the current release
(1.0.22 Alpha) are support for HTML tables and progressive document
loading. All these features will be added in due time.
<p>

As you will notice in this chapter, the behaviour and name of a number of
XmHTML's resources and convenience functions closely resemble those of Motif's
Text widget. The first reason for this similarity is that both widget's display
text. The second reason is that, if you are already familiar with Motif's Text
widget, the interface to a XmHTML widget will also look familiar and thus
learning how to use a XmHTML widget will be a bit easier.

<h1><a name="basics"><font face="helvetica, arial">
	2.1 The Basics of a XmHTML Widget
</font></a></h1>

To understand and appreciate most of the material described in this chapter,
it is important to address some of the basic resources and functions provided
by the XmHTML widget. The widget's text and HTML verification process, document
fonts, dimensions of the widget and hyperlink resources are among the most
important. We begin with how to create a standard XmHTML widget.

<h2><a name="creating"><font face="helvetica, arial">
	2.1.1 Creating a XmHTML Widget
</font></a></h2>

Applications that wish to use XmHTML widgets need to include the file
<i>&lt;XmHTML.h&gt;</i>. You can create a standard XmHTML widget using
the <tt>XtVaCreateManagedWidget()</tt> function:

<pre>
	Widget html_w;

	html_w = XtVaCreateManagedWidget("name", xmHTMLWidgetClass, parent,
		<i>resource-value pairs</i>,
		NULL);
</pre>

The <i>resource-value pairs</i> can be any number of resources specific to the
XmHTML widget or its superclasses. Please note that the XmHTML widget is
subclassed from the Manager widget class.
<p>

Another way of creating a standard XmHTML widget is by using the
<tt>XmCreateHTML()</tt> convenience function:

<pre>
	Widget html_w;

	html_w = XmCreateHTML(parent, "name", <i>args</i>, <i>nargs</i>);
</pre>

The <i>args</i> argument can be any number of resource-value pairs specified
using the <tt>XtSetArg</tt> function. <i>nargs</i> specifies how many
resource-value pairs are contained in the <i>args</i> argument.

<h2><a name="text"><font face="helvetica, arial">
	2.1.2 The XmHTML Widget's Text
</font></a></h2>

The first thing to learn about the XmHTML widget is how to access its internal
text storage. The most simple method to do this is by using the
<tt>XmNvalue</tt> resource. Unlike most widgets in the Motif toolkit that use
text, the XmHTML widget does not use compound strings for its value. Instead,
the value is specified as a regular C string as shown in example 2-1.
<p>

<i>Example 2-1. The simple_html.c program</i><br>
<pre>
/* simple_html.c -- Create a minimally configured XmHTML widget */
#include &lt;XmHTML.h&gt;

main(int argc, char **argv)
{
	Widget toplevel;
	XtAppContext app;

	toplevel = XtVaAppInitialize(&amp;app, "Demos", NULL, 0,
		&amp;argc, argv, NULL, NULL);

	XtVaCreateManagedWidget("html", xmHTMLWidgetClass, toplevel,
		XmNvalue, "&lt;html&gt;&lt;body&gt;A minimally configured XmHTML widget."
			"&lt;/body&gt;&lt/html&gt;",
		NULL);

	XtRealizeWidget(toplevel);
	XtAppMainLoop(app);
}
</pre>

This short program simply creates a XmHTML widget whose initial value is set
to <b>"A minimally configured XmHTML widget."</b> (See Figure 2-1).
<p>

<img src="../Images/book/simple_html.gif" alt="[A Simple HTML Widget]">
<br>
<i>Figure 2-1. simple_html.c: a minimally configured XmHTML widget</i>

<h3><font face="helvetica, arial">
	HTML Verification
</font></h3>

As one can see in the above example, the value of the <tt>XmNvalue</tt> resource
contains five HTML elements: four markup and one text element. This brings us
to one of the most important aspects of the XmHTML widget: it is a widget for
displaying HTML documents. HTML documents are text documents written in the
<i>HyperText Markup Language</i>, which is a language composed of a set of
elements that define a document and guide its display.
<p>

In order for XmHTML to display such a document properly, it is necessary that
the widget verifies the correctness of these markup elements. It does this by
comparing the contents of the document that is to be displayed against the
now official W3C HTML 3.2 recommendation (referred to as the HTML 3.2
standard). This standard defines both appearance and content of each
markup element. During this verification process (which is performed
before anything is displayed), the widget goes thru great lengths as to
ensure that the document adheres to this standard. As such, the widget
is capable of modifying the specified <i>markup</i> elements substantially
(it will never modify text elements). The disadvantage of this document
verification is that a document might not look as expected, but the main
advantage is that even the most horrid HTML document will be displayed.
<p>

A detailed description of this document verification and repair process is
given in the next chapter, so we will only mention that the more a document
adheres to the HTML 3.2 standard, the less the widget will modify the markup
elements.

<h3><font face="helvetica, arial">
	Setting a XmHTML Widget's Text
</font></h3>

The initial value of the <tt>XmNvalue</tt> resource may be set either at
initialization time (as in example 2-1) or by using <tt>XtVaSetValues</tt>:

<pre>
	XtVaSetValues(html_w, XmNvalue, <i>text</i>, NULL);
</pre>
This resource always represents the entire text of the widget.
<p>

Another method for setting the text in a XmHTML widget is by using the
convenience routine <tt>XmHTMLTextSetString</tt>:

<pre>
	void
	XmHTMLTextSetString(html_w, value)
		Widget  html_w;
		char   *value;
</pre>

Although the two methods produce the same results, the convenience routine may
be more efficient since it accesses the internals of the widget directly
(The <tt>XtVaSetValues()</tt> method involves going through the X Toolkit
Intrinsics). On the other hand, if you are also setting many other resources
at the same time, the <tt>XtVaSetValues</tt> method is better since it saves
the overhead of multiple function calls (All resources can be set in a single
call).
<p>

Whichever function you use, the <i>value</i> (however it is provided) is
copied into the internals of the widget. This is important to known if you have
provided the <i>value</i> via an allocated memory buffer: once the text is set
in the widget, you can safely free this memory buffer.
<p>

A XmHTML widget's may contain large amounts of text provided there is enough
memory available on the computer running the client application. The upper
limit on the number of bytes a XmHTML widget may have is given by the maximum
value of an unsigned int (4 gigabyte on 32 bit systems), so it is more likely
that the user's computer will run out of memory before the XmHTML widget's
maximum capacity is reached.

<h3><font face="helvetica, arial">
	Getting a XmHTML Widget's Text
</font></h3>

XmHTML widget's provide several methods for obtaining text. Before learning
how to get the widget's text however, it is important to make a distinction
between the <i>source text</i> and the <i>displayed text</i>. The source text
is the text you have set into a XmHTML widget by using the <tt>XmNvalue</tt>
resource (or by using the <tt>XmHTMLTextSetString()</tt> convenience function),
while the displayed text is the source text after HTML verification
has taken place. This distinction is important since XmHTML widget's will
never modify the source text but instead create a new HTML document while the
HTML verification process is taking place.
<p>

<font face="helvetica, arial" size="3">[Note: A new HTML document is not
actually created: when text is set in a XmHTML widget, the HTML parser
translates the source text to a list of internal objects. The new HTML document
that is mentioned in the above paragraph only exists in theory but can be 
created upon request as we will soon see.]</font>
<p>

You might ask yourself why this distinction is important. The answer is that 
it depends on the type of application you are using a XmHTML widget for.
Lets assume you are using a XmHTML widget in an application that displays
HTML documents you have retrieved via a network layer (a WWW browser for
example). When the user of your application wishes to save the document he has
been viewing, it is most likely he wishes to save the original document and
not the verified document. On the other hand, when you are using a XmHTML
widget in an application intended for writing and/or verifying HTML documents,
the most obvious thing a user would want to save is his verified document.
<p>

<h4><font face="helvetica, arial">
	Getting the Source Text
</font></h4>

So how does one go about getting a XmHTML widget's text? To get the widget's
<i>source</i> text, you can use either <tt>XtVaGetValues()</tt> or the
<tt>XmHTMLTextGetSource()</tt> convenience function. Both methods return the
value of the <tt>XmNvalue</tt> resource. The value returned is a pointer
to the internal text storage, which may never be freed nor
modified. The code fragment below demonstrates how to use the convenience
function:

<pre>
	String text_p;

	if((text_p = XmHTMLTextGetSource(html_w)) != NULL)
	{
		/* Save, display the text, but never modify or free it */
	}
</pre>

Or, by using the Xt function <tt>XtVaGetValues()</tt>:

<pre>
	String text;

	XtVaGetValues(html_w, XmNvalue, &amp;text_p, NULL);
</pre>

Similar to using the <tt>XmHTMLTextSetString()</tt> convenience function to
set a XmHTML widget's text, using the <tt>XmHTMLTextGetSource()</tt> to get a
XmHTML
widget's text may be more efficient since it accesses the internals of the
widget directly instead of going through the X Toolkit Intrinsics.
<p>

<font face="helvetica, arial" size="3">[Note: It is also worthwhile to mention
that all of the <tt>XmHTML...</tt> convenience functions access the internals of
the XmHTML widget directly. None of them involves going through the X Toolkit
Intrinsics.]</font>
<p>

If you want to modify the source text, or you just want a copy of the text
that you can modify for other reasons, then you must copy the text
into your own local dataspace:

<pre>
	char *text_p, buf[1024];

	text_p = XmHTMLTextGetSource(html_w);

	(void)strncpy(buf, text_p, 1024);
	/* modify "buf" all you want */
</pre>

Here, we don't know how much text <tt>text_p</tt>
points to, but for purposes of this demonstration, we assume it's not more
than 1024 bytes. Just to be sure that we don't cause an overflow of 
<tt>buf</tt>, we use <tt>strncpy()</tt>. Let me stress that, unless you are
intimately familiar with the nature of the XmHTML widget your are using, it is
unwise to make general assumptions about the amount of text you are getting.

<h4><font face="helvetica, arial">
	Getting the Displayed Text
</font></h4>

The method to get the <i>displayed text</i> is very similar to the Motif
Text <tt>XmTextGetString()</tt> convenience function:
<tt>XmHTMLTextGetString()</tt>.
Both functions allocate enough space (using <tt>XtMalloc()</tt>) to contain
all the text and return a pointer to this newly allocated area. While the
pointer can be modified any way you like, you must free it using
<tt>XtFree()</tt> when you are through using it. The code fragment below
demonstrates how this function may be used:

<pre>
	String text_p;

	if((text_p = XmHTMLTextGetString(html_w)) != NULL)
	{
		/*
		* Allocated memory returned.
		* do anything with "text_p" you want.
		*/
		XtFree(text_p);
		/* we *must* free "text" or there will be a memory leak */
	}
</pre>

This convenience function returns a HTML document created from the
XmHTML widget's internal representation of the original source document after
HTML verification has taken place. Depending on the adherance to the HTML 3.2
standard of the original source document, the newly created HTML document may
or may not differ from the original source document. If there is a difference,
it will only be found in the markup elements; XmHTML widget's never modify 
text elements.
<p>

Getting the displayed text of a XmHTML widget is potentially an expensive
operation if the widget contains large amounts of text. A XmHTML widget
needs to create a HTML document from the internal representation every time
<tt>XmHTMLTextGetString()</tt> is called. 

<h2><a name="dimensions"><font face="helvetica, arial">
	2.1.3 XmHTML Widget's Dimensions
</font></a></h2>

Let's return to Example 2-1 and examine more closely what is exposed to the
user. As you can notice from the output of the program (shown in Figure
2-1), a vertical scrollbar is displayed and the text is not entirely visible:
the user has to drag the vertical scrollbar to see all the text contained in
the XmHTML widget. When no size has been specified, the width of a
XmHTML widget defaults to 20 ex (a <i>T<sub>E</sub>X</i> measure for average
character width) and the height of a single line in the default font.
<p>

You specify the size of a XmHTML widget by using the <tt>XmNwidth</tt> and
<tt>XmNheight</tt> resources (which a XmHTML widget inherits from the 
<tt>Core</tt> widget), as shown in Example 2-2:
<p>

<i>Example 2-2. The simple_html2.c program</i><br>

<pre>
/* simple_html2.c -- Create another minimally configured XmHTML widget */
#include &lt;XmHTML.h&gt;

main(int argc, char **argv)
{
	Widget toplevel;
	XtAppContext app;

	toplevel = XtVaAppInitialize(&amp;app, "Demos", NULL, 0,
		&amp;argc, argv, NULL, NULL);

	/* create a XmHTML widget but this time we specify a size */
	XtVaCreateManagedWidget("html", xmHTMLWidgetClass, toplevel,
		XmNvalue, "&lt;html&gt;&lt;body&gt;Another minimally configured XmHTML "
			"widget.&lt;/body&gt;&lt;/html&gt;",
		XmNwidth, 200,
		XmNheight, 75,
	NULL);

	XtRealizeWidget(toplevel);
	XtAppMainLoop(app);
}
</pre>

The output of this program is shown in Figure 2-2.
<p>

<img src="../Images/book/simple_html2.gif" alt="[Another Simple HTML Widget]">
<br>
<i>Figure 2-2. simple_html2.c: another minimally configured XmHTML widget</i>
<p>

The specified width and height are only used at initialization. Once the
application is up and running, the user can resize windows and effectively
change those dimensions.
<p>

<h3><a name="autosize"><font face="helvetica, arial">
	2.1.3.1 Autosizing a XmHTML Widget
</font></a></h3>

As you can see in Figure 2-2, the widget's text is now entirely visible
but a vertical scrollbar is still present. We could remove this vertical 
scrollbar by obtaining a handle to it and then unmanaging it, but another and
more subtle way to remove the vertical scrollbar is to use the autosizing
feature of a XmHTML widget as shown in Example 2-3.
<p>

<i>Example 2-3. The autosize_html.c program</i><br>

<pre>
/* autosize_html.c -- Demonstrate the autosizing feature of a XmHTML widget */
#include &lt;XmHTML.h&gt;

main(int argc, char **argv)
{
	Widget toplevel;
	XtAppContext app;

	toplevel = XtVaAppInitialize(&amp;app, "Demos", NULL, 0,
		&amp;argc, argv, NULL, NULL);

	/* make sure we may resize ourselves */
	XtVaSetValues(toplevel, XmNallowShellResize, True, NULL);

	/* create a XmHTML widget but this time enable autosizing */
	XtVaCreateManagedWidget("html", xmHTMLWidgetClass, toplevel,
		XmNvalue, "&lt;html&gt;&lt;body&gt;An AutoSizing XmHTML widget.&lt;/body&gt;&lt;/html&gt;",
		XmNresizeWidth, True,
		XmNresizeHeight, True,
	NULL);

	XtRealizeWidget(toplevel);
	XtAppMainLoop(app);
}
</pre>

The output of this program is shown in Figure 2-3.
<p>

<img src="../Images/book/autosize_html.gif" alt="[An Autosizing HTML Widget]">
<br>
<i>Figure 2-3. autosize_html.c: an autosizing XmHTML widget</i>
<p>

When looking at Example 2-3, we notice a few things that are of interest. First
of all, there is the <tt>XmNallowShellResize</tt> resource. The value of this
resource determines whether a <tt>Shell</tt> widget (or any of its subclasses,
in this case a <tt>topLevelShellWidget</tt>) will honor geometry requests from
its children. Since we want the XmHTML widget to compute its own size, we
must set this resource to <tt>True</tt> (it is <tt>False</tt> by default).
<p>

The second and most interesting thing to notice are the
<tt>XmNresizeWidth</tt> and
<tt>XmNresizeHeight</tt> resources. These resources
control the autosizing feature of XmHTML widgets. The first enables autosizing
in horizontal direction and the latter in vertical direction. When the
<tt>XmNresizeWidth</tt> resource is set to <tt>True</tt>,
XmHTML widget's base their initial width on the width of the longest
text element in the source document, with a maximum of 80 characters.
XmHTML widget's with autosizing enabled will never cover the entire screen:
the maximum dimensions a XmHTML widget take will never exceed 80% of 
the available screen dimensions.
<p>

In strong contrast with specifying the dimensions of XmHTML widget's using
the <tt>XmNwidth</tt> and <tt>XmNheight</tt> resources, autosizing is
persistent: When the user resizes a window, the dimensions of a XmHTML widget
are not affected. Autosizing remains effective as long as the autosizing
resources are set.
<p>

You should use the autosizing feature of XmHTML widget's sparingly. Dynamic
resizing of widgets is generally considered as poor design. This is especially
true of widgets in a Shell or Dialog with other elements in it.
<p>

An example of acceptable use of dynamic resizing would be when a XmHTML widget
is used in a popup dialog used for displaying small amounts of text (such as
explanation of terminology in a Hypertext Help system).

<h3><a name="dimension_by_resource"><font face="helvetica, arial">
	2.1.3.2 XmHTML Widget's Dimensions and Resources
</font></a></h3>

As we will see in section 2.1.5, <a href="#children">XmHTML Children</a>, a
XmHTML widget creates three subwidgets: a DrawingArea and two scrollbars.
<p>

When a XmHTML widget is created, the size of the DrawingArea is set explicitly
by the widget itself, but it uses the Motif default values when it creates
the scrollbars. It is important that you realize this when you set the
dimensions of a XmHTML widget by means of application-wide fallback resources
or when specifying them in a resource file: if you specify the dimensions of a
XmHTML widget using resource wildcarding you can be sure to expect
unwanted behaviour whenever text is set into the widget.
<p>

The correct way to specify the widget dimensions is as follows:

<pre>
static String fallbackResources[] = {
	"*XmHTML.width:       575",
	"*XmHTML.height:      600",
};
</pre>

This will only set the width of the DrawingArea subwidget to 575 pixels and the
height to 600 pixels, leading to the expected behaviour.
<p>

If on the other hand you incorrectly specify the dimensions as follows:

<pre>
static String fallbackResources[] = {
	"*XmHTML*width:       575",
	"*XmHTML*height:      600",
};
</pre>

you are not only setting the dimensions of the DrawingArea subwidget but 
also the dimensions for every subwidget created by a XmHTML widget. Needless
to say that this kind of behaviour is unwanted. The correct way to specify
the dimensions of both a XmHTML widget and its ScrollBar subwidgets is as
follows:

<pre>
static String fallbackResources[] = {
	"*XmHTML.width:       575",
	"*XmHTML.height:      600",
	"*XmHTML*verticalScrollBar.width:       25",
	"*XmHTML*horizontalScrollBar.height:    25",
};
</pre>
<p>

<font face="helvetica, arial" size="3">[Note: although it is possible to
use resource wildcarding to set the dimensions of a XmHTML widget when the
width and height of a ScrollBar are explicitly set, it is advisable that
this is never done. The problem is not limited to the dimensions of the
ScrollBars subwidgets but extends to any subwidgets a XmHTML widget creates
when it encounters a HTML document with a &lt;FORM&gt;&lt;/FORM&gt; 
declaration in it.]
</font>

<h2><a name="scrolling"><font face="helvetica, arial">
	2.1.4 Document Scrolling
</font></a></h2>

Adding document scrolling to XmHTML widget's is easy: you don't. If you look
at the output of Example 2-1 (Figure 2-1), you will notice that a vertical
scrollbar is present while we didn't instruct the XmHTML widget to add one.
When the XmHTML widget was created it noticed that it wasn't high enough to
display all of the text and thus it added a vertical scrollbar to allow the
user to view all of the text by dragging the scrollbar. If you resize the
window vertically, the vertical scrollbar will disappear when the widget is
high enough to contain all text (including the horizontal and vertical margins).
<p>

The behaviour you have observed in Example 2-1 is the default behaviour for
the XmHTML widget: when not all of the text can be fitted in the available
dimensions, a horizontal and/or vertical scrollbar is added, and when all text
can be fitted in the available dimensions, the horizontal and/or vertical
scrollbar is removed.
<p>

As there might be cases where you want the presence of a vertical scrollbar
while one is not required, you can force the presence of a vertical scrollbar
by using the <tt>XmNscrollBarDisplayPolicy</tt> resource as shown in the
following example:
<p>

<i>Example 2-4. The forced_html.c program</i><br>
<pre>
/* forced_html.c -- Force the display of the vertical scrollbar */
#include &lt;XmHTML.h&gt;

main(int argc, char **argv)
{
	Widget toplevel;
	XtAppContext app;

	toplevel = XtVaAppInitialize(&amp;app, "Demos", NULL, 0,
		&amp;argc, argv, NULL, NULL);

	/* create a XmHTML widget but this time we specify a size */
	XtVaCreateManagedWidget("html", xmHTMLWidgetClass, toplevel,
		XmNvalue, "&lt;html&gt;&lt;body&gt;A minimally configured "
			"XmHTML widget.&lt;/body&gt;&lt;html&gt;",
		XmNwidth, 200,
		XmNheight, 75,
		XmNscrollBarDisplayPolicy, XmSTATIC,
		XmNscrollBarPlacement, XmTOP_LEFT,
		XmNmarginWidth, 5,
		XmNmarginHeight, 5,
        NULL);

	XtRealizeWidget(toplevel);
	XtAppMainLoop(app);
}
</pre>

The <tt>XmNmarginWidth</tt> and <tt>XmNmarginHeight</tt> resources determine the
spacing between the outer borders of a XmHTML widget and the displayed text.
For demonstration purposes they have been set to a smaller value than the
default value of 20. If you compile and run this program you will see that a
vertical scrollbar is present and stays present when the widget is resized,
even when the widget is high enough to contain all text.
<p>

Example 2-4 also shows the <tt>XmNscrollBarPlacement</tt> resource. This
resource controls the placement of both horizontal and vertical scrollbar. In
this case the vertical scrollbar is placed on the left side of the window and
the horizontal scrollbar is placed on top of the window (making the window
smaller will show the horizontal scrollbar). Possible values for this resource
are:
<p>
<ul>
<li><tt>XmTOP_LEFT:</tt> vertical ScrollBar on left; horizontal on top;
<li><tt>XmBOTTOM_LEFT:</tt> vertical ScrollBar on left; horizontal on bottom;
<li><tt>XmTOP_RIGHT:</tt> vertical ScrollBar on right; horizontal on top;
<li><tt>XmBOTTOM_RIGHT:</tt> vertical ScrollBar on right; horizontal on bottom;
</ul>
<p>

XmHTML widget's do not provide any way to force the display of a horizontal
scrollbar, you can only control it's placement.

<h4><a name="scrolling"><font face="helvetica, arial">
	Keyboard Scrolling
</font></a></h4>

XmHTML widget's implement a full keyboard navigation interface by installing a
number of translations. On most keyboards, the arrows provide the same behaviour
as dragging the scrollbars while the PageUp and PageDown keys scroll through a 
document a page at a time. Additional keys are also available, see the XmHTML
Reference Manual for the complete set of translations that XmHTML widget's
install.

<h2><a name="children"><font face="helvetica, arial">
	2.1.5 XmHTML Children
</font></a></h2>

A XmHTML widget is made up of a number of subwidgets: a DrawingArea widget in
which the document is displayed, and two ScrollBars. You can get the
handles to these children using the Xt <tt>XtVaGetValues()</tt> method, as
demonstrated in the following code fragment:

<pre>
	Widget work_window, hsb, vsb;

	XtVaGetValues(html_w,
		XmNworkWindow, &amp;work_window,
		XmNhorizontalScrollBar, &amp;hsb,
		XmNverticalScrollBar, &amp;vsb,
		NULL);
</pre>

Getting XmHTML widget children can be usefull when you want to install your
own event handlers or set additional resources on these children.
<p>

Let us now demonstrate a case where it is usefull to get a handle to one of
XmHTML's children: the workWindow. Amongst the many convenience routines offered
by the XmHTML widget's is the <tt>XmHTMLXYToInfo()</tt>
function. This function takes a XmHTML widget and a pointer position as it's
arguments and returns a structure containing information about the contents of
the currently displayed document at the requested pointer position. The
structure returned is of type <tt>XmHTMLInfoStructure</tt>, which is defined as
follows:

<pre>
typedef struct
{
	int line_no;		/* line number at selected position */
	Boolean is_map;		/* true when clicked image is an imagemap */
	int x,y;		/* position relative to image corner */
	XmImageInfo *image;	/* image data */
	XmHTMLAnchorPtr anchor;	/* possible anchor data */
}XmHTMLInfoStructure, *XmHTMLInfoPtr;
</pre>

The <tt>XmImageInfo</tt> and <tt>XmHTMLAnchorPtr</tt> members of this structure
will be explained in the following sections, so we will now only say that the
first structure contains information about an image over which the pointer
is located, while the latter contains information about a hyperlink over which
the anchor is currently located.
<p>

A perfect way to display this information to the user would be to display
a popup menu when the user clicks on the currently displayed document. In
order for this to work, we need to attach an event handler to the workWindow
of a XmHTML widget. The following example demonstrates how to attach the event
handler to the workWindow and how to use the <tt>XmHTMLXYToInfo()</tt>
function:
<p>

<i>Example 2-5. The work_window.c program</i><br>
<pre>
/*
* work_window.c: attaching an event handler to the work_window of a XmHTML
* widget.
*/
#include &lt;XmHTML.h&gt;

void
attachInfoHandler(Widget html, Widget popup)
{
	Widget work_window;

	XtVaGetValues(html, XmNworkWindow, &amp;work_window, NULL);

	/*
	* Add an event handler which responds to mouse clicks. "popup" is the
	* popup menu which is to be displayed, it is stored as client_data
	* for the event handler.
	*/
	XtAddEventHandler(work_window, ButtonPressMark, 0,
		(XtEventHandler)infoHandler, popup);
}

void
infoHandler(Widget work_window, Widget popup, XButtonPressedEvent *event)
{
	XmHTMLInfoPtr info;
	Widget html_w;
	WidgetList children;

	/* we only take events generated by button 3 */
	if(event->button != 3)
		return;

	/*
	* The work_window is a child of a XmHTML widget, so we can get a handle
	* to the XmHTML widget itself by using Xt's <b>XtParent</b> routine.
	*/
	html_w = XtParent(work_window);

	/* get the info for the selected position.  */
	info = XmHTMLXYToInfo(html_w, event->x, event->y);

	/*
	* Check the returned info structure. There will be nothing to display
	* if the pointer wasn't over an image or anchor when the user 
	* clicked his mouse.
	*/
	if(info == NULL || (info->image == NULL &amp;&amp; info->anchor == NULL))
		return;

	/*
	* For this example we assume that the popup menu has two buttons:
	* a hyperlink button and an image button. We retrieve these children
	* of the popup menu using the XmNchildren resource of Motif's
	* rowColumn widget.
	*/
	XtVaGetValues(popup, XmNchildren, &amp;children, NULL);

	/* check if the info structure has an anchor */
	if(info->anchor)
	{
		XmString label;
		label = XmStringCreateLocalized(info->anchor->href);
		XtVaSetValues(children[0], XmNlabelString, label, NULL);
		XmStringFree(label);
		XtManageChild(children[0]);
	}
	else
		XtUnmanageChild(children[0]);

	/* check if the info structure has an image */
	if(info->image)
	{
		XmString label;
		label = XmStringCreateLocalized(info->image->url);
		XtVaSetValues(children[1], XmNlabelString, label, NULL);
		XmStringFree(label);
		XtManageChild(children[1]);
	}
	else
		XtUnmanageChild(children[1]);

	/* the "popup" menu has now been configured, pop it up */
	XmMenuPosition(popup, event);
	XtManageChild(popup);
}
</pre>

Note that the above example does not use any global variables; we can obtain
all handles to the widgets we need. The handle to the popup menu is
stored as client_data for the event handler, while the handles to the menu
buttons of the popup menu can be easily obtained using one of Motif's
<tt>RowColumn</tt> widget resources. It is also important to notice that it is
very easy to obtain the widget id of the XmHTML widget. The event handler was
attached to the workWindow of a XmHTML widget, and therefore this workWindow is
the same widget as the work_window argument to the infoHandler routine.  This
is the reason why the <tt>XtParent(work_window)</tt> call returns the handle
of the XmHTML widget.
<p>

Also notice that we do not have to free any of the members of the returned
<tt>XmHTMLInfoStructure</tt> structure. In fact, we
are not permitted to do this since the <tt>image</tt> and <tt>anchor</tt>
members of this structure contain pointers to data owned by a XmHTML widget.
Unless it is explicitly mentioned, all structures returned by any of XmHTML
widget's resources, callback resources or convenience routines should be 
considered as read only.
<p>

Example 2-5 is a simple demonstration which does not use any callbacks on
the popup menu buttons. In a real implementation however, callback resources
could be attached to each of the popup menu buttons which would allow the user
to jump to the selected hyperlink or display information about the selected
image.
<p>

<font face="helvetica, arial" size="3">[Note: if you want to specify
resource values for the subwidgets mentioned in this chapter by means of
application fallback resources or in a resource file, the following names
should be used: workWindow for the DrawingArea child, verticalScrollBar for
the vertical ScrollBar child and horizontalScrollBar for the horizontal
ScrollBar child.]
</font>

<h1><a name="appearance"><font face="helvetica, arial">
	2.2 Modifying the Document Appearance
</font></a></h1>

A HTML document typically contains a number of hyperlinks. Hyperlinks (also
referred to as <i>anchors</i>) are often used in HTML documents to allow the
reader to navigate the currently displayed document or between different
documents. In order for the reader to recognize these anchors they should
appear different from the main content of a HTML document. XmHTML widget's
provide a number of resources that control the appearance of these anchors.
<p>

Another set of resources allow you to control the fonts that are used to render
the displayed text.

<h2><a name="anchor"><font face="helvetica, arial">
	2.2.1 Changing the Anchor Appearance
</font></a></h2>

XmHTML widget's identify three different types of anchors: a regular anchor,
a visited anchor and an anchor which has the <tt>target</tt> attribute set.
The latter is a special type of anchor and is one of the extensions to the
HTML 3.2 standard that are implemented by XmHTML. Typical use of this
attribute can be found in HTML documents that utilize the HTML
<tt>&lt;FRAMESET&gt;</tt> extension, where this attribute indicates a
destination to which the contents of the activated anchor
should be sent. This destination can target (amongst others) another XmHTML
widget or a new dialog. Other use of this attribute can be found in Hypertext
help systems where it might be used to indicate that the contents of the
activated anchor should be displayed in a popup window.
<p>

A visited anchor is an anchor that the reader of the document has selected in
the past.
<p>

Each anchor has three states: <i>passive</i>, <i>armed</i> and 
<i>activated</i>. An anchor is considered armed when a user has located
the mouse pointer over an anchor. It is active when the user presses the first
or second mouse button on an armed anchor. It is considered passive otherwise.
<p>

XmHTML widget's provide four ways to let an anchor stand out:
<p>
<ul>
<li>by changing the cursor when an anchor is armed;
<li>by actively changing the look of an anchor when it is armed;
<li>by rendering the anchor as a pushbutton;
<li>by underlining the anchor;
</ul>
<p>

The first and second item in this list are always selectable, while the
third and fourth item are mutually exclusive: you choose either to display the
anchors as pushbuttons or to underline them. The latter offers the most
control on anchor appearance, while some users may find pushbutton anchors
aesthetically more pleasing (although it can be slightly more difficult to
identify anchors).
Both types allow you to control the color in which the anchor is displayed in
both it's passive and activated state.
<p>

XmHTML widget's will display anchors as pushbuttons by default: the default
value of the <tt>XmNanchorButtons</tt> resource is <tt>True</tt>. By setting
this resource to False, anchors will be underlined instead of being displayed
as a pushbutton.

<h3><a name="anchor_cursor"><font face="helvetica, arial">
	2.2.1.1 Anchor Cursor Resources
</font></a></h3>

To indicate that an anchor can be activated by the user, it is often convenient
to not only render the anchor differently than the remainder of the document
but also to change the cursor when the pointer is moved over an anchor.
<p>

XmHTML widget's will change the cursor to a hand with a pointing finger when
the user moves the pointer over an anchor. The default cursor is a built-in
cursor, but it can be changed to a different cursor by using the
<tt>XmNanchorCursor</tt> resource. Although it will seldomly be needed, the
<tt>XmNanchorDisplayCursor</tt> resource allows you to control whether or not
XmHTML widget's should change the cursor when the pointer is moved over an
anchor (it is <tt>True</tt> by default).
<p>

The following code fragment demonstrates how to create, set and destroy a
cursor:

<pre>
#include &lt;X11/cursorfont.h&gt;	/* standard X cursors */
#include &lt;XmHTML.h&gt;

void
setCursor(Widget html_w, Boolean destroy_cursor)
{
	static Cursor cursor;

	/* create a standard X cursor when it is not yet created */
	if(cursor == None)
		cursor = XCreateFontCursor(XtDisplay(html_w), XC_hand2);

	if(destroy_cursor)
	{
		/* only free the cursor when we have created one */
		if(cursor != None)
			XFreeCursor(XtDisplay(html_w), cursor);
		cursor = None;
	}
	else	/* set this cursor as the anchor cursor for this XmHTML widget */
		XtVaSetValues(html_w,
			XmNanchorCursor, cursor,
			XmNanchorDisplayCursor, True,
			NULL);
}
</pre>

The <tt>cursor</tt> is created using <tt>XCreateFontCursor()</tt>, but this is
not required; you may use other functions like <tt>XCreateGlyphCursor()</tt>
or <tt>XCreatePixmapCursor()</tt>,
if you like. See O'Reilly's X Window System Programming guides Volume One,
<i>Xlib Programmer's Manual</i>, for more information.
<p>

It is also considered nice programming to use X resources sparingly (although
in the case of cursor's it is not really required, they are a virtually
unlimited resource under X). This is why the above fragment declares the
allocated cursor as a static variable: once allocated the cursor id is always
available and we can use it for every XmHTML widget that is provided as an
argument to the above routine. When this routine is called with the
<tt>destroy_cursor</tt> argument set to True the cursor is destroyed and reset.

<h3><a name="anchor_display"><font face="helvetica, arial">
	2.2.1.2 Anchor Display Resources
</font></a></h3>

Whether or not you select to display anchors as pushbuttons or to underline
them, you can always specify the foreground color in which an anchor is
rendered. You can specify a different foreground color for the passive state of
each of the anchor types mentioned in the introduction to this section:
<p>

<ul>
<li><tt>XmNanchorForeground</tt>:<br>
	specifies the foreground color that is to be used to render a regular
	anchor;
<li><tt>XmNanchorVisitedForeground</tt>:<br>
	specifies the foreground color that is to be used to render a visited
	anchor;
<li><tt>XmNanchorTargetForeground</tt>:<br>
	specifies the foreground color that is to be used to render an anchor
	that has the <b>target</b> attribute set;
</ul>
<p>

The <tt>XmNanchorActivatedForeground</tt> resource
identifies the foreground color to be used when an anchor is activated.
This resource is the same for all three anchor types.
<p>

When you opt to underline the anchors, you can also use the
<tt>XmNanchorActivatedBackground</tt> resource to
specify the background color to use when an anchor is activated.
<p>

<font face="helvetica, arial" size="3">[Note: When a HTML document contains
a background image and displaying of background images is enabled (which is
true by default), the <b>XmNanchorActivatedBackground</b> resource is also
ignored when anchors are to be underlined, making the anchors appear as being
transparent.]</font>
<p>

You need to specify a <i>Pixel</i> for all three resources. You can specify
a Pixel value by pre-allocating a pixel (by using any of Xlib's
<tt>XAllocColor()</tt> routines) or by using Xt's <tt>XtVaTypedArg</tt> method.
Both methods have their pro's and con's, but in either case you must free
the allocated color values when your application exits.
<p>

When you have set the <tt>XmNanchorButtons</tt> resource to <tt>False</tt>,
you can also specify the type of underlining for each of the three anchor
types. XmHTML widget's support the following types of underlining:
<p>

<ul>
<li><tt>XmNO_LINE:</tt><br>
	no lines are drawn;
<li><tt>XmSINGLE_LINE:</tt><br>
	a single solid line. This is the default for regular and visited anchors;
<li><tt>XmDOUBLE_LINE:</tt><br>
	a double solid line. This is the default for anchors that have the
	<tt>target</tt> attribute set;
<li><tt>XmSINGLE_DASHED_LINE:</tt><br>
	a single dashed line;
<li><tt>XmDOUBLE_DASHED_LINE:</tt><br>
	a double dashed line;
</ul>
<p>

The resource names are as follows:
<p>

<ul>
<li><tt>XmNanchorUnderlineType</tt>:<br>
	specifies the type of underlining to use for regular anchors;
<li><tt>XmNanchorVisitedUnderlineType</tt>:<br>
	specifies the type of underlining to use for visited anchors;
<li><tt>XmNanchorTargetUnderlineType</tt>:<br>
	specifies the type of underlining to use for anchors
	that have the <tt>target</tt> attribute set;
</ul>
<p>

Finally, there is the <tt>XmNhighlightOnEnter</tt> resource. When set to
<tt>True</tt> (which is the default), a XmHTML widget will actively modify
the look of an anchor whenever it becomes armed by <i>highlighting</i>
the anchor. The actual color and type of highlighting used heavily depends on
the content of the document that is currently displayed. When a background
image is present, a XmHTML widget will base the highlight color on the value
of the <tt>XmNanchorActivatedForeground</tt> resource and render the
anchor's text in the computed color. When no background image is present, the
highlight color will be based on the current document background and the
anchor's text will be rendered in a rectangle filled with the computed
color. If you decide to enable this resource, it is adviced that you offer
a possibility to the user to toggle the value of this resource: a XmHTML widget
attempts to do it's best when computing the highlight color, but might fail
to find a suitable color. This can happen, for instance, on documents where
the colors used by the background (fixed color or background image), text
and anchors are poorly balanced.


<h2><a name="anchor_visited"><font face="helvetica, arial">
	2.2.2 Marking a Visited Anchor
</font></a></h2>

You now know that XmHTML widget's contain the concept of <i>visited anchors</i>,
which are anchors that the reader of the document has selected in the past
(e.g, have already been visited). But when the user of your application is
switching between documents the following question arises: how do you inform a
XmHTML widget that an anchor was previously visited by the user?
<p>

The answer is fairly simple: you use the 
<tt>XmNanchorVisitedProc</tt> resource. When a
procedure has been installed for this resource, a XmHTML widget will call this
procedure to test if an anchor has already been visited. There are two
arguments to this procedure: the widget id of a XmHTML widget and the name of
the anchor. It should return <tt>True</tt> when the anchor should be rendered
using the <tt>XmNanchorVisitedForeground</tt> resource and <tt>False</tt> when
it should be rendered as a regular anchor.
<p>

Please note that a XmHTML widget only calls any installed procedure when a
document is set into a XmHTML widget, and that it will be called for every
anchor that is found in this document.
<p>

The following example shows how easy it can be to use this resource:
<pre>
#include &lt;XmHTML.h&gt;

static int num_visited_anchors;
String visited_anchors[100];

static Boolean
visitedTestProc(Widget html_w, String anchor)
{
	int i;

	for(i = 0; i &lt; num_visited_anchors; i++)
		if(!strcasecmp(visited_anchors[i], anchor))
			return(True);
	return(False);
}

int
main(int argc, char **argv)
{
	Widget toplevel;
	XtAppContext app;

	toplevel = XtVaAppInitialize(&amp;app, "Demos", NULL, 0,
		&amp;argc, argv, NULL, NULL);

	XtVaCreateManagedWidget("html", xmHTMLWidgetClass, toplevel,
		XmNanchorVisitedProc, visitedTestProc,
		NULL);

	XtRealizeWidget(toplevel);
	XtAppMainLoop(app);
}
</pre>
In this example we assume that text can be set in the XmHTML widget, 
<tt>visited_anchors</tt> contains a list of already visited anchors and that
<tt>num_visited_anchors</tt> contains the number of items in the visited anchor
list. In section 2.5 we will demonstrate how to maintain this list.
<p>

<h2><a name="fonts"><font face="helvetica, arial">
	2.2.3 Specifying the Document Fonts
</font></a></h2>

One of the most important (if not the most important) aspect that will
determine the way a document will look to the user concerns the fonts used to
render the text in a document. Selecting an appropriate default font (and its
size) is a very important decision when using a XmHTML widget, and it is more
difficult than it might seem, especially if you want to internationalize your
application.
<p>

Font specification for a XmHTML widget does not follow the standard Motif font
specification rules (the <tt>XmFontList</tt> type). Due to the nature of the
HTML language this would be rather impossible; it does not only contain font
markup elements that allow the writer of a HTML document to change the style
of a font, but also to change the typeface and size of a font. To make things
even more complicated, all of these font markup elements can be used in
arbitrary sequence.
<p>

In order to cope efficiently with this virtually unlimited number of font
combinations in HTML documents, XmHTML widget's allocate their fonts directly
and employ a smart font caching scheme that will keep the number of required
font allocations to an absolute minimum. The font cache is shared by all
XmHTML widget's on a per display basis (which effectively means that you
can use a XmHTML widget for a multi-display application).
<p>

Another reason why XmHTML widget's do not use the Motif font specification
rules is that the XmHTML font allocation routines go thru great lengths to
ensure that a requested font is matched. When a requested font can not be
exactly matched, the font allocation routines attempt to find a close match
by following a number of different paths instead of giving up immediatly and
using a default font. XmHTML widget's produce much better looking text than
some of the most well known HTML browsers as a result of this.
<p>

Because XmHTML widget's allocate their fonts themselves instead of relying on
Motif, a number of resources are offered that allow you, the programmer, to
select a character set, foundry, typeface, spacing and size of the fonts that
are to be used for displaying a document.
<p>

<font face="helvetica, arial" size="3">[Note: In order to fully appreciate the
font resources of XmHTML widget's you are encouraged to read Appendix A of
O'Reilly's X Window System Programming guides, Volume One,
<i>Xlib Programmer's Manual</i>.]</font>
<p>

Before explaining the various font resources I will mention that a XmHTML
widget uses the contents of the font resources to compose a X Logical Font
Description (XLFD) which is used to query your X server. Knowing this, it
is obvious that you are allowed to use wildcards for all font resources
(except size of course). This can be potentially dangerous: depending on the
configuration of your font path and directories, the font returned by the X
server may or may not be what is intended.
<p>

As a final note in this fairly long introduction, the default values for
each of the various font resources have been choosen in such a way that every
combination represents a font that is present in the default font path of
the standard R5 X distribution.

<h3><a name="fonts_charset"><font face="helvetica, arial">
	2.2.3.1 Specifying the Character Set
</font></a></h3>

The character set resource, <tt>XmNcharset</tt>,
is a string representing the ISO character set encoding to be used. The
default character set used by XmHTML widget's, <tt>ISO8859-1</tt>, represents
the ISO Latin-1 character set (which is used by all of the fonts in the
<i>75dpi</i> and <i>100dpi</i> directories of X's default font path). This
character set is a superset of the standard ASCII character set, which includes
various special characters used in European languages other than English.
<p>

The <tt>XmNcharset</tt> resource makes it relatively
easy to select a font for non-European (non-English) languages. For example,
<tt>"XmNcharset: koi8-*"</tt> specifies the koi8
Cyrillic font, while <tt>"XmNcharset: UJIS-*"</tt>
identifies a Japanese font.
<p>

It is also important to notice that this resource is very important, if not
the most important font resource. If a charset is specified which is
unknown to the X server (or the charset is given as a wildcard), a XmHTML
widget has almost no control about the fonts to use: the actual charset that
is used will then only depend on the fontpath configuration of the X server and
the specified font family. Therefore it is considered wise to first verify
if the requested character set is available on the system your application
is running on before changing it. See also section
<a href="#fonts_family">2.2.3.2</a>, Specifying the Font Family.
<p>

The font allocation scheme used by XmHTML will first try to load a font for
a given character set and font family. When that fails it will wildcard the
charset. This causes a XmHTML Widget to honor the following sequence of HTML
tags with the default charset:
<p>

<tt>&nbsp;&nbsp;&lt;FONT FACE="symbol"&gt;alpha&lt;/FONT&gt;</tt>
<p>

which is rendered as:
<p>

<tt>&nbsp;&nbsp;</tt><font face="symbol">alpha</font>
<p>

<font face="helvetica, arial" size="3">[Note: this will render the word alpha
in the symbol font if it is installed on your X server, and in english if you
are viewing this document with almost any other browser or haven't got the
symbol font installed.]</font>

<h3><a name="fonts_family"><font face="helvetica, arial">
	2.2.3.2 Specifying the Font Family
</font></a></h3>

XmHTML widget's use two different types of font: a proportional font and a
fixed-width font. Proportional fonts are fonts in which each character in a
character set has a different width (an example of a proportional font is Times
Roman), while fonts in which each character has the same width are called
fixed-width fonts. Proportional fonts are more easy for the human eye to read
than fixed-width fonts and therefore the main portion of the text in a HTML
document is rendered in a proportional font. Fixed-width fonts are used to
display preformatted text in a HTML document.
<p>

You specify the proportional font family by using the
<tt>XmNfontFamily</tt> resource,
and the fixed-width font family by using the
<tt>XmNfontFamilyFixed</tt> resource.
The value for both these resources is a sequence of four dash-seperated
strings that define a font family. These four fields are:
<p>

<ol>
	<li>foundry: the type foundry that digitized and supplied the font, i.e.
		Adobe;
	<li>family: the font family name (also known as typeface), i.e. roman;
	<li>set width: a value describing a font's proportionate width according
		to the selected foundry, i.e. normal;
	<li>spacing: type of character spacing for a font. m (for monospace, i.e.
		fixed width) or p (proportional, i.e., variable-width) are two well
		known font spacings.
</ol>
<p>

The default value for the <tt>XmNfontFamily</tt>
resource is <tt>adobe-times-normal-*</tt>, and the
default value for the <tt>XmNfontFamilyFixed</tt>
resource is <tt>adobe-courier-normal-*</tt>.
Both font families represent a standard, scalable font, present on each
X server.
<p>

You should always try to specify a scalable font whenever possible: HTML
documents intend to use a lot of differently sized fonts (the header markup
elements for example all require a different font size), and the displayed
text will generally look much better if a scalable font is used instead of a
bitmapped font.
<p>

A note of caution: before changing any of the <tt>fontFamily</tt> resources,
the existence of this font (within the context of the current or new value of
the <tt>XmNcharset</tt> resource) should be verified before actually changing
it. An unsuccesfull attempt to change the default font settings <b>can</b>
cause a XmHTML widget to exit your application: if it can not find a default
font it simply can not display anything.

<h3><a name="fonts_sizes"><font face="helvetica, arial">
	2.2.3.3 Specifying the Font Sizes
</font></a></h3>

The last step in specifying the document fonts is to specify the font sizes
for both the proportional and fixed-width font families. Font sizes are
always specified in <i>points</i> and not in pixels: specifying a font
size in pixels would require you to know in advance the x- and y-resolution of
the screen your application is running on. The XmHTML widget determines the
screen resolution and selects an appropriate pixel size automatically.
<p>

You can specify the text font size, the sup- and superscript font size and the
font size for each of the header markup elements for the proportional font
family. For the fixed-width font family you can specify the text font size and
sup- and superscript size.
<p>

The sizes for the proportional font family are given by the
<tt>XmNfontSizeList</tt> resource. The value for this resource is a comma
seperated list of eight strings. The list below describes the fields in this
resource.
<p>

<ol>
<li>normal text size;
<li>sub and superscript font size;
<li>font size for the &lt;H1&gt; markup element;
<li>font size for the &lt;H2&gt; markup element;
<li>font size for the &lt;H3&gt; markup element;
<li>font size for the &lt;H4&gt; markup element;
<li>font size for the &lt;H5&gt; markup element;
<li>font size for the &lt;H6&gt; markup element;
</ol>
<p>

The default value for this resource is
<tt>"14,8,24,18,14,12,10,8"</tt>.
<p>

You do not have to specify all values; when an element in this list has the
value 0 (zero), the appropriate default font size is used.
<p>

The sizes for the fixed-width font family are given by the
<tt>XmNfontSizeFixedList</tt> resource. The value for
this resource is a comma seperated list of two strings, where the first
value describes the normal text size and the second value the size for sup- and
superscript text. The default value for this resource is <tt>"12,8"</tt>.

<h1><a name="images"><font face="helvetica, arial">
	2.3 XmHTML and Images
	</font></a></h1>

One of the strong and much admired features of the XmHTML Widget is it's
built in image support. A XmHTML widget can support a wide range of different
image types (from simple X11 bitmaps through complex GIF animations to full
32bit RGB PNG images with an alpha channel). For simple applications one 
does not need to know anything about this image support as a XmHTML widget
can handle almost everything by itself. In fact, you only need to read
this section if you want to exploit XmHTML's image support to it's fullest.

<h2><a name="images_info"><font face="helvetica, arial">
	2.3.1 The XmImageInfo Structure
</font></a></h2>

The basis of XmHTML's image API is formed by the XmImageInfo structure.
XmHTML uses this structure to compose the actual image.

<pre>
typedef struct _XmImageInfo
{
    /* regular image fields */
    String url;                    /* original location of image */
    unsigned char *data;           /* raw image data. ZPixmap format */
    unsigned char *clip;           /* raw clipmask data. XYBitmap format */
    Dimension width;               /* used image width, in pixels */
    Dimension height;              /* used image height, in pixels */
    int *reds;                     /* red image pixels */
    int *greens;                   /* green image pixels */
    int *blues;                    /* blue image pixels */
    unsigned int ncolors;          /* Number of colors in the image */
    int bg;                        /* transparent pixel index */
    unsigned char *rgba;           /* image data in rgba format */
    float fg_gamma;                /* image gamma */
    unsigned int options;          /* image option bits */

    /* Additional animation data */
    int x;                         /* logical screen x-position for a frame */
    int y;                         /* logical screen y-position for a frame */
    int loop_count;                /* animation loop count */
    unsigned char dispose;         /* image disposal method */
    int timeout;                   /* frame refreshment in milliseconds */
    int nframes;                   /* no of animation frames remaining */
    struct _XmImageInfo *frame;    /* ptr to next animation frame */

    /* image classification fields and original data */
    unsigned char type;            /* image type, see below */
    int depth;                     /* bits per pixel for this image */
    unsigned char colorspace;      /* colorspace for this image */
    unsigned char transparency;    /* transparency type for this image */
    Dimension swidth;              /* image width as read from image */
    Dimension sheight;             /* image height as read from image */
    unsigned int scolors;          /* Original number of colors in the image */

    XtPointer user_data;           /* any data to be stored with this image */
}XmImageInfo, *XmImageInfoStruct;
</pre>

The first part of this structure contains the raw image data XmHTML
requires to create an image. The second part is used for creating animations
while the third part provides additional information about the image
represented by this structure.
<p>

As will be shown in the following sections of this chapter, all of the
convenience functions of a XmHTML widget that deal with images work with this
structure, either as an argument or as a return value. 
<p>

<h3><a name="image_info_explained"><font face="helvetica, arial">
2.3.1.1 The XmImageInfo Structure Explained
</font></a></h3>

Although this section is mostly intended for those that want to add support
for an image type that is unknown to XmHTML, it also contains important
information for those that want to enable what is known as
<a href="#advanced_images_delayed">delayed image loading</a> or want to exploit
XmHTML's built-in image support to its fullest extent. It explains every field
in the XmImageInfo structure, what each field should contain and the default
values assumed when an image is loaded using the 
<a href="#images_proc">XmHTMLImageDefaultProc</a>.
<p>

<dl>
<dt><tt>url</tt>
<dd>This field represents the original location from where the image in
	question should be or has been obtained. It is actually the contents of
	the <tt>SRC</tt> attribute of the <tt>&lt;IMG&gt;</tt> tag.
	It is important that this field always contains a value,
	especially if you want to switch on delayed image loading.
<p>
<dt><tt>data</tt>
<dd>This field represents the actual image data in ZPixmap format. It is a
	continuous stream of bytes in which each byte represents an index in the
	colormap for this image (as defined by the <i>reds, greens</i> and 
	<i>blues</i> fields).
<p>

<dt><tt>clip</tt>
<dd>This field represents a <i>bitmap</i> (a pixmap with depth 1) which a
	XmHTML widget will use to create a clipmask. It is a continuous stream
	of <b>bits</b>, where each bit defines if the underlying pixel should
	be rendered (bit set to 1) or should be left as it is (bit set to 0).
	It is only valid for transparent images, although it is very well
	possible to use this field for defining non-rectangular pixmaps.
	The dimensions of this bitmap should equal the actual image dimensions.
<p>

<dt><tt>width</tt> and <tt>height</tt>
<dd>These fields contain the absolute dimensions of the final pixmap as given
	by the <tt>data</tt> field. They are specified in pixel units, and their
	product <b>must</b> match the size of the <tt>data</tt> field.
<p>

<dt><tt>reds, greens, blues</tt> and <tt>ncolors</tt>
<dd>Each of these fields is an array of color component values which together
	form the RGB colormap of the image. Each array must have the same
	size, and this size is given by the value of <tt>ncolors</tt>. This number
	must be equal the the number of colors used by the image. A XmHTML widget
	uses these arrays to allocate the actual image colors and then maps the
	image data onto these colors.
<p>

<dt><tt>bg</tt>
<dd>The index of the transparent pixel, or <tt>-1</tt> when the image is
	fully opaque. 
<p>

<dt><tt>rgba</tt>
<dd>This field is only used for images containing an alpha channel.
	An alpha channel is a series of pixel values in an image used to compute
	partial pixel transparency. With partial pixel transparency fade in/out or
	anti-aliasing effects can be achieved regardless of the current background
	setting. The XmHTMLImageDefaultProc supports alpha channelled PNG images.
	The format of the data stored in this field is a continuous stream of
	bytes where each pixel is represented by its red, green, blue and
	alpha channel component.
<p>

<dt><tt>fg_gamma</tt>
<dd>This field contains the gamma value of the display on which the image
	was created. It is only used in combination with alpha channelled images.
<p>

<dt><tt>options</tt>
<dd>This field contains a combination of OR'd constants which tell
	a XmHTML Widget what it can and can't do with an <tt>XmImageInfo</tt>
	structure. A number of these constants define how and when a XmHTML
	should free a structure (or members of it), while others determine
	what type of operations are allowed and how the actual image should
	be processed.
	<p>

	&quot;Set by default&quot; indicates a bit set when the 
	XmHTMLImageDefaultProc was used to read an image.
	<p>

	<dl>
	<dt><tt>XmIMAGE_DELAYED</tt>
	<dd>When set, XmHTML will ignore all fields except <tt>url</tt> and use 
		a default image instead. This default image can be updated at a later
		stage using either the
		<a href="images.html#XmHTMLImageReplace">XmHTMLImageReplace</a> or
		<a href="images.html#XmHTMLImageUpdate">XmHTMLImageUpdate</a> 
		convenience function;
		See the section on <a href="#advanced_images_delayed">Delayed Image
		Loading</a> for more information.
	<p>

	<dt><tt>XmIMAGE_DEFERRED_FREE</tt>
	<dd>When set, XmHTML will take care of destroying this structure when
		a new document is loaded. Set by default;
	<p>

	<dt><tt>XmIMAGE_IMMEDIATE_FREE</tt>
	<dd>When set, this structure will be destroyed as soon as XmHTML no longer
		needs it;
	<p>

	<dt><tt>XmIMAGE_RGB_SINGLE</tt>
	<dd>set this bit when the <tt>reds, greens</tt> and <tt>blues</tt> fields
		have been allocated with one single malloc instead of three separate. 
		Set by default;
	<p>

	<dt><tt>XmIMAGE_ALLOW_SCALE</tt>
	<dd>set this bit when scaling an image is allowed. Set by default;
	<p>

	<dt><tt>XmIMAGE_FRAME_IGNORE</tt>
	<dd>use with animations: set this bit when a frame falls outside the
		logical screen area. No pixmap is created but the timeout for the
		frame is kept.
	<p>

	<dt><tt>XmIMAGE_CLIPMASK</tt>
	<dd>This bit is set when the returned <tt>XmImageInfo</tt> structure
		contains clipmask data. XmHTML uses this info to create a clipping
		bitmap. Changing this bit from set to unset will lead to a memory leak
		while changing it from unset to set without providing a clipmask
		yourself will cause an error to happen. You can however set this bit
		when you are providing your own clipmask (to provide non-rectangular
		images for example), provided you fill the &quot;clip&quot; field
		with valid bitmap data.
	<p>

	<dt><tt>XmIMAGE_SHARED_DATA</tt>
	<dd>This bit is set when images share data. XmHTML sets this bit when the
		image in question is an internal image, e.i., one for which the image
		data may never be freed. Be carefull setting this bit yourself, since
		it prevents XmHTML from freeing the image data present in the
		XmImageInfo structure.  It can easily lead to memory leaks when an
		image is not an internal image.
	<p>

	<dt><tt>XmIMAGE_PROGRESSIVE</tt>
	<dd>Setting this bit will enable progressive image loading. A function
		must have been installed on the <tt>XmNprogressiveReadProc</tt>
		resource prior to setting this bit. Installing a function on the
		<tt>XmNprogressiveEndProc</tt> is optional but strongly advised. When
		this bit is set all other bits and all members except the <tt>url</tt>
		field of the <tt>XmImageInfo</tt> structure will be ignored.
	<p>

	<dt><tt>XmIMAGE_DELAYED_CREATION</tt>
	<dd>This bit is read-only. It is used internally by XmHTML for images with
		an alpha channel. Alpha channel processing merges the current
		background with the original RGBA data (see above) from the image and
		uses the result to compose the actual on-screen image (the merged data
		is stored in the &quot;data&quot; field of the <tt>XmImageInfo</tt>
		structure). XmHTML needs to store the original data somewhere, and
		when this bit is set it is stored in the &quot;rgba&quot; field of the
		<tt>XmImageInfo</tt> structure. When this bit is set, the returned
		structure may not be freed as long as the current document is alive.
		You can discard it as soon as a new document is loaded.
	</dl>
<p>

<dt><tt>type</tt>
<dd>This field contains a value which describes the type of image that is
	represented by this structure. This field is unused internally and is
	provided for your convenience only. You should consider this value
	read-only though as it might well be used in the future. Table 2-1 lists
	all possible values for this field.
	<p>

	<center>
	<table cols="2" border="1">
	<caption>Table 2-1. Supported Image Types</caption>
	<tr valign="top" halign="left">
		<th>Type
		<th>Image description
	<tr valign="top" halign="left">
		<td>IMAGE_ERROR
		<td>error on image loading
	<tr valign="top" halign="left">
		<td>IMAGE_UNKNOWN
		<td>unknown image
	<tr valign="top" halign="left">
		<td>IMAGE_XPM
		<td>X11 pixmap
	<tr valign="top" halign="left">
		<td>IMAGE_XBM
		<td>X11 bitmap
	<tr valign="top" halign="left">
		<td>IMAGE_GIF
		<td>CompuServe(C) Gif87a or Gif89a
	<tr valign="top" halign="left">
		<td>IMAGE_GIFANIM
		<td>animated gif
	<tr valign="top" halign="left">
		<td>IMAGE_GIFANIMLOOP
		<td>animated gif with NETSCAPE2.0 loop extension
	<tr valign="top" halign="left">
		<td>IMAGE_GZF
		<td>compatible Gif87a or Gif89a
	<tr valign="top" halign="left">
		<td>IMAGE_GZFANIM
		<td>compatible animated gif
	<tr valign="top" halign="left">
		<td>IMAGE_GZFANIMLOOP
		<td>compatible animated gif with NETSCAPE2.0 loop extension
	<tr valign="top" halign="left">
		<td>IMAGE_JPEG
		<td>JPEG image
	<tr valign="top" halign="left">
		<td>IMAGE_PNG
		<td>PNG image
	<tr>
	</table>
	</center>
<p>

</dl>


	<h2><a name="images_proc"><font face="helvetica, arial">
		2.3.2 The XmHTMLDefaultImageProc
		</font></a></h2>
	<h2><a name="images_anim"><font face="helvetica, arial">
		2.3.3 Animations
		</font></a></h2>
	<h2><a name="images_maps"><font face="helvetica, arial">
		2.3.4 XmHTML's Imagemap Support
		</font></a></h2>

<h1><a name="callbacks"><font face="helvetica, arial">
		2.4 XmHTML Widget Callback Functions
		</font></a></h1>

	<h2><a name="anchorCB"><font face="helvetica, arial">
		2.4.1 Anchor Activation Callback
		</font></a></h2>
	<h2><a name="trackCB"><font face="helvetica, arial">
		2.4.2 Anchor Tracking Callback
		</font></a></h2>
	<h2><a name="frameCB"><font face="helvetica, arial">
		2.4.3 Frame Notification Callback
		</font></a></h2>
	<h2><a name="formCB"><font face="helvetica, arial">
		2.4.4 Form Activation Callback
		</font></a></h2>
	<h2><a name="imageCB"><font face="helvetica, arial">
		2.4.5 Imagemap Activation Callback
		</font></a></h2>
	<h2><a name="docCB"><font face="helvetica, arial">
		2.4.6 Document Verification Callback
		</font></a></h2>
	<h2><a name="linkCB"><font face="helvetica, arial">
		2.4.7 Document Link Callback
		</font></a></h2>
	<h2><a name="motionCB"><font face="helvetica, arial">
		2.4.8 Document Motion Callback
		</font></a></h2>
	<h2><a name="armCB"><font face="helvetica, arial">
		2.4.9 Document Arm Callback
		</font></a></h2>
	<h2><a name="inputCB"><font face="helvetica, arial">
		2.4.10 Document Input Callback
		</font></a></h2>

<h1><a name="collective_example"><font face="helvetica, arial">
	2.5 Collective Example
</font></a></h1>

<h1><a name="advanced"><font face="helvetica, arial">
		2.6 Advanced XmHTML Programming Techniques
		</font></a></h1>

	<h2><a name="advanced_frame"><font face="helvetica, arial">
		2.6.1 Adding Support for HTML Frames
		</font></a></h2>
<h2><a name="advanced_images_delayed"><font face="helvetica,arial">
	2.6.2 Delayed Image Loading
</font></a></h2>

When a document is loaded into a XmHTML widget, it might not always be possible 
to provide an image when the XmHTML widget encounters one in the document: a
net connection might be slow or the image requested can be that large that
loading it can take quite a long time. It can be quite annoying if XmHTML 
should block until the image is available. Therefore, XmHTML offers Delayed
Image Loading. Delayed Image Loading fools XmHTML into thinking that it has the
image it wants, so it will happily continue without a noticable slowdown, and
display the document once it has been parsed and formatted.
<p>

Now, how does it work? Basically it is quite simple: when a XmHTML widget
finds a &lt;IMG&gt; tag, it will call the function that has been installed for
the XmNimageProc resource function (say, <a href="#imageProc">imageProc</a>).
<p>

The XmNimageProc function should then initialise a blank 
<a href="#images_info">XmImageInfo</a> structure, fill in the <i>url</i> field
and set the <i>XmIMAGE_DELAYED</i> bit (this last step is imperative). It
should then call a function which requests an image from a remote server and
return the new XmImageInfo to XmHTML. The image is retrieved asynchronously.
<p>

At some point in the future, the image has been retrieved by the network layer,
and the application calls a routine (say
<a href="#replaceImage">replaceImage</a>) which will replace the blank image in
the XmImageInfo structure with the newly loaded one.
<p>

XmHTML widget's provide two functions for replacing or updating a delayed
image: XmHTMLImageReplace and XmHTMLImageUpdate. The difference between these
two functions is that the former will actually replace the given XmImageInfo
structure with a new one while the latter will only update the given image.
<p>

The above will probably make more sense in an example, so here is one.
<p>

<i>Example 2-?: Delayed Image Loading</i><br> <a name="imageProc"></a>
<pre>
#include &lt;XmHTML.h&gt;

XmImageInfo *imageProc(Widget w, String url)
{
	String filename;
	static XmImageInfo *image;

	image = NULL;

	/* test delayed image loading */
	if((filename = resolveFile(url)) != NULL)
	{
		image = XmHTMLImageDefaultProc(html, filename, NULL, 0);
		image_cache[current_image].image = image;
		image_cache[current_image++].name = strdup(filename);
	}
	else
	{
		image = (XmImageInfo*)malloc(sizeof(XmImageInfo));
		memset(image, 0, sizeof(XmImageInfo));
		image->options = XmIMAGE_DELAYED; /* Tell XmHTML this image is delayed */
		image->url = strdup(url);
		/* associate the new XmImageInfo with this url */
		image_cache[current_image].image = image;
		image_cache[current_image++].name = strdup(url);
		fetchFileFromServer(url);
	}
	return(image);
}
</pre>
In the above example, it is first tested if the requested image is already
available. When it is, XmHTMLImageDefaultProc is called to load the image, and
it's return value is stored in an image cache.
<p>

When the requested image is not available on the other hand, a blank
XmImageInfo structure is initialized and stored, the delayed bit is set
and a function is called which will fetch the image asynchronously from
a server. The blank XmImageInfo structure is then returned and XmHTML
will continue where it left off. When the image has been received, the
application calls the replaceImage function.
<p>

<i>Example 2-?: Updating delayed images</i><br> <a name="replaceImage"></a>
<pre>
#include &lt;XmHTML.h&gt;

void replaceImage(String url, unsigned char *buf, int len)
{
	int i;
	XmImageInfo *image;

	for(i = 0; i &lt; image_cache_size; i++)
	{
		if(!(strcmp(image_cache[i].name, url)))
		{
			image = XmHTMLImageDefaultProc(html, url, buf, len);
			XmHTMLImageReplace(html, image_cache[i].image, image);
			image_cache[i].image = image;
		}
	}
}
</pre>

As already explained in this section, the replaceImage function is called
when an image has been retrieved from a server. Contents of the image from 
location <i>url</i> have been placed in the buffer <i>buf</i> with size 
<i>len</i>.
<p>

Remember that we have already associated a XmImageInfo structure with a url 
in the imageProc function, so the first thing we do is get the correct 
XmImageInfo. When we have found the correct entry, we simply call
XmHTMLImageDefaultProc to actually load the image, replace the image 
represented by our old XmImageInfo structure and update the image cache.
<p>

In a real world implementation the previous XmImageInfo structure would also
be freed. It would also call the XmHTMLRedisplay function after all images
have been loaded to force XmHTML to do a recalculation of it's screen layout.

	<h2><a name="advanced_images_other"><font face="helvetica, arial">
		2.6.3 Adding Support for Other Imagetypes
		</font></a></h2>

<h2><a name="advanced_images_misc"><font face="helvetica, arial">
	2.6.4 Using XmHTML's Image Support for Other Purposes
</font></a></h2>
One of the many nice features in a XmHTML widget is the built-in image support.
What is even nicer is that this image support is also available for purposes
other than use with a XmHTML widget: the XmHTML widget set contains a number of
routines that allow you to read an image of any of the supported image types.
You can then use the returned <b>XmImage</b> to your own likings. This section
explains the XmImage image datatype and describes how to create, destroy and
use such images.

<h3><a name="advanced_images_xmimage"><font face="helvetica, arial">
	2.6.4.1 The XmImage Structure
</font></a></h3>
The basis of the external image support of the XmHTML widget set is formed
by the <b>XmImage</b> structure. This structure is defined as follows:

<pre>
typedef struct{
	/* regular image data */
	String file;		/* originating file */
	unsigned char type;	/* image type */
	Pixmap pixmap;		/* actual image	*/
	Pixmap clip;		/* for transparant pixmaps */
	int width;		/* image width */
	int height;		/* image height */	

	/* animation data */
	XmImageFrame *frames;	/* array of animation frames */
	int nframes;		/* no of frames following */
	int current_frame;	/* current frame count */
	int current_loop;	/* current loop count */
	int loop_count;		/* maximum loop count */
	XtIntervalId proc_id;	/* timer id for animations */
	Widget w;		/* image owner */
	XtAppContext context;	/* Application context for animations */

	/* Private data */
	unsigned long *pixels;
	int npixels;
  	struct _XColorContext *xcc;
}XmImage;
</pre>
The <i>pixmap</i> field contains the actual image. It is this pixmap that
you should use in a call to <b>XCopyArea</b> to put it directly in a window
or in combination with Motif's <b>XmNlabelPixmap</b> resource to put the
pixmap in a label widget.
<p>

If the value of the <i>clip</i> field is other than <b>None</b>, it means the
original image is a transparent image. You can then use this field as a
clipmask of a GC so your image will also be transparent.
<p>

<font face="helvetica, arial" size="3">[Note: the clipmask is a pixmap of depth
1, so it is actually a X11 bitmap.]</font>
<p>

One important reminder before explaining how to create and use a XmImage:
you should never touch any of the fields in the XmImage structure which are
mentioned as private data. This private data is used when the XmImage is
destroyed, so modifying any of these fields is a potential danger and leads
at least to a memory leak. If you really want to know what these fields
represent, here's a very short explanation of what they represent:
<p>

<ul>
<li><i>pixels</i>: an array of allocated pixels values;
<li><i>npixels</i>: the number of elements in pixels;
<li><i>xcc</i>: a structure containing a lot of information about the current
	visual, colormap, maximum number of colors, color shifts and masks, etc...
	This structure is used when allocating colors. If you really want to know
	more about this structure, you should examine the following source files
	of the XmHTML Widget Set source code: <tt>XCC.c, XCC.h</tt> and
	<tt>XCCP.h</tt>
</ul>
<p>

<h3><a name="advanced_images_create"><font face="helvetica, arial">
	2.6.4.2 Creating a XmImage
</font></a></h3>
You can create an XmImage by using the <b>XmImageCreate</b> convenience
function. This function is defined as follows:
<pre>
XmImage *XmImageCreate(Widget w, String file, Dimension width,
	Dimension height);
</pre>
<i>w</i> must contain the id of a <b>Widget</b> (and not a Gadget) which will
be the owner of this image, <i>file</i> is the name of a file representing
the image that is to be loaded. The <i>width</i> and <i>height</i> arguments
allow you to scale the image. If both have the value 0 (zero), the 
dimensions of the loaded image will be the dimensions as found in the image.
Otherwise, <b>XmImageCreate</b> will scale to image to fit the given
dimensions. Scaling is only done in the directions for which a value is given:
if you only want to scale the image horizontally, you should only specify
a value for <i>width</i> and set <i>height</i> to zero (or a value for height
and 0 for width to only scale the image vertically).
<p>

Although the external image support is independent of a XmHTML widget, you can
also use the <b>XmImageInfo</b> structure to create a XmImage. An example where
this can be usefull is in conjuction with the
<b><font face="fixed">XmHTMLXYToInfo()</font></b> convenience function. 
As you may know by now, the return value of this function can contain a pointer
to a XmImageInfo structure. Supposing this is the case and you would want to
display a dialog box to the user with a thumbnail of the image, it is much
more convenient to create a XmImage directly from the XmImageInfo structure
instead of creating it from a file. 
<p>

The syntax of the <b>XmImageCreateFromInfo()</b> convenience function is as
follows:
<pre>
XmImage *XmImageCreateFromInfo(Widget w, XmImageInfo *info, Dimension width,
	Dimension height);
</pre>
The only difference with the <b>XmImageCreate()</b> function is that instead
of a filename you now supply a XmImageInfo structure.


<h3><a name="advanced_images_destroy"><font face="helvetica, arial">
	2.6.4.3 Destroying a XmImage
</font></a></h3>

When you are done using a XmImage, you should destroy it using the
<b>XmImageDestroy</b> convenience function. The syntax to this function is
as follows:
<pre>
void XmImageDestroy(XmImage *image);
</pre>

This function will take care of destroying all pixmaps, possible animation
data and will free the colors allocated to this image.  When this function
returns the given XmImage will no longer be valid.
<p>

One thing that this function will <b>not</b> do is release any
<b>XtIntervalId</b> that might be present in the given XmImage structure. It
is your responsibility to do this.

<h3><a name="advanced_images_using"><font face="helvetica, arial">
	2.6.4.4 How to use a XmImage
</font></a></h3>

<h4><font face="helvetica, arial">
	Normal Images
</font></h4>

<h4><font face="helvetica, arial">
	Running Animations
</font></h4>
For the sake of clarity, we will repeat the <i>animation data</i> of the
<a href="#advanced_images_xmimage">XmImage</a> structure here:
<pre>
	/* animation data */
	XmImageFrame *frames;	/* array of animation frames */
	int nframes;		/* no of frames following */
	int current_frame;	/* current frame count */
	int current_loop;	/* current loop count */
	int loop_count;		/* maximum loop count */
	XtIntervalId proc_id;	/* timer id for animations */
	Widget w;		/* image owner */
	XtAppContext context;	/* Application context for animations */
</pre>

The <i>*frames</i> field points to an array of structures of the following
type:
<pre>
typedef struct
{
	int x;			/* x position in logical screen */
	int y;			/* y position in logical screen */
	int w;			/* width of this particular frame */
	int h;			/* height of this particular frame */
	int timeout;		/* timeout for the next frame */
	unsigned char dispose;	/* previous frame disposal method */
	Pixmap pixmap;		/* actual image */
	Pixmap clip;		/* image clipmask */
	Pixmap prev_state;	/* previous screen state */

	/* private data */
	unsigned long *pixels;
	int npixels;
}XmImageFrame;
</pre>

The total number of frames is given by the <i>nframes</i> field in the XmImage
structure. Each member of this array of structures represents a single frame in
an animation, so displaying all frames in sequence will result in an animation
being shown to the user.
<p>

Before embarking on how to display animations, it is necessary that you
understand the what the fields of the XmImageFrame structure represent.
<p>

<b>x, y, w and h</b>
<p>

The first frame in an animation determines the screen size of the animation.
This is what is called the <i>logical screen</i>. Every following frame can
have a size equal to or less than the logical screen size. The <i>x</i> and 
<i>y</i> fields of the XmImageFrame structure determine the place of a frame
on the logical screen, while the <i>w</i> and <i>h</i> fields determine
the size of a frame.
<p>

<font face="helvetica, arial" size="3">[Note: Frames crossing logical screen
boundaries are automatically clipped by the XmImageCreate routines.]</font>
<p>

<b>timeout</b>
<p>

This field field indicates the number of milliseconds that should expire
before the next frame in an animation is displayed. 
<p>

<b>loop_count</b>
<p>

This field indicates how many times an animation should be run. A loop_count
of zero indicates forever. Any self-respecting application should run
animations with a non-zero loop_count only for the specified number of loops.
<p>

<b>dispose</b>
<p>

This indicates how the <b>previous</b> frame should be removed before a new
frame is displayed. This field can have the following values:
<p>

<dl>
<dt>XmIMAGE_DISPOSE_NONE (value = 1)
<dd>do nothing, overlay the previous frame with the current frame;

<dt>XmIMAGE_DISPOSE_BY_BACKGROUND (value = 2)
<dd>Restore to background color. The area used by the previous frame should
	be restored to the background color/image;
<p>

<dt>XmIMAGE_DISPOSE_BY_PREVIOUS (value = 3)
<dd>Restore to previous. The area used by the previous frame should be
	restored to what was there prior to rendering the previous frame.
</dl>
<p>
Handling disposal methods 2 and 3 are one of the most difficult items to deal
with when running an animation. This is the reason why the <i>prev_state</i>
field is present in the <b>XmImageFrame</b> structure.
<p>

The use of the remaining fields of the <b>XmImageFrame</b> structure will
become clear in the following example which demonstrates how to run an
animation and how to deal with the different disposal methods.

<p>
<i>Example 2-?: Running an animation</i><p>
<pre>
[Put in a copy of the src/paint.c, routine DrawFrame]
</pre>

<p>
<IMG SRC="../Images/wood/bar.gif" width=508 height=15>
<br>

<img ismap usemap=#back src="../Images/wood/back.gif" border=0>
<map name=back>
	<area href="progguide.html" shape=rect coords=0,0,83,33>
</map>

<img ismap usemap=#home src="../Images/wood/home.gif" border=0>
<map name=home>
	<area href="http://www.xs4all.nl" shape=rect coords=0,0,83,33>
</map>
<img ismap usemap=#email_map src="../Images/wood/email.gif" border=0>
<map name=email_map>
	<area href="mailto:ripley@xs4all.nl" shape=rect coords=0,0,83,33>
</map>

<br><IMG SRC="../Images/wood/bar.gif" width=508 height=15><br>
<i><font size="-1">
&copy;Copyright 1996-1997 by Ripley Software Development<br>
Last update: September 19, 1997 by Koen
</font></i>
</BODY>
</HTML>