This file is indexed.

/usr/share/gtk-doc/html/libbonobo/monikers-overview.html is in libbonobo2-dev 2.32.1-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Monikers in the Bonobo Component System</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="index.html" title="Libbonobo Reference Manual">
<link rel="up" href="monikers.html" title="Monikers">
<link rel="prev" href="monikers.html" title="Monikers">
<link rel="next" href="libbonobo-bonobo-moniker.html" title="BonoboMoniker">
<meta name="generator" content="GTK-Doc V1.16 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
<td><a accesskey="p" href="monikers.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="monikers.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">Libbonobo Reference Manual</th>
<td><a accesskey="n" href="libbonobo-bonobo-moniker.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr></table>
<div class="refentry">
<a name="monikers-overview"></a><div class="titlepage"></div>
<p>Monikers in the Bonobo Component System.</p>
<p>Miguel de Icaza (miguel@ximian.com)</p>
<div class="refsect1">
<a name="id403277"></a><h2>Monikers in the Bonobo Component System</h2>
<div class="refsect2">
<a name="id403283"></a><h3>Introduction</h3>
<p>
		We recently reimplemented and fully revamped the the
		Moniker support in Bonobo.  This work has opened a
		wide range of possibilities: from unifying the object
		naming space, to provide better integration in the
		system. </p>
<p> Note: on this document I have ommited exception
		environments handling for the sake of explaining the
		technology.</p>
</div>
<hr>
<div class="refsect2">
<a name="id403592"></a><h3>Monikers - a user perspective</h3>
<p>
		Monikers are used to name objects, they effectively
		implement an object naming space.  You can obtain
		monikers either because you created the moniker
		manually, or from a stringified representation of a
		moniker.</p>
<p>Here is a list of stringified monikers, and an
		interpretation of it:</p>
<div class="variablelist"><table border="0">
<col align="left" valign="top">
<tbody>
<tr>
<td><p><span class="term"><code class="literal">
		    file:quake-scores.gnumeric</code></span></p></td>
<td><p>
			    This would be a moniker that represents the
			    file <code class="filename">quake-scores.gnumeric</code>
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
		    oafid:GNOME:Gnumeric:WorkbookFactory:1.0</code></span></p></td>
<td><p>
			This moniker represents the Gnumeric Workbook
			factory object.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			oafid:GNOME:Gnumeric:WorkbookFactory:1.0:new:
			</code></span></p></td>
<td><p>
			This moniker represents a Gnumeric Workbook instance. 
			Notice that we are using the exact same OAFID
			as the example before, but there is a "new:"
			suffix at the end.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:/tmp/a.gz
			</code></span></p></td>
<td><p>
			This represents the file
			in <code class="filename">/tmp/a.gz</code>.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:/tmp/a.gz#gunzip
			</code></span></p></td>
<td><p>
			This represents the decompressed stream of
			data from <code class="filename">a.gz</code>.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:/tmp/a.gz#gunzip:streamcache
			</code></span></p></td>
<td><p>
			This provides a cache on top of the
			decompressed stream of data
			for <code class="filename">a.gz</code> (the streamcache
			moniker is an in-proc component).
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			http://www.gnome.org
			</code></span></p></td>
<td><p>
			This one represents the GNOME web site.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			evolution:Mail/Inbox
			</code></span></p></td>
<td><p>
			This represents the Evolution Mail/Inbox
			folder.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:quake-scores.gnumeric!January
			</code></span></p></td>
<td><p>
			This represents the January Sheet in the
			<code class="filename">quake-scores.gnumeric</code> workbook.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:quake-scores.gnumeric!January!Winner
			</code></span></p></td>
<td><p>
			This represents the cell whose name is
			"Winner" in the January sheet in the
			<code class="filename">quake-scores.gnumeric</code> workbook.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:quake-scores.gnumeric!January!Winner!Style!Font
			</code></span></p></td>
<td><p>
			This represents the Font interface of the
			Style attached to the Winner cell.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:quake-scores.gnumeric!Jannuary!Winner!Style!BackgroundColor
			</code></span></p></td>
<td><p>
			This represents the background color for the cell.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			http://www.gnome.org/index.html!title
			</code></span></p></td>
<td><p>
			This represents the title element in the HTML
			web page at <code class="literal">www.gnome.org</code>.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:toyota.xml!cars/car/model/
			</code></span></p></td>
<td><p>
			The "cars/car/model" is an XPath expression
			that for locating a specific node in the
			<code class="filename">toyota.xml</code> file.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			config:*/Session/Calendar
			</code></span></p></td>
<td><p>
			This represents a PropertyBag for the GNOME
			Calendar using the Local configuration system
			and using the settings stored in the Session
			domain.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			oafid:Helix:Evolution:Wombat:1.0
			</code></span></p></td>
<td><p>
			This represents the Evolution model server
			that stores all the per-user information.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			queue:oafid:Helix:Evolution:Wombat
			</code></span></p></td>
<td><p>
			This represents an interface that queues CORBA
			requests to the Evoution Wombat: Any calls
			issued will be queued: if the Wombat is busy
			or not accepting connection, all the CORBA
			method invocations will be queued without
			stopping the execution of the client code.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			http://www.gnome.org/index.html.gz#gunzip#html:title
			</code></span></p></td>
<td><p>
			This will reutrn the title element of the
			compressed HTML file at 
			<code class="literal">http://www.gnome.org/index.html.gz</code>
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			ftp://ftp.gnome.org/gnome-core-1.0.tar.gz#utar/gnome-core-1.0/ChangeLog
			</code></span></p></td>
<td><p>
			A reference to the ChangeLog file contained in
			the compressed gnome-core-1.0.tar.gz tar file
			at <code class="literal">ftp://ftp.gnome.org</code>.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			desktop:Backgound
			</code></span></p></td>
<td><p>
			The background object for the user's desktop.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			trashcan:
			</code></span></p></td>
<td><p>
			The system trashcan.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:logo.png
			</code></span></p></td>
<td><p>
			This represents the logo.png file.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			oafid:OAFIID:eog_viewer_factory:file:logo.png
			</code></span></p></td>
<td><p>
			This specifies a specific image viewer to be
			used to display the file "<code class="literal">logo.png</code>", in this
			case the "EOG" program.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:logo.png!Zoom=2.0
			</code></span></p></td>
<td><p>
			This represents
			the <code class="filename">logo.png</code> file in EOG
			at zoom level 2.0.
			</p></td>
</tr>
<tr>
<td><p><span class="term"><code class="literal">
			file:logo.png!Zoom=2.0,dither=max,notransparency
			</code></span></p></td>
<td><p>
			The image logo.png is configured to be zoomed
			at 2.0 factor, to do maximum dithering and not
			use any transparency.
			</p></td>
</tr>
</tbody>
</table></div>
<p>
		Now, what you saw above are some examples of
		stringified representations of monikers.  This means
		that they are not really monikers, it is the way a
		Moniker is represented in string form.
	    </p>
<p>
		Monikers typically are created either by using a
		Bonobo API call that transforms the stringified
		representation into an object (which exports the
		<code class="literal">IDL:Bonobo/Moniker:1.0</code> interface),
		like this:
	    </p>
<pre class="programlisting">
	moniker = bonobo_moniker_client_new_from_name (moniker_string);
	    </pre>
<p>
		Now, a moniker is only interesting because it can
		yield other objects when resolved.  During the
		resolution process, you specify which interface you
		are intersted on the moniker to return.  This is
		achieved by invoking the ::resolve method on the
		moniker and passing the repoid of the interface you
		desire, like this:</p>
<pre class="programlisting">
	Bonobo::Unknown control;

	control = moniker-&gt;resolve ("Bonobo/Control")
	    </pre>
<p> This would request the moniker to return an object
		that implements the IDL:Bonobo/Control:1.0 interface.
		This means that the object could be embedded as a
		regular Bonobo control in applications.</p>
<p> Maybe you do not want to get a control, but rather
		to resolve the moniker against a different interface,
		for instance a Bonobo::PropertyBag interface:</p>
<pre class="programlisting">
	properties = moniker-&gt;resolve ("Bonobo/PropertyBag");
	    </pre>
<p>The resolution process might yield completely different
		objects.</p>
<p>The parsing and resolution process is all
		encapsulated into a single API call for your
		convenience: the bonobo_get_object function:</p>
<pre class="programlisting">
	Bonobo::Unknown bonobo_object_get (char *moniker_string, char *interface);
	    </pre>
<p> Now, as I said, the resolution process might yield
		very different objects depending on the interface
		being requested, for example:</p>
<pre class="programlisting">
	x = bonobo_object_get ("http://www.gnome.org", "Bonobo/Control")
	y = bonobo_object_get ("http://www.gnome.org", "Bonobo/Stream")
	    </pre>
<p>The "x" object might launch Mozilla which would in turn load
		<code class="literal">www.gnome.org</code>, and the returned
		object can be used as a Bonobo Control, and used in
		your application as a widget.</p>
<p> The "y" object on the other hand does not need all
		the power of Mozilla, we are only requesting the very
		simple Stream interface, so we might be able to
		implement this with a lightweight HTTP implementation:
		maybe a wget-based bonobo server, or a libghttp
		server. </p>
<p> Note that even if the stringified versions of the
		monikers were the same (ie, "http://www.gnome.org")
		the resulting objects might differ wildely depending
		on the interface being requested. </p>
</div>
<hr>
<div class="refsect2">
<a name="id404220"></a><h3>The Moniker parsing system</h3>
<p>During parsing the Moniker stringified, Bonobo will
		use the colon-terminated prefix as the toplevel
		moniker to be invoked for the resolution process.</p>
<p>For the prefix "file:" the file moniker will be used;  For the
		prefix "oafid", the oafid moniker will be used;  For the
		"queue:" prefix, the queue moniker will be used.</p>
<p>Once the moniker that handles a specific prefix has
		been activated, the moniker will be requested to parse
		the remaining of the string specification and return a
		valid moniker.</p>
<p>Each moniker typically will consume a number of
		bytes up to the point where its domain stops, will
		figure out what is the next moniker afterwards.  Then
		it will activate the next moniker and pass the
		remaining of the moniker stringified version until the
		parsing is finished.</p>
<p>Each moniker is free to define its own mechanism for parsing,
		its special characters that are used to indicate the end of a
		moniker space, and the beginning of a new one (like the "#"
		and the "!" characters in some of the examples above).  This
		flexibility is possible because each moniker gets to define
		its rules (and this is important, as we want to integrate with
		standards like http and file).</p>
</div>
<hr>
<div class="refsect2">
<a name="id404253"></a><h3>Monikers as an object naming scheme</h3>
<p>As you can see, monikers are used to implement a
		naming system that can be used to reference and
		manipulate objects.  As you might have noticed, the
		::resolve method on the Moniker interface returns a
		Bonobo::Unknown interface.  And by definition, the
		bonobo_get_object also returns a Bonobo::Unknown.</p>
<p>This means that the resulting object from the
		moniker resolution will always support ref, unref and
		query_interface methods.</p>
<p>The Moniker object naming scheme is:</p>
<div class="variablelist"><table border="0">
<col align="left" valign="top">
<tbody>
<tr>
<td><p><span class="term">Extensible</span></p></td>
<td><p> A new entry point into the
			object naming space can be created and
			installed into the system.</p></td>
</tr>
<tr>
<td><p><span class="term">Hierarchical</span></p></td>
<td><p> Monikers. </p></td>
</tr>
</tbody>
</table></div>
</div>
<hr>
<div class="refsect2">
<a name="id404305"></a><h3>Creating Monikers</h3>
<p>Monikers are created typically by API calls into the
		Bonobo runtime or by your own classes that implement
		monikers.</p>
</div>
<hr>
<div class="refsect2">
<a name="id404318"></a><h3>Object Name Space</h3>
<div class="refsect3">
<a name="id404322"></a><h4>Comparing the Moniker name space with the
		Unix Name Space</h4>
<p> Lets start simple.  A moniker is a reference to
		    an object[1].  To actually use the object, you
		    have to "resolve" the moniker.  The term used in
		    the literature is "binding the object". </p>
<p> The result of resolving the moniker is a
		    <code class="literal">Bonobo::Unknown</code> object.</p>
<p>Think of a moniker as a pathname.  And think of the
		    binding process as the "open" system call on Unix.</p>
<p>Example:</p>
<div class="informaltable"><table border="0">
<colgroup>
<col>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td> </td>
<td>Unix Files</td>
<td>Monikers</td>
</tr>
<tr>
<td>Object naming:</td>
<td>path name</td>
<td>moniker string representation</td>
</tr>
<tr>
<td>Binding function:</td>
<td>open(2)</td>
<td>bonobo_get_object</td>
</tr>
<tr>
<td>Return value:</td>
<td>kernel file descriptor</td>
<td>Bonobo::Unknown CORBA reference</td>
</tr>
<tr>
<td>Binder:</td>
<td>Kernel VFS+each FS</td>
<td>bonobo_get_object + Bonobo::Moniker</td>
</tr>
<tr>
<td>Persisting:</td>
<td>none</td>
<td>Moniker::QI(Persist)</td>
</tr>
</tbody>
</table></div>
<p>In the case of the file system, the kernel does
		    the "resolution" of each path element by parsing
		    one element of the file system, and the Virtual
		    File System switch uses the current file system +
		    mount points to resolve the ultimate file name.</p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="id404464"></a><h3>File Linking</h3>
<p> Monikers were originally implemented as part of the
		Microsoft OLE2 compound document system.  They can be
		used effectively by applications during drag and drop
		and cut and paste operations to pass objects that must
		be linked by other applications.</p>
<p>The source application would create a moniker for a
		given object that would fully identify it, and pass it
		through a drag and drop operation or a cut and paste
		operation to the recipient application.</p>
<p>The recipient application then can resolve the
		moniker against the interface required (in the Bonobo
		case, Bonobo/Embeddable, or Bonobo/Control would be a
		common choice).</p>
<p>Applications do not need to store the entire
		contents of linked information, they can just store a
		stringified representation of the moniker, and resolve
		it again at load time.</p>
</div>
<hr>
<div class="refsect2">
<a name="id404491"></a><h3>Instance initialization</h3>
<p>Monikers can be used to initialize objects, as a way
		of passing arguments to your object.  This is coupled
		with the Bonobo/ItemContainer interface and the Item
		Moniker.</p>
<p>The Item Moniker is covered later.</p>
</div>
<hr>
<div class="refsect2">
<a name="id404505"></a><h3>Resolution of a moniker against an interface</h3>
<p>A moniker can be resolved against different
		interfaces.  The resulting object might be different
		depending on the interface that is being resolved.  To
		illustrate this, here is an example, lets say we have
		the <code class="literal">"http://www.helixcode.com"</code>
		string representation of a moniker.</p>
<p>The string representation of the moniker can be resolved
		against the "Bonobo/Control" interface:</p>
<pre class="programlisting">
	bonobo_get_object ("http://www.helixcode.com", "Bonobo/Control");
	    </pre>
<p>This could return an embeddable Mozilla component
		that is suitable to be embedded into your application
		as a widget (because we are requesting the moniker to
		return a Bonobo/Control interface).  If the interface
		is resolved against the "Bonobo/Stream"
		interface,maybe Mozilla is not required, and the
		process could use a smaller process that just provides
		Bonobo/Streams, say a corbaified wget.</p>
<p>The logic for this lives on the http: moniker
		handler.</p>
</div>
<hr>
<div class="refsect2">
<a name="id404543"></a><h3>Core monikers</h3>
<p>Bonobo ships with a number of moniker handlers: the
		<code class="literal">file</code> moniker,
		the <code class="literal">item</code> moniker,
		the <code class="literal">oafid</code> moniker and
		the <code class="literal">new</code> moniker.</p>
<div class="refsect3">
<a name="id404575"></a><h4>The file moniker</h4>
<p>The file moniker is used to reference files.
		    For instance:</p>
<pre class="programlisting">file:sales.gnumeric</pre>
<p> The file moniker will scan its argument until
		    it reaches the special characters `#' or `!' which
		    indicate the end of the filename.</p>
<p>The file moniker will use the mime type
		    associated with the file to find a component that
		    will handle the file.  Once the object handler has
		    been invoked, the Moniker will try to feed the
		    file to the component first through quering the
		    PersistFile interface, and if this is not
		    supported, through the PersistStream interface.</p>
</div>
<div class="refsect3">
<a name="id404602"></a><h4>The item moniker</h4>
<p>The item moniker is typically triggered by the
		    "!" string in the middle.  The item moniker can be
		    used to implement custom object naming, or
		    argument handling.</p>
<p>The item moniker parses the text following '!'
		    until the next '!' character, this is called the
		    argument of the item moniker.  During the
		    resolution process, the item moniker will request
		    from its parent the Bonobo/ItemContainer interface
		    and will invoke the getObject on this interface
		    with the argument.</p>
<p>For example, in a Gnumeric spreadsheet this
		    allows programmers to reference sub-objects by
		    name.  For instance, Workbooks can locate Sheet
		    objects; Sheets can locate range names, cell
		    names, or cell references.</p>
<p>This moniker would reference the sheet named
		    `Sales' in the workbook contained in the
		    sales.gnumeric spreadsheet:</p>
<pre class="programlisting">
	sheet = bonobo_get_object ("sales.gnumeric!Sales", "Gnumeric/Sheet");
		</pre>
<p>This other would reference the cell that has been named
		    `Total' inside the Sheet "Sales":</p>
<pre class="programlisting">
	cell = bonobo_get_object ("sales.gnumeric!Sales!Total", "Gnumeric/Cell")
		</pre>
<p> The way this works from the container
		    perspective, is that the container will implement
		    the <code class="function">getObject</code> (string)
		    method, and would respond to
		    the <code class="function">getObject</code> request.</p>
<p> Item monikers can also be used to perform
		    instance initialization.  The component that wants
		    to support instance initialization needs to
		    support the Bonobo/ItemContainer interface and
		    implement a getObject method that would return the
		    object properly initialized.</p>
<p> For example, lets consider an image viewer
		    component that can be configured, like this: </p>
<pre class="programlisting">
	image = bonobo_get_object ("file.jpg!convert_to_gray=on", "Bonobo/Control")
		</pre>
<p>The above example would activate the EOG
		    component because of the file.jpg match, and then
		    invoke EOG's ItemContainer implementation with the
		    argument "convert_to_gray=on".  getObject should
		    return an object (which would be itself) but it
		    would modify the instance data to set the
		    "convert_to_gray" flag to on.  Like this:</p>
<pre class="programlisting">
Bonobo_Unknown
eog_item_container_get_object (BonoboObject *o, char *name)
{
	if (command_is (name, "convert_to_gray", &amp;v))
		image_set_convert_to_gray (o, v);
	...
	bonobo_object_ref (o);
	return bonobo_objet_corba_objref (o);
}
		</pre>
</div>
<div class="refsect3">
<a name="id404691"></a><h4>The oafiid moniker</h4>
<p>The <code class="literal">oafid:</code> moniker handles
		    activation using the Object Activation Framework.
		    This allows application programmers to activate
		    objects by their OAF ID, like this:</p>
<pre class="programlisting">
	gnumeric = bonobo_object_get ("oafiid:GNOME_Gnumeric_Workbook", iface)
		</pre>
</div>
<div class="refsect3">
<a name="id404714"></a><h4>The "new:" moniker</h4>
<p>The new moniker requests from its parent the
		    "Bonobo/GenericFactory" interface and invokes the
		    method create_instance in the interface.</p>
<p>Typically this moniker would be invoked like this:</p>
<pre class="programlisting">
		bonobo_get_object ("oafid:RandomFactory:new:", iface);
		</pre>
<p>In the example above "RandomFactory" is the
		    OAFID for the factory for a certain object.
		    During the resolution process, the "new:" moniker
		    would request its parent to resolve against the
		    IDL:GNOME/ObjectFactory:1.0 interface (which is
		    the traditional factory interface in GNOME for
		    creating new object instances) and then invoke the
		    new_instance method on it.</p>
<p>Historically GNORBA (the old GNOME object
		    activation system) and OAF (the new object
		    activation system) implemented a special "hack" to
		    do this same processing.  Basically, the
		    description files for the object activation system
		    was overloaded, there were three types of
		    activation mechanism defined:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>activate object implementation from an
			executable.</p></li>
<li class="listitem"><p>activate object implementation from a
			shared library.</p></li>
<li class="listitem"><p>activate object implementation by
			launching another object, and querying the
			launched object for the ObjectFactory
			interface.</p></li>
</ul></div>
<p>The "new:" moniker basically obviates the need
		    for the last step in the activation system.  With
		    OAF, using the OAF approach proves to be more
		    useful, as it is possible to query OAF for
		    components that have certain attributes, and the
		    attributes for a factory object are not as
		    interesting as the attributes for the instances
		    themselves.  Despite this, the "new:" moniker can
		    be used for performing the operation of instance
		    initialization in more complex scenarios that go
		    beyond the scope of activation provided by
		    OAF.</p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="id404775"></a><h3>Adding moniker handlers to the system</h3>
<p><b>Ideal monikers: </b>There are two moniker handlers that would be
		    interesting to implement: the Configuration
		    Moniker and the VFS moniker.</p>
<p>They both help the system overall, because the added
		simplicity of having a standard way of activating
		services in the system and given that the API to these
		services is CORBA-based, any programming language with
		CORBA/Bonobo support can make use of them without the
		need of a special language binding.</p>
<p>I am convinced that this helps make the system more
		self consistant internally.</p>
<div class="refsect3">
<a name="id404799"></a><h4>The Configuration Moniker</h4>
<p>The configuration moniker is invoked by using
		    the <code class="literal">"config:"</code> prefix.  The
		    string afterwards is the configuration locator.
		    The moniker should support being querried against
		    the "Bonobo/Property" or "Bonobo/PropertyBag"
		    depending on whether we are requesting a set of
		    attributes, or a single attribute.</p>
<p>For example, retrieving the configuration
		    information for a specific configuration property
		    in Gnumeric would work like this:</p>
<pre class="programlisting">
	Bonobo_Property auto_save;
	CORBA_Any value;
	
	auto_save = bonobo_get_object (
		"config:gnumeric/auto-save", "/Bonobo/Property");
	value = bonobo_property_get_value (auto_save, &amp;ev);
	if (value-&gt; tc-&gt; kind == CORBA_tk_bool)
	    printf ("Value: %s\n", (CORBA_bool) value-&gt;_value ? "true" : "false");
	else
	    printf ("Property is not boolean\n");
		</pre>
<p> In the above example, we first use the
		    <code class="function">bonobo_get_object</code> routine to locate the
		    configuration object through its moniker.  The
		    return value from the <code class="function">bonobo_get_object</code> is of type
		    <code class="literal">Bonobo_Property</code> which is the
		    standard Bonobo way of manipulating
		    properties.</p>
<p>This has two main advantages:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<p>By accessing the configuration engine
			    through the moniker interface we have
			    eliminated the need to define a C-specific
			    API for the configuration management.  The
			    configuration could have been reached
			    through any other programming language
			    that supports CORBA.</p>
<p>The GNOME project has always tried to
			    define APIs that could be easily wrapped
			    and accessed from various languages
			    (particularly, we have done this with the
			    toolkit and recently with the CORBA
			    bindings).</p>
<p>But even if we have taken special care
			    of doing this, and there are continous
			    efforts to wrap the latest and greatest
			    APIs, widgets, and tools, the bindings
			    typically lag a few weeks to monthsw
			    behind the actual C API.</p>
<p>By moving towards CORBA, we only need to
			    support CORBA in the various programming
			    languages and we get access to any new
			    APIs defined by it.</p>
</li>
<li class="listitem"><p>Any tools on the system that can
			    manipulate a Bonobo::Property or
			    ::PropertyBag (a GUI in a visual designer,
			    or a configuration engine that
			    persists/hidrates objects, or a browsing
			    tool) can talk directly to the
			    configuration engine all of a sudden, as
			    we are using the same interface method
			    across every language on the system.</p></li>
</ul></div>
<p>The Bonobo::Property interface is pretty
		    comprehensive, and should address most needs, the
		    methods are:</p>
<pre class="synopsis">
	string   get_name ();
	TypeCode get_type ();
	any      get_value ();
	void     set_value ();
	any      get_default ();
	string   get_doc_string ();
	long     get_flags ();
		</pre>
<p>Now, this interface as you can see does not
		    specify an implementation for the actual backend.
		    Given that this is just an interface, we do not
		    care what the moniker will connect us to, we only
		    care with the fact that we will be able to use the
		    Property and PropertyBag interfaces.</p>
</div>
<div class="refsect3">
<a name="id404915"></a><h4>Configuration transactions</h4>
<p>Handling of transactional changes to the
		    configuration system can be achieved by the use of
		    the setValues interface in the PropertyBag.  The
		    implementation of the PropertyBag can either
		    accept the values set, or it can do consistency
		    checking of the values being set (for instance, to
		    avoid the configuration to contradict itself, or
		    store invalid values).  If the values being set
		    are invalid, an exception is thrown.</p>
<p>It would be also possible to hook up an
		    arbitrary consistency checking component in the
		    middle, by inserting the consistency checking in
		    the middle of the stream, like this:</p>
<pre class="programlisting">
	bonobo_get_object ("config:gnumeric/auto-save:gnumeric-consistency-check:", "Bonobo/Property");
		</pre>
<p>Notice the `gnumeric-consistency-check:' moniker handler.
		    This could just be a shared library consistency checking
		    component if it needs to be.</p>
</div>
<div class="refsect3">
<a name="id404944"></a><h4>Listening to changes.</h4>
<p>
		    One of the requirements for a modern desktop is to
		    be react globally when changes are made to global
		    settings.  For example, in the GNOME desktop when
		    a theme is changed, a special protocol inside Gtk+
		    is used to notify all the applications that they
		    should reload their theme configuration.
		</p>
<p>There are many other examples where applications
		    need to keep track of the current setting.  For
		    example, when a preference is changed, we want the
		    preference to take place right away, without us
		    having to restart our running applications.
		</p>
<p>This is easily achieved by registering a
		    Listener with the Bonobo/EventSource in the
		    PropertyBag.</p>
</div>
<div class="refsect3">
<a name="id404965"></a><h4>What about GConf?</h4>
<p>GConf is a configuration management
		    infrastructure that provides the following
		    features:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>A schema system for specifying the
			various configuration options, as well as
			their documentation and initial values
			(default values).</p></li>
<li class="listitem"><p>A way for the system administrator
			to override values in a system-wide fashion
			(this encompasses a network-wise setup if
			desired).</p></li>
<li class="listitem"><p>A change notification system:
			applications might be notified of changes to
			various values they might want to keep track
			of.</p></li>
</ul></div>
<p>There are two drawbacks to GConf currently:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>Although gconf provides pretty
			much everything that is required, but it is a
			C-based API that needs to be wrapped for every
			language that wants to support GConf.</p></li>
<li class="listitem"><p>GConf is limited in the kind of
			information that can be stored on its
			database.  A BonoboProperty stores a CORBA_Any
			which can contain any of the simple CORBA
			types (strings, integers, floating points,
			booleans), structures, arrays and
			unions.</p></li>
</ul></div>
<p>The actual engine and backend for GConf could
		    become the configuration moniker handler, only the
		    API would be replaced as well as the actual
		    storage system to support the more complete
		    CORBA_Any, and the ad-hoc CORBA interface can be
		    replaced with a more powerful system.</p>
</div>
<div class="refsect3">
<a name="id405025"></a><h4>Configuration management: Open Issues</h4>
<p><b>Specifying the location for
		    configuration. </b>The syntax for accessing the configuration
			has not been defined, but we can cook this up
			pretty easily.</p>
<p>Forcing the configuration data to be loaded from
		    a specific location.  Although the arguments to
		    the moniker could be used to encode a specific
		    location, for example:</p>
<pre class="programlisting">
	config:~/file.config!auto-save
		</pre>
<p> It seems more natural to use the file moniker
		    to provide this information, for example:</p>
<pre class="programlisting">
	file:~/file.config!config:auto-save
		</pre>
<p>The config moniker can test for the presence of
		    a parent, and if the parent exists, then it would
		    request one of the Persist interfaces from it to
		    load the actual configuration file, and provide
		    access to it.
		    </p>
<p><b>Transactional setting of values. </b>It might make sense to "batch" a number of
			changes done under a prefix to avoid listeners
			to a range of keys to reset themselves
			multiple times.  Consider the case in which a
			command line tool makes various changes to the
			background properties, say the changes are
			done in this order:</p>
<pre class="programlisting">
	background = bonobo_get_object ("config:desktop/background", "PropertyBag");
	bonobo_property_bag_set_values (background, 
		bonobo_property_list_new (
			"gradient", "string", "true",
			"color1",   "string"  "red",
			"color2",   "string"  "blue",
			&amp;ev);
		</pre>
<p>If the real configuration program for handling
		    the background is running at that point, it will
		    have registered to be notified of changes to all
		    those values.  The changes might be very
		    expensive.  For example the code migh react to
		    every change and recompute the whole background
		    image on each change.</p>
<p>An optimization would be to tag the beginning of
		    the transaction and the end of it in the client
		    code to allow listeners to get batched
		    notification of changes:</p>
<pre class="programlisting">
	background = bonobo_get_object ("config:desktop/background", iface);
	bonobo_property_bag_batch_push (background);
	bonobo_property_set (background, "gradient", "true");
	bonobo_property_set (background, "color1", "red");
	bonobo_property_set (background, "color2", "blue");
	bonobo_property_bag_batch_pop (background);
		</pre>
<p>This would allow the listener code to batch all
		    the expensive requests into a single pass.</p>
<p><b>Configuration handlers. </b>Consider the example above, we would like to
			be able to change properties on the system and
			have those properties to take effect
			independently of whether a listener is
			registered or not.</p>
<p>A property handler might register with the
		    configuration moniker to be launched when a
		    property changes.  This could be done in a file
		    installed in a special location.</p>
</div>
<div class="refsect3">
<a name="id405128"></a><h4>The GNOME VFS becomes deprecated.</h4>
<p>The GNOME VFS provides an asyncronouse
		    file-system interface abstraction that can be used
		    to access local files, remote files, files in
		    compressed files and more.</p>
<p>The problem with the GNOME VFS is that it is
		    very limited: it can only expose a file system
		    like interface to its clients (very much like the
		    Unix interface after which it was modeled).</p>
<p> As covered before in the `Object Naming Space',
		    Monikers define an object naming space, and
		    monikers can be defined for any type of resource
		    that the GNOME VFS supports (a transitional path
		    might include a set of monikers implemented on top
		    of the actual GNOME VFS).</p>
<p> A file dialog could request a moniker to be
		    resolved against a "Graphical File Listing"
		    interface, which might result in a miniature
		    Nautilus window to be embedded in the dialog
		    box.</p>
<p>It would be possible to entirely reuse the
		    existing GNOME VFS code by providing monikers for
		    the various access methods that would handle the
		    special cases "Stream", "Storage" and
		    "FileListing".  Other interfaces will be plugged
		    into the moniker handler to support the richer
		    content.</p>
<p> For instance, consider the "trashcan:" moniker.
		    The trashcan moniker could be resolved against
		    various interfaces.  A file manager would resolve
		    it against a DirectoryListing interface to display
		    the contents of it; It could resolve it against a
		    "Control" interface to get a trahscan custom view
		    (to configure the values in the trashcan); a
		    PropertyBag interface could be used to
		    programmatically configure the various settings in
		    it.</p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="id405169"></a><h3>Other monikers</h3>
<p>There is another family of moniker handlers that are
		worth stuyding.  The filtering moniker handlers and
		the caching moniker handlers.</p>
<div class="refsect3">
<a name="id405178"></a><h4>The <code class="literal">streamcache:</code> moniker</h4>
<p>The idea of the streamcache: moniker is to be
		    basically a shared library moniker handler that
		    provides a cache for the IDL:Bonobo/Stream:1.0
		    interface.</p>
<p>This moniker is very simple, during resolution
		    it requests the IDL:Bonobo/Stream:1.0 interface
		    from its parent and it can only expose the
		    IDL:Bonobo/Stream:1.0 interface to clients.</p>
<p>The plus is this: it is a shared library
		    component, which will run in the address space of
		    the application that will use the Stream, and it
		    provides a cache to the parent Stream (so we can
		    use small granular method invocations, and the
		    stream cache can do the traditional buffering).</p>
<p> Think of this difference as the one between an
		    application using write()/read and the application
		    using fwrite/fread/getc/putc: although many
		    applications can implement their own buffering,
		    most of the time just using the libc-provided ones
		    (fwrite/fread/getc/putc) will do it.  This is
		    exactly what the streamcache: moniker will do: By
		    appending this to a stringified representation of
		    a moniker, you can get a Stream cache for free.</p>
</div>
<div class="refsect3">
<a name="id405213"></a><h4>The #gunzip, #utar filtering monikers</h4>
<p>The #utar moniker is a moniker that would
		    implement tar file decoding (the same concept can
		    be used for other archive formats).  This moniker
		    uses an auxiliary tar component handler.  The
		    moniker connects the tar component handler to the
		    parent object's Stream interface and returns the
		    resulting object.  The result of the #utar moniker
		    can be either a Bonobo/Stream (for a file
		    reference) or Bonobo/Storage (for a directory
		    reference).</p>
<p>Like this:</p>
<pre class="programlisting">
	file:/home/miguel/mail-backup.tar#utar:2000/may/1001
	ftp://ftp.helixcode.com/pub/sources/gnome-libs-1.2.tar.gz#gunzip#utar:/README
		</pre>
<p>The beauty of this system is that if two
		    applications use the same moniker, they would be
		    sharing the same data without having to uncompress
		    two times the same tar file.</p>
<p>This is all achieved transparently. This would
		    happen in quite a few instances, for example, if
		    you are exploring a compressed tar file in a file
		    manager and you drag the file to another
		    Moniker-aware application, say Gnumeric, Gnumeric
		    would be using the same file that was openened by
		    the file manager instead of having two
		    uncompressed sets of files in your system.</p>
<p>The above scenario is particularly useful if you
		    have little space, or if the process of untaring a
		    file would take a long time.</p>
</div>
<div class="refsect3">
<a name="id405252"></a><h4>The propertycache: moniker</h4>
<p>Accessing individual properties over and over
		    might take quite some time due to the CORBA round
		    trips.  The propertycache: moniker would be also a
		    shared library handler that would basically
		    activate the property moniker, and would set up
		    property listeners (which would be notified of
		    changes in the property data base).</p>
<p>So if your application does a lot of queries to
		    a property, you might just want to append this to
		    improve performance and not care about doing
		    clustered reads, the cache would do this for
		    you.</p>
<p>This is not implemented, as it requires the
		    property moniker to be written.</p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="id405275"></a><h3>The accidental invention</h3>
<p>Monikers were invented originally in OLE2 to
		implement Object Linking.  The OLE2 programmers
		accidentally invented an object naming system.</p>
<p>This object naming system is not only very powerful,
		but it is extensible and it helps make the system more
		consistent.</p>
</div>
<hr>
<div class="refsect2">
<a name="id405289"></a><h3>Monikers and the GNOME VFS</h3>
<p>
		Some people ask: monikers look as if they are just
		re-implementing the GNOME-VFS, why is that?</p>
<p>For a storage backend you can always use something
		like bonobo_storage_new ("gnome-vfs") and get away
		with life.</p>
<p>The main difference between the gnome-vfs, and
		monikers is that monikers are used to implement an
		object-based name space, while the gnome-vfs is a fine
		abstraction for naming files and directories.  The
		moniker space goes well beyond this.</p>
<p>When Ettore, Nat and I designed the GNOME VFS in
		Paris Ettore had a grander vision than Nat and I had.
		Nat and I wanted exactly what the GNOME VFS is: an
		asyncronous, pluggable virtual file system
		implementation.  Ettore wanted something more general,
		something that would implement an object name space.
		And some of the design decisions in the core of the
		gnome-vfs reflect some of this thinking, but the API
		and the infrastructure was limited to handling
		files.</p>
<p>Various months later, we finally understood
		completely the moniker system, and we realized that
		monikers were an object naming space, and that if done
		correctly monikers would be able to implement Ettore's
		initial vision for having an object-based naming
		space.</p>
</div>
<hr>
<div class="refsect2">
<a name="id405322"></a><h3>Open Issues</h3>
<p>We will need to research the implementation
		requirements for asyncronous parsing and resolution of
		Monikers.</p>
<p>Currently, both the Object Activation Framework and
		Bonobo support asyncronous activation.  Implementing
		this for Monikers should not be hard, but might
		require a few changes in the Moniker interface.</p>
</div>
<hr>
<div class="refsect2">
<a name="id405337"></a><h3>Conclusion</h3>
<p>Monikers are very powerful mechanisms that can unify
		the name space of objects in the system and can be
		used to provide a uniform access method for a wide
		variety of tasks:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>Component initialization</p></li>
<li class="listitem"><p>Addressing objects</p></li>
<li class="listitem"><p>Addressing sub-objects in a compound
		    document.</p></li>
<li class="listitem"><p>Implementing Object Linking.</p></li>
<li class="listitem"><p>Implementing nested objects, and nested handlers for
		    file systems.</p></li>
</ul></div>
</div>
<hr>
<div class="refsect2">
<a name="id405374"></a><h3>Acknowledgements</h3>
<p>The Bonobo moniker implementation was done by
		Michael Meeks.</p>
<p>The design for the Bonobo moniker system was done by
		Ettore Perazzoli, Michael Meeks and myself.</p>
</div>
</div>
</div>
<div class="footer">
<hr>
          Generated by GTK-Doc V1.16</div>
</body>
</html>