summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2011-11-30 16:29:56 +0000
committerJonny Lamb <jonny.lamb@collabora.co.uk>2011-11-30 16:29:56 +0000
commitc27d23ab605c1e01a2fe5542f6140d71f47eccc4 (patch)
tree0ecddd92fa32bd5dc19f4cba28a1d8ea0d5b8dbf
parentb40460beb2fd3ba1f737f9d830fe731ac7fca846 (diff)
parent03ff6d8645aaed47f8477f94bc663bb9f43bade7 (diff)
Merge remote-tracking branch 'spec/testing'
-rw-r--r--spec/.gitignore12
-rw-r--r--spec/AUTHORS17
-rw-r--r--spec/COPYING510
-rw-r--r--spec/COPYRIGHT13
-rw-r--r--spec/Makefile121
-rw-r--r--spec/NEWS301
-rw-r--r--spec/README96
-rw-r--r--spec/doc/templates/devhelp.devhelp224
-rw-r--r--spec/doc/templates/errors.html65
-rw-r--r--spec/doc/templates/favicon.pngbin0 -> 1813 bytes
-rw-r--r--spec/doc/templates/fullindex.html61
-rw-r--r--spec/doc/templates/generic-types.html60
-rw-r--r--spec/doc/templates/index.html89
-rw-r--r--spec/doc/templates/interface.html566
-rw-r--r--spec/doc/templates/interfaces.html61
-rw-r--r--spec/doc/templates/jquery.js6240
-rw-r--r--spec/doc/templates/jquery.min.js23
-rw-r--r--spec/doc/templates/magic.js47
-rw-r--r--spec/doc/templates/style.css350
-rw-r--r--spec/doc/templates/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--spec/spec/Account.xml715
-rw-r--r--spec/spec/Account_Interface_Addressing.xml76
-rw-r--r--spec/spec/Account_Interface_Avatar.xml75
-rw-r--r--spec/spec/Account_Interface_External_Password_Storage.xml58
-rw-r--r--spec/spec/Account_Interface_Hidden.xml65
-rw-r--r--spec/spec/Account_Interface_Storage.xml169
-rw-r--r--spec/spec/Account_Manager.xml288
-rw-r--r--spec/spec/Account_Manager_Interface_Hidden.xml100
-rw-r--r--spec/spec/Authentication_TLS_Certificate.xml305
-rw-r--r--spec/spec/Call_Content.xml213
-rw-r--r--spec/spec/Call_Content_Interface_Audio_Control.xml111
-rw-r--r--spec/spec/Call_Content_Interface_Media.xml581
-rw-r--r--spec/spec/Call_Content_Interface_Video_Control.xml136
-rw-r--r--spec/spec/Call_Content_Media_Description.xml236
-rw-r--r--spec/spec/Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml145
-rw-r--r--spec/spec/Call_Content_Media_Description_Interface_RTCP_Feedback.xml61
-rw-r--r--spec/spec/Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml73
-rw-r--r--spec/spec/Call_Interface_Mute.xml146
-rw-r--r--spec/spec/Call_Stream.xml309
-rw-r--r--spec/spec/Call_Stream_Endpoint.xml400
-rw-r--r--spec/spec/Call_Stream_Interface_Media.xml770
-rw-r--r--spec/spec/Channel.xml557
-rw-r--r--spec/spec/Channel_Bundle.xml48
-rw-r--r--spec/spec/Channel_Dispatch_Operation.xml483
-rw-r--r--spec/spec/Channel_Dispatcher.xml774
-rw-r--r--spec/spec/Channel_Dispatcher_Interface_Operation_List.xml140
-rw-r--r--spec/spec/Channel_Future.xml68
-rw-r--r--spec/spec/Channel_Handler.xml78
-rw-r--r--spec/spec/Channel_Interface_Addressing.xml107
-rw-r--r--spec/spec/Channel_Interface_Anonymity.xml68
-rw-r--r--spec/spec/Channel_Interface_Call_State.xml147
-rw-r--r--spec/spec/Channel_Interface_Chat_State.xml144
-rw-r--r--spec/spec/Channel_Interface_Conference.xml628
-rw-r--r--spec/spec/Channel_Interface_Credentials_Storage.xml59
-rw-r--r--spec/spec/Channel_Interface_DTMF.xml342
-rw-r--r--spec/spec/Channel_Interface_Destroyable.xml82
-rw-r--r--spec/spec/Channel_Interface_File_Transfer_Metadata.xml98
-rw-r--r--spec/spec/Channel_Interface_Group.xml1252
-rw-r--r--spec/spec/Channel_Interface_HTML.xml86
-rw-r--r--spec/spec/Channel_Interface_Hold.xml232
-rw-r--r--spec/spec/Channel_Interface_Media_Signalling.xml189
-rw-r--r--spec/spec/Channel_Interface_Mergeable_Conference.xml110
-rw-r--r--spec/spec/Channel_Interface_Messages.xml1484
-rw-r--r--spec/spec/Channel_Interface_Password.xml114
-rw-r--r--spec/spec/Channel_Interface_Picture.xml198
-rw-r--r--spec/spec/Channel_Interface_Room.xml368
-rw-r--r--spec/spec/Channel_Interface_Room_Config.xml267
-rw-r--r--spec/spec/Channel_Interface_SASL_Authentication.xml723
-rw-r--r--spec/spec/Channel_Interface_SMS.xml287
-rw-r--r--spec/spec/Channel_Interface_Securable.xml78
-rw-r--r--spec/spec/Channel_Interface_Service_Point.xml86
-rw-r--r--spec/spec/Channel_Interface_Splittable.xml71
-rw-r--r--spec/spec/Channel_Interface_Subject.xml128
-rw-r--r--spec/spec/Channel_Interface_Transfer.xml53
-rw-r--r--spec/spec/Channel_Interface_Tube.xml289
-rw-r--r--spec/spec/Channel_Request.xml345
-rw-r--r--spec/spec/Channel_Type_Call.xml1583
-rw-r--r--spec/spec/Channel_Type_Contact_List.xml107
-rw-r--r--spec/spec/Channel_Type_Contact_Search.xml481
-rw-r--r--spec/spec/Channel_Type_DBus_Tube.xml199
-rw-r--r--spec/spec/Channel_Type_File_Transfer.xml585
-rw-r--r--spec/spec/Channel_Type_Room_List.xml166
-rw-r--r--spec/spec/Channel_Type_Server_Authentication.xml121
-rw-r--r--spec/spec/Channel_Type_Server_TLS_Connection.xml117
-rw-r--r--spec/spec/Channel_Type_Stream_Tube.xml292
-rw-r--r--spec/spec/Channel_Type_Streamed_Media.xml853
-rw-r--r--spec/spec/Channel_Type_Text.xml614
-rw-r--r--spec/spec/Channel_Type_Tubes.xml615
-rw-r--r--spec/spec/Client.xml122
-rw-r--r--spec/spec/Client_Approver.xml201
-rw-r--r--spec/spec/Client_Handler.xml337
-rw-r--r--spec/spec/Client_Handler_Future.xml88
-rw-r--r--spec/spec/Client_Interface_Requests.xml175
-rw-r--r--spec/spec/Client_Observer.xml447
-rw-r--r--spec/spec/Connection.xml1311
-rw-r--r--spec/spec/Connection_Future.xml110
-rw-r--r--spec/spec/Connection_Interface_Addressing.xml248
-rw-r--r--spec/spec/Connection_Interface_Aliasing.xml185
-rw-r--r--spec/spec/Connection_Interface_Anonymity.xml165
-rw-r--r--spec/spec/Connection_Interface_Avatars.xml516
-rw-r--r--spec/spec/Connection_Interface_Balance.xml131
-rw-r--r--spec/spec/Connection_Interface_Capabilities.xml254
-rw-r--r--spec/spec/Connection_Interface_Cellular.xml157
-rw-r--r--spec/spec/Connection_Interface_Client_Types.xml218
-rw-r--r--spec/spec/Connection_Interface_Communication_Policy.xml163
-rw-r--r--spec/spec/Connection_Interface_Contact_Blocking.xml207
-rw-r--r--spec/spec/Connection_Interface_Contact_Capabilities.xml306
-rw-r--r--spec/spec/Connection_Interface_Contact_Groups.xml549
-rw-r--r--spec/spec/Connection_Interface_Contact_Info.xml550
-rw-r--r--spec/spec/Connection_Interface_Contact_List.xml1085
-rw-r--r--spec/spec/Connection_Interface_Contacts.xml191
-rw-r--r--spec/spec/Connection_Interface_Forwarding.xml346
-rw-r--r--spec/spec/Connection_Interface_Keepalive.xml73
-rw-r--r--spec/spec/Connection_Interface_Location.xml464
-rw-r--r--spec/spec/Connection_Interface_Mail_Notification.xml624
-rw-r--r--spec/spec/Connection_Interface_Power_Saving.xml109
-rw-r--r--spec/spec/Connection_Interface_Presence.xml346
-rw-r--r--spec/spec/Connection_Interface_Privacy.xml94
-rw-r--r--spec/spec/Connection_Interface_Renaming.xml98
-rw-r--r--spec/spec/Connection_Interface_Requests.xml631
-rw-r--r--spec/spec/Connection_Interface_Resources.xml212
-rw-r--r--spec/spec/Connection_Interface_Service_Point.xml136
-rw-r--r--spec/spec/Connection_Interface_Simple_Presence.xml695
-rw-r--r--spec/spec/Connection_Manager.xml631
-rw-r--r--spec/spec/Connection_Manager_Interface_Account_Storage.xml120
-rw-r--r--spec/spec/Debug.xml165
-rw-r--r--spec/spec/Media_Session_Handler.xml81
-rw-r--r--spec/spec/Media_Stream_Handler.xml906
-rw-r--r--spec/spec/Properties_Interface.xml196
-rw-r--r--spec/spec/Protocol.xml490
-rw-r--r--spec/spec/Protocol_Interface_Addressing.xml335
-rw-r--r--spec/spec/Protocol_Interface_Avatars.xml157
-rw-r--r--spec/spec/Protocol_Interface_Presence.xml113
-rw-r--r--spec/spec/all.xml321
-rw-r--r--spec/spec/errors.xml657
-rw-r--r--spec/spec/generic-types.xml215
-rw-r--r--spec/spec/template.xml33
-rw-r--r--spec/test/input/_Test.xml126
-rw-r--r--spec/test/input/all.xml25
-rw-r--r--spec/test/input/errors.xml32
-rwxr-xr-xspec/test/test-specparser.py95
-rw-r--r--spec/tools/README24
-rwxr-xr-xspec/tools/doc-generator.py121
-rw-r--r--spec/tools/git-which-branch.sh25
-rw-r--r--spec/tools/specparser.py1420
-rw-r--r--spec/tools/xincludator.py39
146 files changed, 47475 insertions, 0 deletions
diff --git a/spec/.gitignore b/spec/.gitignore
new file mode 100644
index 000000000..fbf61bf45
--- /dev/null
+++ b/spec/.gitignore
@@ -0,0 +1,12 @@
+.*.sw?
+*.pyc
+/FIXME.out
+/doc/*.html
+/doc/spec
+/doc/telepathy-spec.devhelp2
+/telepathy-spec-*.tar*
+/test/output
+/tmp
+.\#*
+\#*\#
+*~
diff --git a/spec/AUTHORS b/spec/AUTHORS
new file mode 100644
index 000000000..51a617bc7
--- /dev/null
+++ b/spec/AUTHORS
@@ -0,0 +1,17 @@
+Daniel d'Andrada T. de Carvalho <daniel.carvalho@indt.org.br>
+Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+Julien Gilli <jgilli@acm.org>
+Dafydd Harries <dafydd.harries@collabora.co.uk>
+Tobias Hunger <tobias.hunger@basyskom.de>
+Andre Magalhaes <andrunko@gmail.com>
+Robert McQueen <robert.mcqueen@collabora.co.uk>
+Simon McVittie <simon.mcvittie@collabora.co.uk>
+Mads Chr. Olesen <shiyee@gmail.com>
+Senko Rasic <senko.rasic@collabora.co.uk>
+Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
+Olli Salli <olli.salli@collabora.co.uk>
+Sjoerd Simons <sjoerd@luon.net>
+Raphael Slinckx <raphael@slinckx.net>
+Rob Taylor <rob.taylor@codethink.co.uk>
+Naveen Verma <naveen.verma@nokia.com>
+Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
diff --git a/spec/COPYING b/spec/COPYING
new file mode 100644
index 000000000..2d2d780e6
--- /dev/null
+++ b/spec/COPYING
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/spec/COPYRIGHT b/spec/COPYRIGHT
new file mode 100644
index 000000000..b14a0ac0d
--- /dev/null
+++ b/spec/COPYRIGHT
@@ -0,0 +1,13 @@
+The specification itself is copyright various combinations of Collabora Ltd,
+Nokia Corporation, and INdT, and licensed under the LGPL v2.1 or later.
+
+The majority of the templates and HTML generation tools are copyright Collabora
+Ltd., and are licensed under the LGPL v2.1 or later.
+
+jquery.js — and jquery.min.js, which is a minified version of the former — is
+taken from <http://jquery.com/>, and is copyright John Resig and The Dojo
+Foundation.
+
+ui-icons_222222_256x240.png is taken from jquery-ui <http://jqueryui.com/>, and
+copyright is held by many individuals. Both files are used under the MIT
+license.
diff --git a/spec/Makefile b/spec/Makefile
new file mode 100644
index 000000000..1063e4b6c
--- /dev/null
+++ b/spec/Makefile
@@ -0,0 +1,121 @@
+all:
+
+GIT = git
+GZIP = gzip
+TAR = tar
+PYTHON = python
+
+DOC_RSYNC_FLAGS=-rvzPp --chmod=Dg+s,ug+rwX,o=rX --delete
+
+XMLS = $(wildcard spec/*.xml)
+TEMPLATES = $(wildcard doc/templates/*)
+
+VERSION := $(shell sed -ne s'!<tp:version>\(.*\)</tp:version>!\1!p' spec/all.xml)
+DISTNAME := telepathy-spec-$(VERSION)
+
+GENERATED_FILES = \
+ doc/spec/index.html \
+ FIXME.out \
+ $(NULL)
+
+doc/spec/index.html: $(XMLS) tools/doc-generator.py tools/specparser.py $(TEMPLATES)
+ rm -rf doc/spec
+ install -d doc/spec
+ $(PYTHON) tools/doc-generator.py spec/all.xml doc/spec/ telepathy-spec \
+ org.freedesktop.Telepathy
+
+all: $(GENERATED_FILES)
+ @echo "Your spec HTML starts at:"
+ @echo
+ @echo file://$(CURDIR)/doc/spec/index.html
+ @echo
+
+CHECK_FOR_UNRELEASED = NEWS $(filter-out spec/template.xml,$(XMLS))
+
+check: all FIXME.out
+ $(PYTHON) test/test-specparser.py
+ @case "$(VERSION)" in \
+ *.*.*.*) ;; \
+ *) \
+ echo "Grepping spec for UNRELEASED..."; \
+ if grep -r UNRELEASED $(CHECK_FOR_UNRELEASED); \
+ then \
+ echo "^^^ This is meant to be a release, but some files say UNRELEASED" >&2; \
+ exit 2; \
+ fi \
+ ;; \
+ esac
+
+FIXME.out: $(XMLS)
+ @echo ' GEN ' $@
+ @egrep -A 5 '[F]IXME|[T]ODO|[X]XX' $(XMLS) \
+ > FIXME.out || true
+
+clean:
+ rm -f $(GENERATED_FILES)
+ rm -rf test/output
+ rm -rf tmp
+ rm -rf doc/spec
+
+maintainer-upload-snapshot: doc/spec/index.html
+ @install -d tmp
+ rsync $(DOC_RSYNC_FLAGS) doc/spec/ telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/spec-snapshot/
+ @echo The snapshot lives at:
+ @echo ' ' http://telepathy.freedesktop.org/spec-snapshot/
+
+maintainer-upload-release: doc/spec/index.html check
+ @install -d tmp
+ @if ! echo $(VERSION) | egrep '[0-9]+\.[0-9]+\.[0-9]+'; then \
+ echo $(VERSION) 'does not look like a spec release'; \
+ exit 1; \
+ fi
+ test -f telepathy-spec-$(VERSION).tar.gz
+ test -f telepathy-spec-$(VERSION).tar.gz.asc
+ gpg --verify telepathy-spec-$(VERSION).tar.gz.asc
+ rsync -vzP telepathy-spec-$(VERSION).tar.gz telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/telepathy-spec/
+ rsync -vzP telepathy-spec-$(VERSION).tar.gz.asc telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/telepathy-spec/
+ rsync $(DOC_RSYNC_FLAGS) doc/spec/ telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/spec/
+ rsync $(DOC_RSYNC_FLAGS) doc/spec/ telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/spec-snapshot/
+
+dist: check
+ @install -d tmp
+ rm -f tmp/ChangeLog "$(DISTNAME)".tar "$(DISTNAME)".tar.gz
+ $(GIT) archive --format=tar --prefix="$(DISTNAME)"/ "HEAD^{tree}" \
+ > "$(DISTNAME)".tar
+ rm -rf tmp/"$(DISTNAME)"
+ mkdir tmp/"$(DISTNAME)"
+ $(GIT) log telepathy-spec-0.16.0.. > tmp/"$(DISTNAME)"/ChangeLog
+ $(TAR) -rf "$(DISTNAME)".tar -C tmp --owner 0 --group 0 --mode 0664 \
+ "$(DISTNAME)"/ChangeLog
+ $(GZIP) -9 "$(DISTNAME)".tar
+ rm -rf tmp/"$(DISTNAME)"
+
+BRANCH = $(shell sh tools/git-which-branch.sh misc | tr -d '\n' | tr -C "[:alnum:]" _)
+UPLOAD_BRANCH_HOST = people.freedesktop.org
+UPLOAD_BRANCH_TO = $(UPLOAD_BRANCH_HOST):public_html/telepathy-spec
+
+# Usage: make upload-branch BRANCH=discussion
+upload-branch: all
+ rsync -rzvP --delete doc/spec \
+ $(UPLOAD_BRANCH_TO)-$(BRANCH)/
+ @echo Your spec branch might be at:
+ @echo ' ' http://$(UPLOAD_BRANCH_HOST)/~$$USER/telepathy-spec-$(BRANCH)/spec/
+
+# automake requires these rules for anything that's in DIST_SUBDIRS
+distclean: clean
+maintainer-clean: clean
+distdir:
+ @echo distdir not implemented yet; exit 1
+
+.PHONY: \
+ all \
+ check \
+ clean \
+ dist \
+ distclean \
+ distdir \
+ maintainer-clean \
+ maintainer-upload-release \
+ maintainer-upload-snapshot \
+ upload-branch \
+ $(NULL)
diff --git a/spec/NEWS b/spec/NEWS
new file mode 100644
index 000000000..5d63cec89
--- /dev/null
+++ b/spec/NEWS
@@ -0,0 +1,301 @@
+This file contains the same edited highlights as the announcement emails.
+For full details, see the ChangeLog in tarballs, or "git log" in Git
+checkouts.
+
+telepathy-spec 0.25.1 (2011-11-23)
+==================================
+
+The “farewell whiskey chess” release.
+
+API additions and clarifications:
+
+• Call1.Content.Interface.AudioControl is a wonderful new interface to
+ allow the connection manager to recommend volume changes during calls.
+
+• The various values of Socket_Access_Control have enjoyed some
+ clarification of their meanings on different tube types.
+
+• Protocol.Interface.Addressing has been undrafted, with NormalizeURI
+ renamed to NormalizeContactURI.
+
+• Connection.Interface.Addressing is still a draft, but its methods have
+ been changed to split the return values into two mappings.
+
+telepathy-spec 0.25.0 (2011-11-10)
+==================================
+
+API additions and clarifications:
+
+• Channel.Interface.FileTransfer.Metadata has been added.
+
+• Channel.Interface.Picture has been added.
+
+• "windows-live" has been added as a known account service name.
+
+• Channel.Interface.Subject: clarify default values for properties in
+ the unknown case.
+
+• RoomConfig: add a PasswordHint property which does what you think it
+ does.
+
+• Room: add Creator, CreatorHandle and CreationTimestamp properties.
+
+• Channel.Type.ContactList has been deprecated.
+
+telepathy-spec 0.24.0 (2011-10-10)
+==================================
+
+The “underestimating the future” release. This is the start of a new
+stable branch of the Telepathy specification.
+
+Changes since 0.23.4:
+
+• Channel.Interface.Room has been undrafted, with a few changes:
+ · The RoomID property has become RoomName;
+ · The Subject property has been split off onto a separate interface,
+ Channel.Interface.Subject (which is also undrafted).
+
+• Channel.Interface.RoomConfig has been defined to replace the remaining
+ klunky Telepathy.Properties on Channel.Type.Text.
+
+• As a result, the Telepathy.Properties interface has been deprecated,
+ since all interfaces which historically used it now have better
+ replacements.
+
+Other notable changes since the 0.22 stable branch:
+
+• Most interfaces now provide both handles and identifiers for contacts.
+ This makes life easier for telepathy-glib and telepathy-qt4 (and, by
+ extension, application authors).
+
+• A new revision of the Call family of interfaces has landed. It is
+ still marked experimental.
+
+• ChannelDispatcher has a pair of new methods, DelegateChannels() and
+ PresentChannel(), to aid user interfaces where channels can be shown
+ in a number of places (like Gnome 3).
+
+• FileTransfer now has a URI property to indicate the on-disk location
+ of the file being sent or received.
+
+telepathy-spec 0.23.4 (2011-09-29)
+==================================
+
+API additions and clarifications:
+
+• Always give contact identifiers together with handles in
+ Channel.Interface.Group. This helps clients to create contact objects without
+ extra async operations. Additions are:
+ • Channel.Interface.Group.MemberIdentifiers;
+ • Channel.Interface.Group.SelfContactChanged; and
+ • Channel.Interface.Group.HandleOwnersChangedDetailed.
+
+• AccountManager: remove note about service activation. Mission Control is
+ service-activatable and is probably the only implementation we'll ever have.
+
+• Clarify possible errors returned by AM.CreateAccount.
+
+Spec HTML improvements:
+
+• Now <tp:value-ref> is used to reference a value in a enumeration.
+
+Call DRAFT2 landed
+
+• Call interfaces are now versioned. For example
+ org.freedesktop.Telepathy.Channel.Type.Call.DRAFT is now renamed to
+ org.freedesktop.Telepathy.Channel.Type.Call1.
+
+telepathy-spec 0.23.3 (2011-07-14)
+==================================
+
+API additions and clarifications:
+
+• The semantics of the 'supersedes' header in Messages have been clarified, and
+ 'original-message-sent' and 'original-message-received' headers have been
+ defined to make the timestamps used for message edits unambiguous.
+ (fd.o#37413, David)
+
+• A tonne of properties on FileTransfer have been marked as requestable and/or
+ immutable. Also, as a clarification, the spec now explicitly says that
+ approvers may set the URI property, and that handlers MUST obey this.
+ (Xavier)
+
+• A new ChannelRequest hint, DelegateToPreferredHandler, has been added.
+ (fd.o#38240, Danni)
+
+Spec HTML improvements:
+
+• Jumping to anchors within the spec HTML will no longer move the text you're
+ looking for underneath the title bar with Webkit. Yay! (Danni (my heroine))
+
+• The generated HTML spec now has a beautiful favicon. (fd.o#38594, Guillaume)
+
+And for spec developers:
+
+• `make upload-branch` now takes an optional UPLOAD_BRANCH_TO Makefile
+ variable, which allows you to override the default server, namely
+ “people.freedesktop.org” (João Paulo Rechi Vita)
+
+telepathy-spec 0.23.2 (2011-05-16)
+==================================
+
+Changes to existing API
+-----------------------
+
+• ChannelDispatcher.DelegateChannels() now calls HandleChannels once per
+ Channel. It also returns the list of Channels which have been delegated
+ and those which have not. (fdo #37109, Guillaume)
+
+telepathy-spec 0.23.1 (2011-05-09)
+==================================
+
+This first release in the 0.23 development branch contains all the fixes and
+additions from 0.22.3.
+
+Enhancements:
+
+• Channel.Interface.SMS.GetSMSLength() to allow SMS message chunking to be
+ shown to the user. (Danni)
+
+• ChannelDispatcher.DelegateChannels() to move channels between handlers.
+ (fdo #25293, Guillaume)
+
+• ChannelDispatcher.PresentChannel(): convenient API to re-ensure an existing
+ channel. (fdo #25293, Guillaume)
+
+
+telepathy-spec 0.22.3 (2011-05-09)
+==================================
+
+Fixes:
+
+• Correct DBus_Property-parameter boilerplate. (fdo #37005, Will)
+
+telepathy-spec 0.22.2 (2011-04-20)
+==================================
+
+The “every cell stayed the same” release.
+
+Once again, this release in the stable series includes some minor API
+additions.
+
+Enhancements:
+
+• Channel.Interface.SMS now includes some sample contact capabilities.
+ (Danni)
+
+• Connection.Interface.Balance now has a ManageCreditURI property.
+ (fd.o#36254, Danni)
+
+• Connection.Interface.SimplePresence now has a
+ MaximumStatusMessageLength property. (fd.o#33054, André)
+
+• SimplePresence defines two new well-known status identifiers: "pstn"
+ and "chat". (fd.o#36159, Danni vs. Will)
+
+Fixes:
+
+• Protocol.Interface.Avatars properties are documented to be immutable.
+ (Guillaume)
+
+• The tables in SimplePresence and Call's HTML documentation look nicer.
+
+telepathy-spec 0.22.1 (2011-03-30)
+==================================
+
+The “we can change the things we know” release.
+
+Unconventionally, this release in the 0.22 stable series of the
+specification contains minor API additions. This is not intended to
+become a trend; once major changes land in the specification and a
+release is made in the 0.23.x unstable series, no new API will be added
+to the stable branch.
+
+• A new error code, InsufficientBalance, has been added, along with a
+ balance-required key for the CallStateDetails dictionary. (Danni)
+
+• Media.StreamHandler has grown two new method/signal pairs, namely
+ SetRemoteFeedbackMessages/SupportedFeedbackMessages and
+ SetRemoteHeaderExtensions/SupportedHeaderExtensions, plus some related
+ types, for enabling exciting RTP header extensions and RTCP feedback
+ messages.
+
+telepathy-spec 0.22.0 (2011-03-21)
+==================================
+
+The “literate small talk” release.
+
+This is a new stable version of telepathy-spec, intended to serve as a
+reference point for future work. There were no API changes since
+development release 0.21.13; significant additions and changes to
+non-DRAFT interfaces from the year-and-a-half of development since
+0.20.0 are summarized below.
+
+The versions of libraries, connection managers and Mission Control
+recommended for use with GNOME 3.0 (such as the upcoming telepathy-glib
+0.14) can be expected to support most of the API from this spec release.
+
+Changes to existing API
+-----------------------
+
+• Handles are no longer expected to be reference-counted - instead, they
+ persist as long as the Connection does. A new property,
+ HasImmortalHandles, indicates whether this is the case. Versions of
+ telepathy-glib since 0.13.8 implement these semantics, and set that
+ property, automatically for most connection managers.
+
+• message-token has been redefined from "globally unique"
+ to "whatever's in the underlying protocol", replacing the unimplemented
+ protocol-token. This makes it feasible to implement message-token again.
+ Note that connection managers implementing message-token should not be
+ backported to Maemo 5, since its event logger assumes that message-token
+ is guaranteed to be unique, which is usually unimplementable.
+
+• The Messages interface is now mandatory for Text channels.
+
+Enhancements to core API
+------------------------
+
+• The Connection has a pair of new methods, AddClientInterest and
+ RemoveClientInterest, to allow clients to subscribe to potentially
+ bandwidth-costly interfaces (such as MailNotification) in a generic
+ way.
+
+• ChannelDispatcher and ChannelRequest now support "request hints"
+ (metadata passed through from the requester to the handler), and the
+ SucceededWithChannel signal.
+
+New optional interfaces
+-----------------------
+
+• The ContactList and ContactGroups interfaces for
+ connections are now considered stable, and a new ContactBlocking
+ interface has been added. Between them, these interfaces replace
+ ContactList channels.
+
+• The Connection.Interface.ClientTypes,
+ Connection.Interface.MailNotification,
+ Connection.Interface.Powersaving, and Protocol.Interface.Presence
+ interfaces are now considered stable.
+
+• Chan.T.ServerAuthentication and Chan.I.SASLAuthentication provide
+ interactive querying for credentials, allowing connection without
+ saving a password if there is a handler for these channels
+
+• Chan.I.Securable indicates whether a channel is secure
+
+• Account.Interface.Addressing stores user preferences for use of
+ accounts for non-primary protocols, such as using SIP for telephony.
+
+Enhancements to optional interfaces
+-----------------------------------
+
+• Add a FileTransfer.URI property which can be used to tell other
+ Telepathy clients about the location of the transferred
+ file.
+
+Changes since 0.21.13
+---------------------
+
+• A server-message key for the Details dictionary in the ConnectionError
+ signal has been defined. (wjt)
diff --git a/spec/README b/spec/README
new file mode 100644
index 000000000..e99e96756
--- /dev/null
+++ b/spec/README
@@ -0,0 +1,96 @@
+=======================
+Telepathy specification
+=======================
+
+telepathy-spec is the canonical description of the Telepathy D-Bus API,
+on which all other Telepathy projects are based.
+
+Telepathy is a D-Bus framework for unifying real time communication,
+including instant messaging, voice calls and video calls. It abstracts
+differences between protocols to provide a unified interface for
+applications.
+
+Requirements
+============
+
+Building HTML documentation for telepathy-spec requires:
+ GNU make <http://www.gnu.org/software/make/>
+ libxslt, xsltproc <http://xmlsoft.org/XSLT/>
+ Python <http://www.python.org/>
+ Docutils (rst2html tool) <http://docutils.sourceforge.net/>
+
+Bugs, feature requests and to-do list
+=====================================
+
+Report all errata, feature requests and "to-do" items here:
+ <https://bugs.freedesktop.org/enter_bug.cgi?product=Telepathy&component=telepathy-spec>
+
+API stability policy
+====================
+
+We use an "odd/even" versioning scheme where the minor version (the y in
+x.y.z) determines stability - stable branches have y even, development
+branches have y odd.
+
+The following interfaces can change at any time, so please do not include them
+in libraries:
+
+* interfaces whose names end with .DRAFT or .FUTURE
+* interfaces with the tp:causes-havoc attribute
+
+Otherwise, we will not make the following changes in a stable branch, and we
+avoid them where possible even in development branches:
+
+* Removing or renaming methods, signals or properties
+* Changing the D-Bus type signature of a method or signal's arguments
+* Changing the D-Bus type signature or access (can be read/can be written)
+ of a property
+* Removing or renaming types (tp:struct etc.)
+* Changing the D-Bus type signature of a type (tp:struct etc.)
+
+We do *not* consider the following changes to be an API break, and reserve the
+right to make them at any time. Telepathy libraries/bindings should be done in
+a way that will not break if we do these:
+
+* Adding new methods or properties
+* Adding new signals, if that does not make old connection managers (that will
+ never emit those signals) fail to comply with the spec
+* Changing the name of a method or signal argument, or giving it a name if
+ it did not previously have one
+* Adding new types (tp:enum, tp:struct etc.)
+* Adding new members to the end of a tp:enum or tp:flags
+* Changing the tp:type of a property or argument, or adding a tp:type if it
+ did not already have one (as long as the D-Bus signature remains the same)
+* Documenting methods to possibly raise new exceptions (any method can raise
+ any exception, and client code should always cope)
+
+If any changes not mentioned here would break your library's API and you want
+us to avoid them, please ask for clarification on the mailing list.
+
+Contact info
+============
+
+This specification is maintained by the Telepathy project:
+ <http://telepathy.freedesktop.org/>
+ <mailto:telepathy@lists.freedesktop.org>
+ <irc://irc.freenode.net/telepathy>
+
+Telepathy development is supported by Collabora Ltd.
+ <http://www.collabora.co.uk/>.
+
+Hacking
+=======
+
+The current development version of telepathy-spec is available from the
+'master' branch in the git repository:
+ <git://git.collabora.co.uk/git/telepathy-spec.git>
+ <git+ssh://git.collabora.co.uk/git/telepathy-spec.git> (for committers)
+ <http://git.collabora.co.uk/?p=telepathy-spec.git> (gitweb)
+
+Stable branches are available from branches with names like
+'telepathy-spec-0.16' in the same repository.
+
+Proposed patches awaiting review can usually be found in the freedesktop.org
+bugzilla with the ‘patch’ keyword, which can be listed using the following
+formidible URL:
+ <https://bugs.freedesktop.org/buglist.cgi?keywords=patch&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=tp-spec&product=Telepathy>
diff --git a/spec/doc/templates/devhelp.devhelp2 b/spec/doc/templates/devhelp.devhelp2
new file mode 100644
index 000000000..cd7fe7a89
--- /dev/null
+++ b/spec/doc/templates/devhelp.devhelp2
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<book xmlns="http://www.devhelp.net/book" title="$spec.title" name="$name" link="index.html">
+ <chapters>
+#for $interface in $spec.interfaces
+ <sub name="$interface.name" link="$interface.get_url()"/>
+#end for
+#if len($spec.generic_types) > 0
+ <sub name="Generic Types" link="generic-types.html"/>
+#end if
+#if len($spec.errors) > 0
+ <sub name="Errors" link="errors.html"/>
+#end if
+ <sub name="Full Index" link="fullindex.html"/>
+ </chapters>
+ <functions>
+#for $obj in $spec.everything.values() + $spec.types.values() + $spec.errors.values()
+#for $entry in $obj.get_index_entries()
+ <keyword type="$obj.devhelp_name" name="$entry" link="$obj.get_url()" #slurp
+#if $obj.is_deprecated: deprecated="true" #slurp
+/>
+#end for
+#end for
+ </functions>
+</book>
diff --git a/spec/doc/templates/errors.html b/spec/doc/templates/errors.html
new file mode 100644
index 000000000..94a793e5c
--- /dev/null
+++ b/spec/doc/templates/errors.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>Errors</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ </head>
+ <body>
+ <div class="header">
+ <h1>Errors</h1>
+ <a href="index.html">Interface Index</a>
+ (<a href="interfaces.html">Compact</a>)
+ | <a href="#summary">Summary</a>
+ | <a href="#errors">Errors</a>
+ </div>
+ <div class="main">
+ <div class="summary">
+ <a name="summary"></a>
+ <h3>Errors</h3>
+ <table class="summary">
+ #for $error in $spec.sorted_errors
+ #if $error.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$error.get_url()">$error.short_name</a></td>
+ <td>
+ #if $error.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ </div>
+
+ #if $spec.errors_section
+ $spec.errors_section.get_docstring()
+ #end if
+
+ <div class="outset errors error">
+ <a name="errors"></a>
+ <h1>Errors</h1>
+ #for $error in $spec.sorted_errors
+ <div class="inset error">
+ <a name="$error.get_anchor()"></a>
+ <span class="permalink">(<a href="$error.get_url()">Permalink</a>)</span>
+ <h2>
+ $error.short_name
+ </h2>
+
+ <div class="indent">
+ <code>$error.name</code>
+ </div>
+
+ $error.get_added()
+ $error.get_deprecated()
+ $error.get_docstring()
+ </div>
+ #end for
+ </div>
+ </div>
+
+ </body>
+</html>
diff --git a/spec/doc/templates/favicon.png b/spec/doc/templates/favicon.png
new file mode 100644
index 000000000..cd58a7134
--- /dev/null
+++ b/spec/doc/templates/favicon.png
Binary files differ
diff --git a/spec/doc/templates/fullindex.html b/spec/doc/templates/fullindex.html
new file mode 100644
index 000000000..df66e525d
--- /dev/null
+++ b/spec/doc/templates/fullindex.html
@@ -0,0 +1,61 @@
+#from itertools import groupby
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>Full Index</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ </head>
+
+#set $star = []
+#for $item in $spec.everything.values() + $spec.errors.values() + $spec.types.values()
+ #echo $star.append(($item.short_name, $item))
+ #slurp
+#end for
+#echo $star.sort(key = lambda t: t[0].title())
+#slurp
+## one use iterators...
+#set $groups = [ (l, list(g)) for l, g in (groupby($star, key = lambda t: t[0][0].upper())) ]
+#set $letters = set(map(lambda t: t[0], groups))
+
+ <body>
+ <div class="header">
+ <h1>Full Index</h1>
+ <a href="index.html">Interface Index</a>
+ (<a href="interfaces.html">Compact</a>)
+ #for $a in map(chr, xrange(ord('A'), ord('Z')+1))
+ #if $a in $letters
+ | <a href="#$a">$a</a>
+ #else
+ | $a
+ #end if
+ #end for
+ </div>
+
+ <div class="main">
+ <table class="summary">
+ #for l, g in $groups
+ <tr><th colspan="3"><a name="$l"></a>$l</th></tr>
+ #for $n in $g
+ #if $n[1].is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td>
+ <a href="$n[1].get_url()" title="$n[1].get_title()">$n[0]</a>
+ #if $n[1].is_deprecated: (deprecated)
+ </td>
+ <td>$n[1].get_type_name()</td>
+ <td>
+ #if $n[1].parent.__class__.__name__ == 'Interface': $n[1].parent.name
+ </td>
+ </tr>
+ #end for
+ #end for
+ <table>
+ </div>
+
+ </body>
+</html>
diff --git a/spec/doc/templates/generic-types.html b/spec/doc/templates/generic-types.html
new file mode 100644
index 000000000..21e982699
--- /dev/null
+++ b/spec/doc/templates/generic-types.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>Generic Types</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ </head>
+ <body>
+ <div class="header">
+ <h1>Generic Types</h1>
+ <a href="index.html">Interface Index</a>
+ (<a href="interfaces.html">Compact</a>)
+ | <a href="#summary">Summary</a>
+ | <a href="#types">Types</a>
+ </div>
+ <div class="main">
+ <div class="summary">
+ <a name="summary"></a>
+ <h3>Generic Types</h3>
+ <table class="summary">
+ #for $type in $spec.generic_types
+ #if $type.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$type.get_url()">$type.short_name</a></td>
+ <td>$type.get_type_name()</td>
+ <td>$type.dbus_type</td>
+ <td>
+ #if $type.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ </div>
+
+ <div class="outset types type">
+ <a name="types"></a>
+ <h1>Generic Types</h1>
+ #for $type in $spec.generic_types
+ <div class="inset type">
+ <a name="$type.get_anchor()"></a>
+ <span class="permalink">$type.get_type_name() (<a href="$type.get_url()">Permalink</a>)</span>
+ <h2>
+ $type.short_name &mdash; $type.dbus_type
+ </h2>
+
+ $type.get_added()
+ $type.get_deprecated()
+ $type.get_docstring()
+ $type.get_breakdown()
+ </div>
+ #end for
+ </div>
+ </div>
+
+ </body>
+</html>
diff --git a/spec/doc/templates/index.html b/spec/doc/templates/index.html
new file mode 100644
index 000000000..2df515d53
--- /dev/null
+++ b/spec/doc/templates/index.html
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>$spec.title &mdash; v$spec.version</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ </head>
+ <body>
+ <div class="header">
+ <h1>$spec.title</h1>
+ <a href="#interfaces">Interfaces</a>
+ (<a href="interfaces.html">Compact</a>)
+#if len($spec.generic_types) > 0
+ | <a href="generic-types.html">Generic Types</a>
+#end if
+#if len($spec.errors) > 0
+ | <a href="errors.html">Errors</a>
+#end if
+ | <a href="fullindex.html">Full Index</a>
+ </div>
+
+ <div class="main">
+ <h3 class="version">Version $spec.version</h3>
+ <div class="legal">
+ <ul class="copyrights">
+ #for c in $spec.copyrights
+ <li>$c</li>
+ #end for
+ </ul>
+
+ #for $para in $spec.license
+ <p>$para</p>
+ #end for
+ </div>
+
+ <a name="interfaces"></a>
+ <h3>Interfaces</h3>
+ <ul>
+ #def output($items)
+ #for $item in $items
+ #if $item.__class__.__name__ == 'Section'
+ #set $anchor = $item.short_name.replace(' ', '-')
+ <li class="chapter">
+ <a name="$anchor"></a>
+ $item.short_name
+ <span class="permalink">(<a href="#$anchor">Permalink</a>)</span>
+ </li>
+ $item.get_docstring()
+ <ul>
+ $output($item.items)
+ </ul>
+ #else
+ #if $item.causes_havoc
+ <li class="causes-havoc">
+ #elif $item.is_deprecated
+ <li class="deprecated">
+ #else
+ <li>
+ #end if
+ <a href="$item.get_url()">$item.name</a>
+ #if $item.causes_havoc
+ (unstable)
+ #elif $item.is_deprecated
+ (deprecated)
+ #end if
+ </li>
+ #end if
+ #end for
+ #end def
+ $output($spec.items)
+ </ul>
+
+#if len($spec.generic_types) > 0 or len($spec.errors) > 0
+ <a name="other"></a>
+ <h3>Other</h3>
+ <ul>
+ #if len($spec.generic_types) > 0
+ <li><a href="generic-types.html">Generic Types</a></li>
+ #end if
+ #if len($spec.errors) > 0
+ <li><a href="errors.html">Errors</a></li>
+ #end if
+ </ul>
+#end if
+
+ </div>
+ </body>
+</html>
diff --git a/spec/doc/templates/interface.html b/spec/doc/templates/interface.html
new file mode 100644
index 000000000..63a24bdf7
--- /dev/null
+++ b/spec/doc/templates/interface.html
@@ -0,0 +1,566 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>$interface.really_short_name &mdash; $spec.title</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ <script src="jquery.min.js"></script>
+ <script src="magic.js"></script>
+ </head>
+ <body>
+ <div class="header">
+ <h1>Interface <abbr title='$interface.name'>$interface.short_name</abbr></h1>
+ <a href="index.html">Interface Index</a>
+ (<a href="interfaces.html">Compact</a>)
+ | <a href="#summary">Summary</a>
+ #if $interface.client_interests: | <a href="#client-interests">Client Interests</a>
+ #if $interface.docstring: | <a href="#description">Description</a>
+ #if $interface.methods: | <a href="#methods">Methods</a>
+ #if $interface.signals: | <a href="#signals">Signals</a>
+ #if $interface.properties: | <a href="#properties">Properties</a>
+ #if $interface.tpproperties: | <a href="#tpproperties">Telepathy Properties</a>
+ #if $interface.contact_attributes: | <a href="#contact-attributes">Contact Attributes</a>
+ #if $interface.handler_capability_tokens: | <a href="#handler-capability-tokens">Handler Capability Tokens</a>
+ #if $interface.types: | <a href="#types">Types</a>
+ </div>
+ <div class="main">
+
+ #if $interface.methods or $interface.signals or $interface.properties or $interface.types or $interface.tpproperties
+ <div class="summary">
+ <a name="summary"></a>
+ #if $interface.client_interests
+ <h3>Client Interests</h3>
+ <table class="summary">
+ #for $interest in $interface.client_interests
+ <td><a href="$interest.get_url()">$interest.name</a></td>
+ #end for
+ </table>
+ #end if
+ #if $interface.methods
+ <h3>Methods</h3>
+ <table class="summary">
+ #for $method in $interface.methods
+ #if $method.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$method.get_url()">$method.short_name</a></td>
+ <td>($method.get_in_args())</td>
+ <td>&#8594;</td>
+ <td>$method.get_out_args()</td>
+ <td>
+ #if $method.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.signals
+ <h3>Signals</h3>
+ <table class="summary">
+ #for $signal in $interface.signals
+ #if $signal.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$signal.get_url()">$signal.short_name</a></td>
+ <td>($signal.get_args())</td>
+ <td>
+ #if $signal.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.properties
+ <h3>Properties</h3>
+ <table class="summary">
+ #for $property in $interface.properties
+ #if $property.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$property.get_url()">$property.short_name</a></td>
+ <td>
+ $property.dbus_type
+ #if $property.type: (<a href="$property.get_type_url()" title="$property.get_type_title()">$property.get_type().short_name</a>)
+ </td>
+ <td>$property.get_access()</td>
+ <td>$property.get_flag_summary()</td>
+ <td>
+ #if $property.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.tpproperties
+ <h3>Telepathy Properties</h3>
+ <table class="summary">
+ #for $property in $interface.tpproperties
+ <tr class="deprecated">
+ <td><a href="$property.get_url()">$property.short_name</a></td>
+ <td>
+ $property.dbus_type
+ #if $property.type: (<a href="$property.get_type_url()" title="$property.get_type_title()">$property.get_type().short_name</a>)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.contact_attributes
+ <h3>Contact Attributes</h3>
+ <table class="summary">
+ #for $token in $interface.contact_attributes
+ <tr class="contact-attribute">
+ <td><a href="$token.get_url()">$token.name</a></td>
+ <td>
+ $token.dbus_type
+ #if $token.type: (<a href="$token.get_type_url()" title="$token.get_type_title()">$token.get_type().short_name</a>)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.handler_capability_tokens
+ <h3>Handler Capability Tokens</h3>
+ <table class="summary">
+ #for $token in $interface.handler_capability_tokens
+ <tr class="handler-capability-token">
+ <td><a href="$token.get_url()">$token.name</a>
+ #if $token.is_family
+ (etc.)
+ #end if
+ </td>
+ <td>
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+
+ #if $interface.types
+ <h3>Types</h3>
+ <table class="summary">
+ #for $type in $interface.types
+ #if type.is_deprecated
+ <tr class="deprecated">
+ #else
+ <tr>
+ #end if
+ <td><a href="$type.get_url()">$type.short_name</a></td>
+ <td>$type.get_type_name()</td>
+ <td>$type.dbus_type</td>
+ <td>
+ #if $type.is_deprecated: (deprecated)
+ </td>
+ </tr>
+ #end for
+ </table>
+ #end if
+ </div>
+ #end if
+
+ #if $interface.causes_havoc
+ <div class="annotation havoc"><span class="warning">WARNING:</span>
+ This interface is $interface.causes_havoc and is likely to cause havoc
+ to your API/ABI if bindings are generated. Do not include this interface
+ in libraries that care about compatibility.
+ </div>
+ #end if
+ $interface.get_added()
+ $interface.get_changed()
+ $interface.get_deprecated()
+
+ #if $interface.requires or $interface.xor_requires
+ <div class="requires">
+ Objects implementing this interface must also implement:
+ <ul>
+ #for $req in $interface.get_xor_requires()
+ <li>
+ #echo " <strong>or</strong> ".join(['<a href="' + x.get_url() + '''"
+ title="''' + x.get_title() + '">' + x.name + '</a>' for x in req])
+ </li>
+ #end for
+ #for $req in $interface.get_requires()
+ <li><a href="$req.get_url()" title="$req.get_title()">$req.name</a></li>
+ #end for
+ </ul>
+ </div>
+ #end if
+
+ #if $interface.docstring
+ <a name="description"></a>
+ <h3>Description</h3>
+ $interface.get_docstring()
+ #end if
+
+ #if $interface.client_interests
+ <div class="outset client-interests client-interest">
+ <a name="client-interests"></a>
+ <h1>Client Interests</h1>
+ <div>
+ Set using the
+ <a href="Connection.html#org.freedesktop.Telepathy.Connection.AddClientInterest">AddClientInterest</a> and
+ <a href="Connection.html#org.freedesktop.Telepathy.Connection.RemoveClientInterest">RemoveClientInterest</a> methods.
+ </div>
+ #for $interest in $interface.client_interests
+ <div class="inset client-interest">
+ <a name="$interest.get_anchor()"></a>
+ <span class="permalink">(<a href="$interest.get_url()">Permalink</a>)</span>
+ <h2>$interest.name</h2>
+
+ $interest.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.methods
+ <div class="outset methods method">
+ <a name="methods"></a>
+ <h1>Methods</h1>
+ #for $method in $interface.methods
+ <div class="inset method">
+ <a name="$method.get_anchor()"></a>
+ <span class="permalink">(<a href="$method.get_url()">Permalink</a>)</span>
+ <h2>$method.short_name ($method.get_in_args()) &#8594; $method.get_out_args()</h2>
+
+ $method.get_added()
+ $method.get_changed()
+ $method.get_deprecated()
+
+ #if $method.no_reply
+ <div class="annotation no-reply">The caller should not expect a reply when calling this method.</div>
+ #end if
+
+ #if $method.in_args
+ <div class="indent">
+ <h3>Parameters</h3>
+ <ul>
+ #for $arg in $method.in_args
+ <li>
+ $arg.short_name &mdash; $arg.dbus_type
+ #if $arg.get_type(): (<a href="$arg.get_type_url()" title="$arg.get_type_title()">$arg.get_type().short_name</a>)
+ </li>
+ $arg.get_added()
+ $arg.get_changed()
+ $arg.get_deprecated()
+ $arg.get_docstring()
+ #end for
+ </ul>
+ </div>
+ #end if
+
+ #if $method.out_args
+ <div class="indent">
+ <h3>Returns</h3>
+ <ul>
+ #for $arg in $method.out_args
+ <li>
+ $arg.short_name &mdash; $arg.dbus_type
+ #if $arg.get_type(): (<a href="$arg.get_type_url()" title="$arg.get_type_title()">$arg.get_type().short_name</a>)
+ </li>
+ $arg.get_added()
+ $arg.get_changed()
+ $arg.get_deprecated()
+ $arg.get_docstring()
+ #end for
+ </ul>
+ </div>
+ #end if
+
+ $method.get_docstring()
+
+ #if $method.possible_errors
+ <hr/>
+ <div class="indent">
+ <h3>Possible Errors</h3>
+ <ul>
+ #for $error in $method.possible_errors
+ <li><a href="$error.get_url()" title="$error.get_title()">$error.get_error().short_name</a></li>
+ $error.get_added()
+ $error.get_changed()
+ $error.get_deprecated()
+ $error.get_docstring()
+ #end for
+ </ul>
+ </div>
+ #end if
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.signals
+ <div class="outset signals signal">
+ <a name="signals"></a>
+ <h1>Signals</h1>
+ #for $signal in $interface.signals
+ <div class="inset signal">
+ <a name="$signal.get_anchor()"></a>
+ <span class="permalink">(<a href="$signal.get_url()">Permalink</a>)</span>
+ <h2>$signal.short_name ($signal.get_args())</h2>
+
+ $signal.get_added()
+ $signal.get_changed()
+ $signal.get_deprecated()
+
+ #if $signal.args
+ <div class="indent">
+ <h3>Parameters</h3>
+ <ul>
+ #for $arg in $signal.args
+ <li>
+ $arg.short_name &mdash; $arg.dbus_type
+ #if $arg.get_type(): (<a href="$arg.get_type_url()" title="$arg.get_type_title()">$arg.get_type().short_name</a>)
+ </li>
+ $arg.get_added()
+ $arg.get_changed()
+ $arg.get_deprecated()
+ $arg.get_docstring()
+ #end for
+ </ul>
+ </div>
+ #end if
+
+ $signal.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.properties
+ <div class="outset properties property">
+ <a name="properties"></a>
+ <h1>Properties</h1>
+ <div>
+ Accessed using the <a
+ href="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties</a>
+ interface.
+ </div>
+ #for $property in $interface.properties
+ <div class="inset property">
+ <a name="$property.get_anchor()"></a>
+ <span class="permalink">(<a href="$property.get_url()">Permalink</a>)</span>
+ <h2>
+ $property.short_name &mdash; $property.dbus_type
+ #if $property.type: (<a href="$property.get_type_url()" title="$property.get_type_title()">$property.get_type().short_name</a>)
+ </h2>
+ <div class="access">$property.get_access()</div>
+
+ #if $property.sometimes_immutable:
+ <div class="annotation immutable">Depending on the protocol, this
+ property may be <strong>immutable</strong> which means that it can never
+ #if $interface.is_channel_related:
+ change once the channel has been created. Immutable properties SHOULD
+ appear in the channel detail list
+ of <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.NewChannels">NewChannels</a>
+ signals.
+ #else
+ change.
+ #end if
+ </div>
+ #elif $property.immutable:
+ <div class="annotation immutable">This property is
+ <strong>immutable</strong> which means that it can never
+ #if $interface.is_channel_related:
+ change once the channel has been created. Immutable properties SHOULD
+ appear in the channel detail list
+ of <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.NewChannels">NewChannels</a>
+ signals.
+ #else
+ change.
+ #end if
+ </div>
+ #end if
+
+ #if $property.sometimes_requestable:
+ <div class="annotation requestable">Depending on the protocol, this
+ property may be <strong>requestable</strong>, which means that it may be
+ allowed in the properties hash of a channel request such as in the
+ <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.CreateChannel">CreateChannel</a>
+ and
+ <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.EnsureChannel">EnsureChannel</a>
+ methods
+ on <a href="Connection_Interface_Requests.html">Requests</a>
+ and <a href="Channel_Dispatcher.html">ChannelDispatcher</a>.
+ If supported on this protocol, the property should appear in either the
+ Fixed_Properties or Allowed_Properties of
+ a <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.RequestableChannelClasses">RequestableChannelClass</a>
+ advertised by the CM.</div>
+ #elif $property.requestable:
+ <div class="annotation requestable">This property
+ is <strong>requestable</strong>, which means that it is allowed
+ in the properties hash of a channel request such as in the
+ <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.CreateChannel">CreateChannel</a>
+ and
+ <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.EnsureChannel">EnsureChannel</a>
+ methods
+ on <a href="Connection_Interface_Requests.html">Requests</a>
+ and <a href="Channel_Dispatcher.html">ChannelDispatcher</a>.
+ The property should also appear in either the Fixed_Properties
+ or Allowed_Properties of
+ a <a href="Connection_Interface_Requests.html#org.freedesktop.Telepathy.Connection.Interface.Requests.RequestableChannelClasses">RequestableChannelClass</a>
+ advertised by the CM.</div>
+ #end if
+
+ $property.get_added()
+ $property.get_changed()
+ $property.get_deprecated()
+
+ #if not $property.immutable:
+ #if $property.emits_changed == $property.EMITS_CHANGED_UPDATES
+ <div class="annotation emits-changed emits-changed-updates">
+ When this property changes, the
+ <code>org.freedesktop.DBus.Properties.PropertiesChanged</code>
+ signal is emitted with the new value.
+ </div>
+ #elif $property.emits_changed == $property.EMITS_CHANGED_INVALIDATES
+ <div class="annotation emits-changed emits-changed-invalidates">
+ When this property changes, the
+ <code>org.freedesktop.DBus.Properties.PropertiesChanged</code>
+ signal is emitted, but the new value is not sent.
+ </div>
+ #elif $property.emits_changed == $property.EMITS_CHANGED_NONE
+ <div class="annotation emits-changed emits-changed-none">
+ The <code>org.freedesktop.DBus.Properties.PropertiesChanged</code>
+ signal is <strong>not</strong> emitted when this property changes.
+ </div>
+ #end if
+ #end if
+
+ #if $property.is_connection_parameter:
+ <div class="annotation connection-parameter">
+ <p><span class='note'>Note:</span> Connections implementing this
+ property SHOULD provide a corresponding parameter named
+ <tt>$property.name</tt> with the <a
+ href="Connection_Manager.html#Conn_Mgr_Param_Flags">DBus_Property</a>
+ flag. Clients SHOULD update this property by
+ calling <a
+ href="Account.html#org.freedesktop.Telepathy.Account.UpdateParameters">UpdateParameters</a>
+ on the relevant <a href="Account.html">Account</a> rather than
+ setting the property directly; change notification is via <a
+ href="Account.html#org.freedesktop.Telepathy.Account.AccountPropertyChanged">AccountPropertyChanged</a>.
+ </p>
+ </div>
+ #end if
+
+ $property.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.tpproperties
+ <div class="outset tpproperties tpproperty">
+ <a name="tpproperties"></a>
+ <h1>Telepathy Properties</h1>
+ <div>
+ Accessed using the <a
+ href="Properties_Interface.html">org.freedesktop.Telepathy.Properties</a>
+ interface.
+ </div>
+ #for $property in $interface.tpproperties
+ <div class="inset tpproperty">
+ <a name="$property.get_anchor()"></a>
+ <span class="permalink">(<a href="$property.get_url()">Permalink</a>)</span>
+ <h2>
+ $property.short_name &mdash; $property.dbus_type
+ #if $property.type: (<a href="$property.get_type_url()" title="$property.get_type_title()">$property.get_type().short_name</a>)
+ </h2>
+ $property.get_added()
+ $property.get_changed()
+ $property.get_deprecated()
+ $property.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.contact_attributes
+ <div class="outset contact-attributes">
+ <a name="contact-attributes"></a>
+ <h1>Contact Attributes</h1>
+ <div>
+ Attributes that a contact can have, accessed with the
+ org.freedesktop.Telepathy.Connection.Interface.Contacts interface.
+ </div>
+ #for $token in $interface.contact_attributes
+ <div class="inset contact-attribute">
+ <a name="$token.get_anchor()"></a>
+ <span class="permalink">(<a href="$token.get_url()">Permalink</a>)</span>
+ <h2>
+ $token.name &mdash; $token.dbus_type
+ #if $token.type: (<a href="$token.get_type_url()" title="$token.get_type_title()">$token.get_type().short_name</a>)
+ </h2>
+ $token.get_added()
+ $token.get_changed()
+ $token.get_deprecated()
+ $token.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.handler_capability_tokens
+ <div class="outset handler-capability-tokens">
+ <a name="handler-capability-tokens"></a>
+ <h1>Handler Capability Tokens</h1>
+ <div>
+ Tokens representing capabilities that a Client.Handler can have.
+ </div>
+ #for $token in $interface.handler_capability_tokens
+ <div class="inset handler-capability-token">
+ <a name="$token.get_anchor()"></a>
+ <span class="permalink">(<a href="$token.get_url()">Permalink</a>)</span>
+ <h2>
+ $token.name
+ #if $token.is_family
+ (etc.)
+ #end if
+ </h2>
+ $token.get_added()
+ $token.get_changed()
+ $token.get_deprecated()
+ $token.get_docstring()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ #if $interface.types
+ <div class="outset types type">
+ <a name="types"></a>
+ <h1>Types</h1>
+ #for $type in $interface.types
+ <div class="inset type">
+ <a name="$type.get_anchor()"></a>
+ <span class="permalink">$type.get_type_name() (<a href="$type.get_url()">Permalink</a>)</span>
+ <h2>
+ $type.short_name &mdash; $type.dbus_type
+ </h2>
+
+ $type.get_added()
+ $type.get_changed()
+ $type.get_deprecated()
+ $type.get_docstring()
+ $type.get_breakdown()
+ </div>
+ #end for
+ </div>
+ #end if
+
+ </div>
+
+ </body>
+</html>
diff --git a/spec/doc/templates/interfaces.html b/spec/doc/templates/interfaces.html
new file mode 100644
index 000000000..d3c5fee69
--- /dev/null
+++ b/spec/doc/templates/interfaces.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" "">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>$spec.title &mdash; v$spec.version</title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="shortcut icon" type="image/png" media="all" href="favicon.png" />
+ </head>
+ <body>
+ <div class="header">
+ <h1>$spec.title</h1>
+ <a href="index.html">Full</a>
+#if len($spec.generic_types) > 0
+ | <a href="generic-types.html">Generic Types</a>
+#end if
+#if len($spec.errors) > 0
+ | <a href="errors.html">Errors</a>
+#end if
+ | <a href="fullindex.html">Full Index</a>
+ </div>
+
+ <div class="main">
+ <b>Version $spec.version</b>
+
+ <a name="interfaces"></a>
+ <h3>Interfaces</h3>
+ <ul>
+ #for $interface in $spec.interfaces
+ #if $interface.causes_havoc
+ <li class="causes-havoc">
+ #elif $interface.is_deprecated
+ <li class="deprecated">
+ #else
+ <li>
+ #end if
+ <a href="$interface.get_url()">$interface.name</a>
+ #if $interface.causes_havoc
+ (unstable)
+ #elif $interface.is_deprecated
+ (deprecated)
+ #end if
+ </li>
+ #end for
+ </ul>
+
+#if len($spec.generic_types) > 0 or len($spec.errors) > 0
+ <a name="other"></a>
+ <h3>Other</h3>
+ <ul>
+ #if len($spec.generic_types) > 0
+ <li><a href="generic-types.html">Generic Types</a></li>
+ #end if
+ #if len($spec.errors) > 0
+ <li><a href="errors.html">Errors</a></li>
+ #end if
+ </ul>
+#end if
+
+ </div>
+ </body>
+</html>
diff --git a/spec/doc/templates/jquery.js b/spec/doc/templates/jquery.js
new file mode 100644
index 000000000..fff677643
--- /dev/null
+++ b/spec/doc/templates/jquery.js
@@ -0,0 +1,6240 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = "body";
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ if ( elem ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $("TAG")
+ } else if ( !context && /^\w+$/.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return jQuery( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.4.2",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
+ }
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || jQuery(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging object literal values or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+ : jQuery.isArray(copy) ? [] : {};
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 13 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn, i = 0;
+ while ( (fn = readyList[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Reset the list of functions
+ readyList = null;
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ return jQuery.ready();
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor
+ && !hasOwnProperty.call(obj, "constructor")
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwnProperty.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {},
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ if ( jQuery.support.scriptEval ) {
+ script.appendChild( document.createTextNode( data ) );
+ } else {
+ script.text = data;
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
+ }
+
+ return object;
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length, j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ if ( !inv !== !callback( elems[ i ], i ) ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var ret = [], value;
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ return indexOf.call( array, elem );
+ };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+ return (new Date).getTime();
+}
+(function() {
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + now();
+
+ div.style.display = "none";
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+ parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+ // Will be defined later
+ deleteExpando: true,
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e) {}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete script.test;
+
+ } catch(e) {
+ jQuery.support.deleteExpando = false;
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", click);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ div = document.createElement("div");
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function() {
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+
+ div = null;
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ var eventSupported = function( eventName ) {
+ var el = document.createElement("div");
+ eventName = "on" + eventName;
+
+ var isSupported = (eventName in el);
+ if ( !isSupported ) {
+ el.setAttribute(eventName, "return;");
+ isSupported = typeof el[eventName] === "function";
+ }
+ el = null;
+
+ return isSupported;
+ };
+
+ jQuery.support.submitBubbles = eventSupported("submit");
+ jQuery.support.changeBubbles = eventSupported("change");
+
+ // release memory in IE
+ root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ expando:expando,
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ "object": true,
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+ if ( !id && typeof name === "string" && data === undefined ) {
+ return null;
+ }
+
+ // Compute a unique ID for the element
+ if ( !id ) {
+ id = ++uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ elem[ expando ] = id;
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+ } else if ( !cache[ id ] ) {
+ elem[ expando ] = id;
+ cache[ id ] = {};
+ }
+
+ thisCache = cache[ id ];
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ // Completely remove the data cache
+ delete cache[ id ];
+ }
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ if ( typeof key === "undefined" && this.length ) {
+ return jQuery.data( this[0] );
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ }
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else {
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+ jQuery.data( this, key, value );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i, elem ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ }
+});
+var rclass = /[\n\t]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /href|src|style/,
+ rtype = /(button|input)/i,
+ rfocusable = /(button|input|object|select|textarea)/i,
+ rclickable = /^(a|area)$/i,
+ rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ", setClass = elem.className;
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ setClass += " " + classNames[c];
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split(rspace);
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Typecast each time if the value is a Function and the appended
+ // value is therefore different each time.
+ if ( typeof val === "number" ) {
+ val += "";
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ if ( elem.nodeType === 1 ) {
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+ // Using attr for specific style information is now deprecated. Use style instead.
+ return jQuery.style( elem, name, value );
+ }
+});
+var rnamespaces = /\.(.*)$/,
+ fcleanup = function( nm ) {
+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+ return "\\" + ch;
+ });
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery.data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events = elemData.events || {},
+ eventHandle = elemData.handle, eventHandle;
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ handleObj.guid = handler.guid;
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( var j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( var j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem /*, bubbling */ ) {
+ // Event object or event type
+ var type = event.type || event,
+ bubbling = arguments[3];
+
+ if ( !bubbling ) {
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+
+ // Only trigger if we've ever bound an event for it
+ if ( jQuery.event.global[ type ] ) {
+ jQuery.each( jQuery.cache, function() {
+ if ( this.events && this.events[type] ) {
+ jQuery.event.trigger( event, data, this.handle.elem );
+ }
+ });
+ }
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray( data );
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.apply( elem, data );
+ }
+
+ var parent = elem.parentNode || elem.ownerDocument;
+
+ // Trigger an inline bound script
+ try {
+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+ event.result = false;
+ }
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( !event.isPropagationStopped() && parent ) {
+ jQuery.event.trigger( event, data, parent, true );
+
+ } else if ( !event.isDefaultPrevented() ) {
+ var target = event.target, old,
+ isClick = jQuery.nodeName(target, "a") && type === "click",
+ special = jQuery.event.special[ type ] || {};
+
+ if ( (!special._default || special._default.call( elem, event ) === false) &&
+ !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+ try {
+ if ( target[ type ] ) {
+ // Make sure that we don't accidentally re-trigger the onFOO events
+ old = target[ "on" + type ];
+
+ if ( old ) {
+ target[ "on" + type ] = null;
+ }
+
+ jQuery.event.triggered = true;
+ target[ type ]();
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( old ) {
+ target[ "on" + type ] = old;
+ }
+
+ jQuery.event.triggered = false;
+ }
+ }
+ },
+
+ handle: function( event ) {
+ var all, handlers, namespaces, namespace, events;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+ if ( !all ) {
+ namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+ namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ var events = jQuery.data(this, "events"), handlers = events[ event.type ];
+
+ if ( events && handlers ) {
+ // Clone the handlers to prevent manipulation
+ handlers = handlers.slice(0);
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Filter the functions by class
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, arguments );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+ event.which = event.charCode || event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
+ },
+
+ remove: function( handleObj ) {
+ var remove = true,
+ type = handleObj.origType.replace(rnamespaces, "");
+
+ jQuery.each( jQuery.data(this, "events").live || [], function() {
+ if ( type === this.origType.replace(rnamespaces, "") ) {
+ remove = false;
+ return false;
+ }
+ });
+
+ if ( remove ) {
+ jQuery.event.remove( this, handleObj.origType, liveHandler );
+ }
+ }
+
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( this.setInterval ) {
+ this.onbeforeunload = eventHandle;
+ }
+
+ return false;
+ },
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+var removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ elem.removeEventListener( type, handle, false );
+ } :
+ function( elem, type, handle ) {
+ elem.detachEvent( "on" + type, handle );
+ };
+
+jQuery.Event = function( src ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[ expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+ }
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ parent = parent.parentNode;
+ }
+
+ if ( parent !== this ) {
+ // set the correct event type
+ event.type = event.data;
+
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( this.nodeName.toLowerCase() !== "form" ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var formElems = /textarea|input|select/i,
+
+ changeFilters,
+
+ getVal = function( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( elem.nodeName.toLowerCase() === "select" ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery.data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery.data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ return jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information/focus[in] is not needed anymore
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery.data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return formElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+}
+
+function trigger( type, elem, args ) {
+ args[0].type = type;
+ return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ this.addEventListener( orig, handler, true );
+ },
+ teardown: function() {
+ this.removeEventListener( orig, handler, true );
+ }
+ };
+
+ function handler( e ) {
+ e = jQuery.event.fix( e );
+ e.type = fix;
+ return jQuery.event.handle.call( this, e );
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ var event = jQuery.Event( type );
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while ( i < args.length ) {
+ jQuery.proxy( fn, args[ i++ ] );
+ }
+
+ return this.click( jQuery.proxy( fn, function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( type === "focus" || type === "blur" ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ context.each(function(){
+ jQuery.event.add( this, liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ });
+
+ } else {
+ // unbind live handler
+ context.unbind( liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ }
+});
+
+function liveHandler( event ) {
+ var stop, elems = [], selectors = [], args = arguments,
+ related, match, handleObj, elem, j, i, l, data,
+ events = jQuery.data( this, "events" );
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861)
+ if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+ return;
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( match[i].selector === handleObj.selector ) {
+ elem = match[i].elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
+ stop = false;
+ break;
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( fn ) {
+ return fn ? this.bind( name, fn ) : this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+ window.attachEvent("onunload", function() {
+ for ( var id in jQuery.cache ) {
+ if ( jQuery.cache[ id ].handle ) {
+ // Try/Catch is to handle iframes being unloaded, see #4280
+ try {
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+ } catch(e) {}
+ }
+ }
+ });
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var filter = Expr.filter[ type ], found, item, left = match[1];
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = part.toLowerCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ return match[1].toLowerCase();
+ },
+ CHILD: function(match){
+ if ( match[1] === "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 === i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ Sizzle.error( "Syntax error, unrecognized expression: " + name );
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ if ( type === "first" ) {
+ return true;
+ }
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first === 0 ) {
+ return diff === 0;
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+ return "\\" + (num - 0 + 1);
+ }));
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.sourceIndex ? -1 : 1;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.ownerDocument ? -1 : 1;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+ })();
+}
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return !!(a.compareDocumentPosition(b) & 16);
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+};
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var ret = this.pushStack( "", "find", selector ), length = 0;
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( var n = length; n < ret.length; n++ ) {
+ for ( var r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.filter( selector, this ).length > 0;
+ },
+
+ closest: function( selectors, context ) {
+ if ( jQuery.isArray( selectors ) ) {
+ var ret = [], cur = this[0], match, matches = {}, selector;
+
+ if ( cur && selectors.length ) {
+ for ( var i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[selector] ) {
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[selector];
+
+ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+ ret.push({ selector: selector, elem: cur });
+ delete matches[selector];
+ }
+ }
+ cur = cur.parentNode;
+ }
+ }
+
+ return ret;
+ }
+
+ var pos = jQuery.expr.match.POS.test( selectors ) ?
+ jQuery( selectors, context || this.context ) : null;
+
+ return this.map(function( i, cur ) {
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+ return cur;
+ }
+ cur = cur.parentNode;
+ }
+ return null;
+ });
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context || this.context ) :
+ jQuery.makeArray( selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call(arguments).join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [], cur = elem[dir];
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+ rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<script|<object|<embed|<option|<style/i,
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
+ fcloseTag = function( all, front, tag ) {
+ return rselfClosing.test( tag ) ?
+ all :
+ front + "></" + tag + ">";
+ },
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ), contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function() {
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML, ownerDocument = this.ownerDocument;
+ if ( !html ) {
+ var div = ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(rinlinejQuery, "")
+ // Handle the case in IE 8 where action=/test/> self-closes a tag
+ .replace(/=([^="'>\s]+\/)>/g, '="$1">')
+ .replace(rleadingWhitespace, "")], ownerDocument)[0];
+ } else {
+ return this.cloneNode(true);
+ }
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ cloneCopyEvent( this, ret );
+ cloneCopyEvent( this.find("*"), ret.find("*") );
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, fcloseTag);
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery(this), old = self.html();
+ self.empty().append(function(){
+ return value.call( this, i, old );
+ });
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery(value).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling, parent = this.parentNode;
+
+ jQuery(this).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, value = args[0], scripts = [], fragment, parent;
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ i > 0 || results.cacheable || this.length > 1 ?
+ fragment.cloneNode(true) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+});
+
+function cloneCopyEvent(orig, ret) {
+ var i = 0;
+
+ ret.each(function() {
+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ return;
+ }
+
+ var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+ }
+ });
+}
+
+function buildFragment( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults,
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+ // Only cache "small" (1/2 KB) strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults ) {
+ if ( cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+jQuery.extend({
+ clean: function( elems, context, fragment, scripts ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [];
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+
+ } else if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, fcloseTag);
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache,
+ special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ];
+
+ if ( data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ } else {
+ removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ ralpha = /alpha\([^)]*\)/,
+ ropacity = /opacity=([^)]*)/,
+ rfloat = /float/i,
+ rdashAlpha = /-([a-z])/ig,
+ rupper = /([A-Z])/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+
+ // cache check for defaultView.getComputedStyle
+ getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+ // normalize float css property
+ styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ return access( this, name, value, true, function( elem, name, value ) {
+ if ( value === undefined ) {
+ return jQuery.curCSS( elem, name );
+ }
+
+ if ( typeof value === "number" && !rexclude.test(name) ) {
+ value += "px";
+ }
+
+ jQuery.style( elem, name, value );
+ });
+};
+
+jQuery.extend({
+ style: function( elem, name, value ) {
+ // don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // ignore negative width and height values #1599
+ if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+ value = undefined;
+ }
+
+ var style = elem.style || elem, set = value !== undefined;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+ var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+ style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+ }
+
+ return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+ "";
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ name = name.replace(rdashAlpha, fcamelCase);
+
+ if ( set ) {
+ style[ name ] = value;
+ }
+
+ return style[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name === "width" || name === "height" ) {
+ var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+ function getWH() {
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ } else {
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ }
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 ) {
+ getWH();
+ } else {
+ jQuery.swap( elem, props, getWH );
+ }
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style, filter;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+ ret = ropacity.test(elem.currentStyle.filter || "") ?
+ (parseFloat(RegExp.$1) / 100) + "" :
+ "";
+
+ return ret === "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ if ( !force && style && style[ name ] ) {
+ ret = style[ name ];
+
+ } else if ( getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( rfloat.test( name ) ) {
+ name = "float";
+ }
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ var defaultView = elem.ownerDocument.defaultView;
+
+ if ( !defaultView ) {
+ return null;
+ }
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle ) {
+ ret = computedStyle.getPropertyValue( name );
+ }
+
+ // We should always get a number back from opacity
+ if ( name === "opacity" && ret === "" ) {
+ ret = "1";
+ }
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth, height = elem.offsetHeight,
+ skip = elem.nodeName.toLowerCase() === "tr";
+
+ return width === 0 && height === 0 && !skip ?
+ true :
+ width > 0 && height > 0 && !skip ?
+ false :
+ jQuery.curCSS(elem, "display") === "none";
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+var jsc = now(),
+ rscript = /<script(.|\s)*?\/script>/gi,
+ rselectTextarea = /select|textarea/i,
+ rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+ jsre = /=\?(&|$)/,
+ rquery = /\?/,
+ rts = /(\?|&)_=.*?(&|$)/,
+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+ r20 = /%20/g,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load;
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" ) {
+ return _load.call( this, url );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function( res, status ) {
+ // If successful, inject the HTML into all the matched elements
+ if ( status === "success" || status === "notmodified" ) {
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div />")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [res.responseText, status, res] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function() {
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function() {
+ return this.name && !this.disabled &&
+ (this.checked || rselectTextarea.test(this.nodeName) ||
+ rinput.test(this.type));
+ })
+ .map(function( i, elem ) {
+ var val = jQuery(this).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function( val, i ) {
+ return { name: elem.name, value: val };
+ }) :
+ { name: elem.name, value: val };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+ jQuery.fn[o] = function( f ) {
+ return this.bind(o, f);
+ };
+});
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ traditional: false,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7 (can't request local files),
+ // so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+ function() {
+ return new window.XMLHttpRequest();
+ } :
+ function() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {}
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajax: function( origSettings ) {
+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+
+ var jsonp, status, data,
+ callbackContext = origSettings && origSettings.context || s,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType === "jsonp" ) {
+ if ( type === "GET" ) {
+ if ( !jsre.test( s.url ) ) {
+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ }
+ } else if ( !s.data || !jsre.test(s.data) ) {
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ }
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data ) {
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ }
+
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+
+ try {
+ delete window[ jsonp ];
+ } catch(e) {}
+
+ if ( head ) {
+ head.removeChild( script );
+ }
+ };
+ }
+
+ if ( s.dataType === "script" && s.cache === null ) {
+ s.cache = false;
+ }
+
+ if ( s.cache === false && type === "GET" ) {
+ var ts = now();
+
+ // try replacing _= if it is there
+ var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type === "GET" ) {
+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Matches an absolute URL, and saves the domain
+ var parts = rurl.exec( s.url ),
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType === "script" && type === "GET" && remote ) {
+ var head = document.getElementsByTagName("head")[0] || document.documentElement;
+ var script = document.createElement("script");
+ script.src = s.url;
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function() {
+ if ( !done && (!this.readyState ||
+ this.readyState === "loaded" || this.readyState === "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+ }
+ };
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ if ( !xhr ) {
+ return;
+ }
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ } else {
+ xhr.open(type, s.url, s.async);
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data || origSettings && origSettings.contentType ) {
+ xhr.setRequestHeader("Content-Type", s.contentType);
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[s.url] ) {
+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+ }
+
+ if ( jQuery.etag[s.url] ) {
+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+ }
+ }
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ // Only send the header if it's not a remote XHR
+ if ( !remote ) {
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e) {}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global ) {
+ trigger("ajaxSend", [xhr, s]);
+ }
+
+ // Wait for a response to come back
+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+ // The request was aborted
+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+ // Opera doesn't call onreadystatechange before this point
+ // so we simulate the call
+ if ( !requestDone ) {
+ complete();
+ }
+
+ requestDone = true;
+ if ( xhr ) {
+ xhr.onreadystatechange = jQuery.noop;
+ }
+
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+ requestDone = true;
+ xhr.onreadystatechange = jQuery.noop;
+
+ status = isTimeout === "timeout" ?
+ "timeout" :
+ !jQuery.httpSuccess( xhr ) ?
+ "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+ "notmodified" :
+ "success";
+
+ var errMsg;
+
+ if ( status === "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(err) {
+ status = "parsererror";
+ errMsg = err;
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status === "success" || status === "notmodified" ) {
+ // JSONP handles its own success callback
+ if ( !jsonp ) {
+ success();
+ }
+ } else {
+ jQuery.handleError(s, xhr, status, errMsg);
+ }
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout === "timeout" ) {
+ xhr.abort();
+ }
+
+ // Stop memory leaks
+ if ( s.async ) {
+ xhr = null;
+ }
+ }
+ };
+
+ // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+ // Opera doesn't fire onreadystatechange at all on abort
+ try {
+ var oldAbort = xhr.abort;
+ xhr.abort = function() {
+ if ( xhr ) {
+ oldAbort.call( xhr );
+ }
+
+ onreadystatechange( "abort" );
+ };
+ } catch(e) { }
+
+ // Timeout checker
+ if ( s.async && s.timeout > 0 ) {
+ setTimeout(function() {
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone ) {
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ // Fire the complete handlers
+ complete();
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async ) {
+ onreadystatechange();
+ }
+
+ function success() {
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success ) {
+ s.success.call( callbackContext, data, status, xhr );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ trigger( "ajaxSuccess", [xhr, s] );
+ }
+ }
+
+ function complete() {
+ // Process result
+ if ( s.complete ) {
+ s.complete.call( callbackContext, xhr, status);
+ }
+
+ // The request was completed
+ if ( s.global ) {
+ trigger( "ajaxComplete", [xhr, s] );
+ }
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+
+ function trigger(type, args) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) {
+ s.error.call( s.context || s, xhr, status, e );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+ }
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol === "file:" ||
+ // Opera returns 0 when status is 304
+ ( xhr.status >= 200 && xhr.status < 300 ) ||
+ xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+ } catch(e) {}
+
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ var lastModified = xhr.getResponseHeader("Last-Modified"),
+ etag = xhr.getResponseHeader("Etag");
+
+ if ( lastModified ) {
+ jQuery.lastModified[url] = lastModified;
+ }
+
+ if ( etag ) {
+ jQuery.etag[url] = etag;
+ }
+
+ // Opera returns 0 when status is 304
+ return xhr.status === 304 || xhr.status === 0;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type") || "",
+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.nodeName === "parsererror" ) {
+ jQuery.error( "parsererror" );
+ }
+
+ // Allow a pre-filtering function to sanitize the response
+ // s is checked to keep backwards compatibility
+ if ( s && s.dataFilter ) {
+ data = s.dataFilter( data, type );
+ }
+
+ // The filter can actually parse the response
+ if ( typeof data === "string" ) {
+ // Get the JavaScript object, if JSON is used.
+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+ data = jQuery.parseJSON( data );
+
+ // If the type is "script", eval it in global context
+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+ jQuery.globalEval( data );
+ }
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [];
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray(a) || a.jquery ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[prefix] );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join("&").replace(r20, "+");
+
+ function buildParams( prefix, obj ) {
+ if ( jQuery.isArray(obj) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || /\[\]$/.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ jQuery.each( obj, function( k, v ) {
+ buildParams( prefix + "[" + k + "]", v );
+ });
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+ }
+
+ function add( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction(value) ? value() : value;
+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+ }
+ }
+});
+var elemdisplay = {},
+ rfxtypes = /toggle|show|hide/,
+ rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+jQuery.fn.extend({
+ show: function( speed, callback ) {
+ if ( speed || speed === 0) {
+ return this.animate( genFx("show", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var nodeName = this[i].nodeName, display;
+
+ if ( elemdisplay[ nodeName ] ) {
+ display = elemdisplay[ nodeName ];
+
+ } else {
+ var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+ display = elem.css("display");
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+
+ elem.remove();
+
+ elemdisplay[ nodeName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" ) {
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete );
+ }
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ var name = p.replace(rdashAlpha, fcamelCase);
+
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ p = name;
+ }
+
+ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+ return opt.complete.call(this);
+ }
+
+ if ( ( p === "height" || p === "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+
+ if ( jQuery.isArray( prop[p] ) ) {
+ // Create (if needed) and add to specialEasing
+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+ prop[p] = prop[p][0];
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function( name, val ) {
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+ } else {
+ var parts = rfxnum.exec(val),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ var timers = jQuery.timers;
+
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, callback ) {
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function() {
+ if ( opt.queue !== false ) {
+ jQuery(this).dequeue();
+ }
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig ) {
+ options.orig = {};
+ }
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+ this.elem.style.display = "block";
+ }
+ },
+
+ // Get the current size
+ cur: function( force ) {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(jQuery.fx.tick, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = now(), done = true;
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ for ( var i in this.options.curAnim ) {
+ if ( this.options.curAnim[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ var old = jQuery.data(this.elem, "olddisplay");
+ this.elem.style.display = old ? old : this.options.display;
+
+ if ( jQuery.css(this.elem, "display") === "none" ) {
+ this.elem.style.display = "block";
+ }
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide ) {
+ jQuery(this.elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show ) {
+ for ( var p in this.options.curAnim ) {
+ jQuery.style(this.elem, p, this.options.orig[p]);
+ }
+ }
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style(fx.elem, "opacity", fx.now);
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ body = container = innerDiv = checkDiv = table = td = null;
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop, left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
+ left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ var props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
+ offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
+ parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+function getWindow( elem ) {
+ return ("scrollTo" in elem && elem.document) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ return this[0] ?
+ jQuery.css( this[0], type, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ return this[0] ?
+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ] :
+
+ // Get document width or height
+ (elem.nodeType === 9) ? // is it a document
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ jQuery.css( elem, type ) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
diff --git a/spec/doc/templates/jquery.min.js b/spec/doc/templates/jquery.min.js
new file mode 100644
index 000000000..d02db0749
--- /dev/null
+++ b/spec/doc/templates/jquery.min.js
@@ -0,0 +1,23 @@
+/*
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(aM,C){var a=function(aY,aZ){return new a.fn.init(aY,aZ)},n=aM.jQuery,R=aM.$,ab=aM.document,X,P=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,aW=/^.[^:#\[\.,]*$/,ax=/\S/,M=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,e=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,b=navigator.userAgent,u,K=false,ad=[],aG,at=Object.prototype.toString,ap=Object.prototype.hasOwnProperty,g=Array.prototype.push,F=Array.prototype.slice,s=Array.prototype.indexOf;a.fn=a.prototype={init:function(aY,a1){var a0,a2,aZ,a3;if(!aY){return this}if(aY.nodeType){this.context=this[0]=aY;this.length=1;return this}if(aY==="body"&&!a1){this.context=ab;this[0]=ab.body;this.selector="body";this.length=1;return this}if(typeof aY==="string"){a0=P.exec(aY);if(a0&&(a0[1]||!a1)){if(a0[1]){a3=(a1?a1.ownerDocument||a1:ab);aZ=e.exec(aY);if(aZ){if(a.isPlainObject(a1)){aY=[ab.createElement(aZ[1])];a.fn.attr.call(aY,a1,true)}else{aY=[a3.createElement(aZ[1])]}}else{aZ=J([a0[1]],[a3]);aY=(aZ.cacheable?aZ.fragment.cloneNode(true):aZ.fragment).childNodes}return a.merge(this,aY)}else{a2=ab.getElementById(a0[2]);if(a2){if(a2.id!==a0[2]){return X.find(aY)}this.length=1;this[0]=a2}this.context=ab;this.selector=aY;return this}}else{if(!a1&&/^\w+$/.test(aY)){this.selector=aY;this.context=ab;aY=ab.getElementsByTagName(aY);return a.merge(this,aY)}else{if(!a1||a1.jquery){return(a1||X).find(aY)}else{return a(a1).find(aY)}}}}else{if(a.isFunction(aY)){return X.ready(aY)}}if(aY.selector!==C){this.selector=aY.selector;this.context=aY.context}return a.makeArray(aY,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(aY){return aY==null?this.toArray():(aY<0?this.slice(aY)[0]:this[aY])},pushStack:function(aZ,a1,aY){var a0=a();if(a.isArray(aZ)){g.apply(a0,aZ)}else{a.merge(a0,aZ)}a0.prevObject=this;a0.context=this.context;if(a1==="find"){a0.selector=this.selector+(this.selector?" ":"")+aY}else{if(a1){a0.selector=this.selector+"."+a1+"("+aY+")"}}return a0},each:function(aZ,aY){return a.each(this,aZ,aY)},ready:function(aY){a.bindReady();if(a.isReady){aY.call(ab,a)}else{if(ad){ad.push(aY)}}return this},eq:function(aY){return aY===-1?this.slice(aY):this.slice(aY,+aY+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(aY){return this.pushStack(a.map(this,function(a0,aZ){return aY.call(a0,aZ,a0)}))},end:function(){return this.prevObject||a(null)},push:g,sort:[].sort,splice:[].splice};a.fn.init.prototype=a.fn;a.extend=a.fn.extend=function(){var a3=arguments[0]||{},a2=1,a1=arguments.length,a5=false,a6,a0,aY,aZ;if(typeof a3==="boolean"){a5=a3;a3=arguments[1]||{};a2=2}if(typeof a3!=="object"&&!a.isFunction(a3)){a3={}}if(a1===a2){a3=this;--a2}for(;a2<a1;a2++){if((a6=arguments[a2])!=null){for(a0 in a6){aY=a3[a0];aZ=a6[a0];if(a3===aZ){continue}if(a5&&aZ&&(a.isPlainObject(aZ)||a.isArray(aZ))){var a4=aY&&(a.isPlainObject(aY)||a.isArray(aY))?aY:a.isArray(aZ)?[]:{};a3[a0]=a.extend(a5,a4,aZ)}else{if(aZ!==C){a3[a0]=aZ}}}}}return a3};a.extend({noConflict:function(aY){aM.$=R;if(aY){aM.jQuery=n}return a},isReady:false,ready:function(){if(!a.isReady){if(!ab.body){return setTimeout(a.ready,13)}a.isReady=true;if(ad){var aZ,aY=0;while((aZ=ad[aY++])){aZ.call(ab,a)}ad=null}if(a.fn.triggerHandler){a(ab).triggerHandler("ready")}}},bindReady:function(){if(K){return}K=true;if(ab.readyState==="complete"){return a.ready()}if(ab.addEventListener){ab.addEventListener("DOMContentLoaded",aG,false);aM.addEventListener("load",a.ready,false)}else{if(ab.attachEvent){ab.attachEvent("onreadystatechange",aG);aM.attachEvent("onload",a.ready);var aY=false;try{aY=aM.frameElement==null}catch(aZ){}if(ab.documentElement.doScroll&&aY){x()}}}},isFunction:function(aY){return at.call(aY)==="[object Function]"},isArray:function(aY){return at.call(aY)==="[object Array]"},isPlainObject:function(aZ){if(!aZ||at.call(aZ)!=="[object Object]"||aZ.nodeType||aZ.setInterval){return false}if(aZ.constructor&&!ap.call(aZ,"constructor")&&!ap.call(aZ.constructor.prototype,"isPrototypeOf")){return false}var aY;for(aY in aZ){}return aY===C||ap.call(aZ,aY)},isEmptyObject:function(aZ){for(var aY in aZ){return false}return true},error:function(aY){throw aY},parseJSON:function(aY){if(typeof aY!=="string"||!aY){return null}aY=a.trim(aY);if(/^[\],:{}\s]*$/.test(aY.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){return aM.JSON&&aM.JSON.parse?aM.JSON.parse(aY):(new Function("return "+aY))()}else{a.error("Invalid JSON: "+aY)}},noop:function(){},globalEval:function(a0){if(a0&&ax.test(a0)){var aZ=ab.getElementsByTagName("head")[0]||ab.documentElement,aY=ab.createElement("script");aY.type="text/javascript";if(a.support.scriptEval){aY.appendChild(ab.createTextNode(a0))}else{aY.text=a0}aZ.insertBefore(aY,aZ.firstChild);aZ.removeChild(aY)}},nodeName:function(aZ,aY){return aZ.nodeName&&aZ.nodeName.toUpperCase()===aY.toUpperCase()},each:function(a1,a5,a0){var aZ,a2=0,a3=a1.length,aY=a3===C||a.isFunction(a1);if(a0){if(aY){for(aZ in a1){if(a5.apply(a1[aZ],a0)===false){break}}}else{for(;a2<a3;){if(a5.apply(a1[a2++],a0)===false){break}}}}else{if(aY){for(aZ in a1){if(a5.call(a1[aZ],aZ,a1[aZ])===false){break}}}else{for(var a4=a1[0];a2<a3&&a5.call(a4,a2,a4)!==false;a4=a1[++a2]){}}}return a1},trim:function(aY){return(aY||"").replace(M,"")},makeArray:function(a0,aZ){var aY=aZ||[];if(a0!=null){if(a0.length==null||typeof a0==="string"||a.isFunction(a0)||(typeof a0!=="function"&&a0.setInterval)){g.call(aY,a0)}else{a.merge(aY,a0)}}return aY},inArray:function(a0,a1){if(a1.indexOf){return a1.indexOf(a0)}for(var aY=0,aZ=a1.length;aY<aZ;aY++){if(a1[aY]===a0){return aY}}return -1},merge:function(a2,a0){var a1=a2.length,aZ=0;if(typeof a0.length==="number"){for(var aY=a0.length;aZ<aY;aZ++){a2[a1++]=a0[aZ]}}else{while(a0[aZ]!==C){a2[a1++]=a0[aZ++]}}a2.length=a1;return a2},grep:function(aZ,a3,aY){var a0=[];for(var a1=0,a2=aZ.length;a1<a2;a1++){if(!aY!==!a3(aZ[a1],a1)){a0.push(aZ[a1])}}return a0},map:function(aZ,a4,aY){var a0=[],a3;for(var a1=0,a2=aZ.length;a1<a2;a1++){a3=a4(aZ[a1],a1,aY);if(a3!=null){a0[a0.length]=a3}}return a0.concat.apply([],a0)},guid:1,proxy:function(a0,aZ,aY){if(arguments.length===2){if(typeof aZ==="string"){aY=a0;a0=aY[aZ];aZ=C}else{if(aZ&&!a.isFunction(aZ)){aY=aZ;aZ=C}}}if(!aZ&&a0){aZ=function(){return a0.apply(aY||this,arguments)}}if(a0){aZ.guid=a0.guid=a0.guid||aZ.guid||a.guid++}return aZ},uaMatch:function(aZ){aZ=aZ.toLowerCase();var aY=/(webkit)[ \/]([\w.]+)/.exec(aZ)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(aZ)||/(msie) ([\w.]+)/.exec(aZ)||!/compatible/.test(aZ)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(aZ)||[];return{browser:aY[1]||"",version:aY[2]||"0"}},browser:{}});u=a.uaMatch(b);if(u.browser){a.browser[u.browser]=true;a.browser.version=u.version}if(a.browser.webkit){a.browser.safari=true}if(s){a.inArray=function(aY,aZ){return s.call(aZ,aY)}}X=a(ab);if(ab.addEventListener){aG=function(){ab.removeEventListener("DOMContentLoaded",aG,false);a.ready()}}else{if(ab.attachEvent){aG=function(){if(ab.readyState==="complete"){ab.detachEvent("onreadystatechange",aG);a.ready()}}}}function x(){if(a.isReady){return}try{ab.documentElement.doScroll("left")}catch(aY){setTimeout(x,1);return}a.ready()}function aV(aY,aZ){if(aZ.src){a.ajax({url:aZ.src,async:false,dataType:"script"})}else{a.globalEval(aZ.text||aZ.textContent||aZ.innerHTML||"")}if(aZ.parentNode){aZ.parentNode.removeChild(aZ)}}function an(aY,a6,a4,a0,a3,a5){var aZ=aY.length;if(typeof a6==="object"){for(var a1 in a6){an(aY,a1,a6[a1],a0,a3,a4)}return aY}if(a4!==C){a0=!a5&&a0&&a.isFunction(a4);for(var a2=0;a2<aZ;a2++){a3(aY[a2],a6,a0?a4.call(aY[a2],a2,a3(aY[a2],a6)):a4,a5)}return aY}return aZ?a3(aY[0],a6):C}function aP(){return(new Date).getTime()}(function(){a.support={};var a4=ab.documentElement,a3=ab.createElement("script"),aY=ab.createElement("div"),aZ="script"+aP();aY.style.display="none";aY.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var a6=aY.getElementsByTagName("*"),a5=aY.getElementsByTagName("a")[0];if(!a6||!a6.length||!a5){return}a.support={leadingWhitespace:aY.firstChild.nodeType===3,tbody:!aY.getElementsByTagName("tbody").length,htmlSerialize:!!aY.getElementsByTagName("link").length,style:/red/.test(a5.getAttribute("style")),hrefNormalized:a5.getAttribute("href")==="/a",opacity:/^0.55$/.test(a5.style.opacity),cssFloat:!!a5.style.cssFloat,checkOn:aY.getElementsByTagName("input")[0].value==="on",optSelected:ab.createElement("select").appendChild(ab.createElement("option")).selected,parentNode:aY.removeChild(aY.appendChild(ab.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};a3.type="text/javascript";try{a3.appendChild(ab.createTextNode("window."+aZ+"=1;"))}catch(a1){}a4.insertBefore(a3,a4.firstChild);if(aM[aZ]){a.support.scriptEval=true;delete aM[aZ]}try{delete a3.test}catch(a1){a.support.deleteExpando=false}a4.removeChild(a3);if(aY.attachEvent&&aY.fireEvent){aY.attachEvent("onclick",function a7(){a.support.noCloneEvent=false;aY.detachEvent("onclick",a7)});aY.cloneNode(true).fireEvent("onclick")}aY=ab.createElement("div");aY.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";var a0=ab.createDocumentFragment();a0.appendChild(aY.firstChild);a.support.checkClone=a0.cloneNode(true).cloneNode(true).lastChild.checked;a(function(){var a8=ab.createElement("div");a8.style.width=a8.style.paddingLeft="1px";ab.body.appendChild(a8);a.boxModel=a.support.boxModel=a8.offsetWidth===2;ab.body.removeChild(a8).style.display="none";a8=null});var a2=function(a8){var ba=ab.createElement("div");a8="on"+a8;var a9=(a8 in ba);if(!a9){ba.setAttribute(a8,"return;");a9=typeof ba[a8]==="function"}ba=null;return a9};a.support.submitBubbles=a2("submit");a.support.changeBubbles=a2("change");a4=a3=aY=a6=a5=null})();a.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var aI="jQuery"+aP(),aH=0,aT={};a.extend({cache:{},expando:aI,noData:{embed:true,object:true,applet:true},data:function(a0,aZ,a2){if(a0.nodeName&&a.noData[a0.nodeName.toLowerCase()]){return}a0=a0==aM?aT:a0;var a3=a0[aI],aY=a.cache,a1;if(!a3&&typeof aZ==="string"&&a2===C){return null}if(!a3){a3=++aH}if(typeof aZ==="object"){a0[aI]=a3;a1=aY[a3]=a.extend(true,{},aZ)}else{if(!aY[a3]){a0[aI]=a3;aY[a3]={}}}a1=aY[a3];if(a2!==C){a1[aZ]=a2}return typeof aZ==="string"?a1[aZ]:a1},removeData:function(a0,aZ){if(a0.nodeName&&a.noData[a0.nodeName.toLowerCase()]){return}a0=a0==aM?aT:a0;var a2=a0[aI],aY=a.cache,a1=aY[a2];if(aZ){if(a1){delete a1[aZ];if(a.isEmptyObject(a1)){a.removeData(a0)}}}else{if(a.support.deleteExpando){delete a0[a.expando]}else{if(a0.removeAttribute){a0.removeAttribute(a.expando)}}delete aY[a2]}}});a.fn.extend({data:function(aY,a0){if(typeof aY==="undefined"&&this.length){return a.data(this[0])}else{if(typeof aY==="object"){return this.each(function(){a.data(this,aY)})}}var a1=aY.split(".");a1[1]=a1[1]?"."+a1[1]:"";if(a0===C){var aZ=this.triggerHandler("getData"+a1[1]+"!",[a1[0]]);if(aZ===C&&this.length){aZ=a.data(this[0],aY)}return aZ===C&&a1[1]?this.data(a1[0]):aZ}else{return this.trigger("setData"+a1[1]+"!",[a1[0],a0]).each(function(){a.data(this,aY,a0)})}},removeData:function(aY){return this.each(function(){a.removeData(this,aY)})}});a.extend({queue:function(aZ,aY,a1){if(!aZ){return}aY=(aY||"fx")+"queue";var a0=a.data(aZ,aY);if(!a1){return a0||[]}if(!a0||a.isArray(a1)){a0=a.data(aZ,aY,a.makeArray(a1))}else{a0.push(a1)}return a0},dequeue:function(a1,a0){a0=a0||"fx";var aY=a.queue(a1,a0),aZ=aY.shift();if(aZ==="inprogress"){aZ=aY.shift()}if(aZ){if(a0==="fx"){aY.unshift("inprogress")}aZ.call(a1,function(){a.dequeue(a1,a0)})}}});a.fn.extend({queue:function(aY,aZ){if(typeof aY!=="string"){aZ=aY;aY="fx"}if(aZ===C){return a.queue(this[0],aY)}return this.each(function(a1,a2){var a0=a.queue(this,aY,aZ);if(aY==="fx"&&a0[0]!=="inprogress"){a.dequeue(this,aY)}})},dequeue:function(aY){return this.each(function(){a.dequeue(this,aY)})},delay:function(aZ,aY){aZ=a.fx?a.fx.speeds[aZ]||aZ:aZ;aY=aY||"fx";return this.queue(aY,function(){var a0=this;setTimeout(function(){a.dequeue(a0,aY)},aZ)})},clearQueue:function(aY){return this.queue(aY||"fx",[])}});var ao=/[\n\t]/g,S=/\s+/,av=/\r/g,aQ=/href|src|style/,d=/(button|input)/i,z=/(button|input|object|select|textarea)/i,j=/^(a|area)$/i,I=/radio|checkbox/;a.fn.extend({attr:function(aY,aZ){return an(this,aY,aZ,true,a.attr)},removeAttr:function(aY,aZ){return this.each(function(){a.attr(this,aY,"");if(this.nodeType===1){this.removeAttribute(aY)}})},addClass:function(a5){if(a.isFunction(a5)){return this.each(function(a8){var a7=a(this);a7.addClass(a5.call(this,a8,a7.attr("class")))})}if(a5&&typeof a5==="string"){var aY=(a5||"").split(S);for(var a1=0,a0=this.length;a1<a0;a1++){var aZ=this[a1];if(aZ.nodeType===1){if(!aZ.className){aZ.className=a5}else{var a2=" "+aZ.className+" ",a4=aZ.className;for(var a3=0,a6=aY.length;a3<a6;a3++){if(a2.indexOf(" "+aY[a3]+" ")<0){a4+=" "+aY[a3]}}aZ.className=a.trim(a4)}}}}return this},removeClass:function(a3){if(a.isFunction(a3)){return this.each(function(a7){var a6=a(this);a6.removeClass(a3.call(this,a7,a6.attr("class")))})}if((a3&&typeof a3==="string")||a3===C){var a4=(a3||"").split(S);for(var a0=0,aZ=this.length;a0<aZ;a0++){var a2=this[a0];if(a2.nodeType===1&&a2.className){if(a3){var a1=(" "+a2.className+" ").replace(ao," ");for(var a5=0,aY=a4.length;a5<aY;a5++){a1=a1.replace(" "+a4[a5]+" "," ")}a2.className=a.trim(a1)}else{a2.className=""}}}}return this},toggleClass:function(a1,aZ){var a0=typeof a1,aY=typeof aZ==="boolean";if(a.isFunction(a1)){return this.each(function(a3){var a2=a(this);a2.toggleClass(a1.call(this,a3,a2.attr("class"),aZ),aZ)})}return this.each(function(){if(a0==="string"){var a4,a3=0,a2=a(this),a5=aZ,a6=a1.split(S);while((a4=a6[a3++])){a5=aY?a5:!a2.hasClass(a4);a2[a5?"addClass":"removeClass"](a4)}}else{if(a0==="undefined"||a0==="boolean"){if(this.className){a.data(this,"__className__",this.className)}this.className=this.className||a1===false?"":a.data(this,"__className__")||""}}})},hasClass:function(aY){var a1=" "+aY+" ";for(var a0=0,aZ=this.length;a0<aZ;a0++){if((" "+this[a0].className+" ").replace(ao," ").indexOf(a1)>-1){return true}}return false},val:function(a5){if(a5===C){var aZ=this[0];if(aZ){if(a.nodeName(aZ,"option")){return(aZ.attributes.value||{}).specified?aZ.value:aZ.text}if(a.nodeName(aZ,"select")){var a3=aZ.selectedIndex,a6=[],a7=aZ.options,a2=aZ.type==="select-one";if(a3<0){return null}for(var a0=a2?a3:0,a4=a2?a3+1:a7.length;a0<a4;a0++){var a1=a7[a0];if(a1.selected){a5=a(a1).val();if(a2){return a5}a6.push(a5)}}return a6}if(I.test(aZ.type)&&!a.support.checkOn){return aZ.getAttribute("value")===null?"on":aZ.value}return(aZ.value||"").replace(av,"")}return C}var aY=a.isFunction(a5);return this.each(function(ba){var a9=a(this),bb=a5;if(this.nodeType!==1){return}if(aY){bb=a5.call(this,ba,a9.val())}if(typeof bb==="number"){bb+=""}if(a.isArray(bb)&&I.test(this.type)){this.checked=a.inArray(a9.val(),bb)>=0}else{if(a.nodeName(this,"select")){var a8=a.makeArray(bb);a("option",this).each(function(){this.selected=a.inArray(a(this).val(),a8)>=0});if(!a8.length){this.selectedIndex=-1}}else{this.value=bb}}})}});a.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(aZ,aY,a4,a7){if(!aZ||aZ.nodeType===3||aZ.nodeType===8){return C}if(a7&&aY in a.attrFn){return a(aZ)[aY](a4)}var a0=aZ.nodeType!==1||!a.isXMLDoc(aZ),a3=a4!==C;aY=a0&&a.props[aY]||aY;if(aZ.nodeType===1){var a2=aQ.test(aY);if(aY==="selected"&&!a.support.optSelected){var a5=aZ.parentNode;if(a5){a5.selectedIndex;if(a5.parentNode){a5.parentNode.selectedIndex}}}if(aY in aZ&&a0&&!a2){if(a3){if(aY==="type"&&d.test(aZ.nodeName)&&aZ.parentNode){a.error("type property can't be changed")}aZ[aY]=a4}if(a.nodeName(aZ,"form")&&aZ.getAttributeNode(aY)){return aZ.getAttributeNode(aY).nodeValue}if(aY==="tabIndex"){var a6=aZ.getAttributeNode("tabIndex");return a6&&a6.specified?a6.value:z.test(aZ.nodeName)||j.test(aZ.nodeName)&&aZ.href?0:C}return aZ[aY]}if(!a.support.style&&a0&&aY==="style"){if(a3){aZ.style.cssText=""+a4}return aZ.style.cssText}if(a3){aZ.setAttribute(aY,""+a4)}var a1=!a.support.hrefNormalized&&a0&&a2?aZ.getAttribute(aY,2):aZ.getAttribute(aY);return a1===null?C:a1}return a.style(aZ,aY,a4)}});var aC=/\.(.*)$/,A=function(aY){return aY.replace(/[^\w\s\.\|`]/g,function(aZ){return"\\"+aZ})};a.event={add:function(a1,a5,ba,a3){if(a1.nodeType===3||a1.nodeType===8){return}if(a1.setInterval&&(a1!==aM&&!a1.frameElement)){a1=aM}var aZ,a9;if(ba.handler){aZ=ba;ba=aZ.handler}if(!ba.guid){ba.guid=a.guid++}var a6=a.data(a1);if(!a6){return}var bb=a6.events=a6.events||{},a4=a6.handle,a4;if(!a4){a6.handle=a4=function(){return typeof a!=="undefined"&&!a.event.triggered?a.event.handle.apply(a4.elem,arguments):C}}a4.elem=a1;a5=a5.split(" ");var a8,a2=0,aY;while((a8=a5[a2++])){a9=aZ?a.extend({},aZ):{handler:ba,data:a3};if(a8.indexOf(".")>-1){aY=a8.split(".");a8=aY.shift();a9.namespace=aY.slice(0).sort().join(".")}else{aY=[];a9.namespace=""}a9.type=a8;a9.guid=ba.guid;var a0=bb[a8],a7=a.event.special[a8]||{};if(!a0){a0=bb[a8]=[];if(!a7.setup||a7.setup.call(a1,a3,aY,a4)===false){if(a1.addEventListener){a1.addEventListener(a8,a4,false)}else{if(a1.attachEvent){a1.attachEvent("on"+a8,a4)}}}}if(a7.add){a7.add.call(a1,a9);if(!a9.handler.guid){a9.handler.guid=ba.guid}}a0.push(a9);a.event.global[a8]=true}a1=null},global:{},remove:function(bd,a8,aZ,a4){if(bd.nodeType===3||bd.nodeType===8){return}var bg,a3,a5,bb=0,a1,a6,a9,a2,a7,aY,bf,bc=a.data(bd),a0=bc&&bc.events;if(!bc||!a0){return}if(a8&&a8.type){aZ=a8.handler;a8=a8.type}if(!a8||typeof a8==="string"&&a8.charAt(0)==="."){a8=a8||"";for(a3 in a0){a.event.remove(bd,a3+a8)}return}a8=a8.split(" ");while((a3=a8[bb++])){bf=a3;aY=null;a1=a3.indexOf(".")<0;a6=[];if(!a1){a6=a3.split(".");a3=a6.shift();a9=new RegExp("(^|\\.)"+a.map(a6.slice(0).sort(),A).join("\\.(?:.*\\.)?")+"(\\.|$)")}a7=a0[a3];if(!a7){continue}if(!aZ){for(var ba=0;ba<a7.length;ba++){aY=a7[ba];if(a1||a9.test(aY.namespace)){a.event.remove(bd,bf,aY.handler,ba);a7.splice(ba--,1)}}continue}a2=a.event.special[a3]||{};for(var ba=a4||0;ba<a7.length;ba++){aY=a7[ba];if(aZ.guid===aY.guid){if(a1||a9.test(aY.namespace)){if(a4==null){a7.splice(ba--,1)}if(a2.remove){a2.remove.call(bd,aY)}}if(a4!=null){break}}}if(a7.length===0||a4!=null&&a7.length===1){if(!a2.teardown||a2.teardown.call(bd,a6)===false){ag(bd,a3,bc.handle)}bg=null;delete a0[a3]}}if(a.isEmptyObject(a0)){var be=bc.handle;if(be){be.elem=null}delete bc.events;delete bc.handle;if(a.isEmptyObject(bc)){a.removeData(bd)}}},trigger:function(aY,a2,a0){var a7=aY.type||aY,a1=arguments[3];if(!a1){aY=typeof aY==="object"?aY[aI]?aY:a.extend(a.Event(a7),aY):a.Event(a7);if(a7.indexOf("!")>=0){aY.type=a7=a7.slice(0,-1);aY.exclusive=true}if(!a0){aY.stopPropagation();if(a.event.global[a7]){a.each(a.cache,function(){if(this.events&&this.events[a7]){a.event.trigger(aY,a2,this.handle.elem)}})}}if(!a0||a0.nodeType===3||a0.nodeType===8){return C}aY.result=C;aY.target=a0;a2=a.makeArray(a2);a2.unshift(aY)}aY.currentTarget=a0;var a3=a.data(a0,"handle");if(a3){a3.apply(a0,a2)}var a8=a0.parentNode||a0.ownerDocument;try{if(!(a0&&a0.nodeName&&a.noData[a0.nodeName.toLowerCase()])){if(a0["on"+a7]&&a0["on"+a7].apply(a0,a2)===false){aY.result=false}}}catch(a5){}if(!aY.isPropagationStopped()&&a8){a.event.trigger(aY,a2,a8,true)}else{if(!aY.isDefaultPrevented()){var a4=aY.target,aZ,a9=a.nodeName(a4,"a")&&a7==="click",a6=a.event.special[a7]||{};if((!a6._default||a6._default.call(a0,aY)===false)&&!a9&&!(a4&&a4.nodeName&&a.noData[a4.nodeName.toLowerCase()])){try{if(a4[a7]){aZ=a4["on"+a7];if(aZ){a4["on"+a7]=null}a.event.triggered=true;a4[a7]()}}catch(a5){}if(aZ){a4["on"+a7]=aZ}a.event.triggered=false}}}},handle:function(aY){var a6,a0,aZ,a1,a7;aY=arguments[0]=a.event.fix(aY||aM.event);aY.currentTarget=this;a6=aY.type.indexOf(".")<0&&!aY.exclusive;if(!a6){aZ=aY.type.split(".");aY.type=aZ.shift();a1=new RegExp("(^|\\.)"+aZ.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}var a7=a.data(this,"events"),a0=a7[aY.type];if(a7&&a0){a0=a0.slice(0);for(var a3=0,a2=a0.length;a3<a2;a3++){var a5=a0[a3];if(a6||a1.test(a5.namespace)){aY.handler=a5.handler;aY.data=a5.data;aY.handleObj=a5;var a4=a5.handler.apply(this,arguments);if(a4!==C){aY.result=a4;if(a4===false){aY.preventDefault();aY.stopPropagation()}}if(aY.isImmediatePropagationStopped()){break}}}}return aY.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a1){if(a1[aI]){return a1}var aZ=a1;a1=a.Event(aZ);for(var a0=this.props.length,a3;a0;){a3=this.props[--a0];a1[a3]=aZ[a3]}if(!a1.target){a1.target=a1.srcElement||ab}if(a1.target.nodeType===3){a1.target=a1.target.parentNode}if(!a1.relatedTarget&&a1.fromElement){a1.relatedTarget=a1.fromElement===a1.target?a1.toElement:a1.fromElement}if(a1.pageX==null&&a1.clientX!=null){var a2=ab.documentElement,aY=ab.body;a1.pageX=a1.clientX+(a2&&a2.scrollLeft||aY&&aY.scrollLeft||0)-(a2&&a2.clientLeft||aY&&aY.clientLeft||0);a1.pageY=a1.clientY+(a2&&a2.scrollTop||aY&&aY.scrollTop||0)-(a2&&a2.clientTop||aY&&aY.clientTop||0)}if(!a1.which&&((a1.charCode||a1.charCode===0)?a1.charCode:a1.keyCode)){a1.which=a1.charCode||a1.keyCode}if(!a1.metaKey&&a1.ctrlKey){a1.metaKey=a1.ctrlKey}if(!a1.which&&a1.button!==C){a1.which=(a1.button&1?1:(a1.button&2?3:(a1.button&4?2:0)))}return a1},guid:100000000,proxy:a.proxy,special:{ready:{setup:a.bindReady,teardown:a.noop},live:{add:function(aY){a.event.add(this,aY.origType,a.extend({},aY,{handler:V}))},remove:function(aZ){var aY=true,a0=aZ.origType.replace(aC,"");a.each(a.data(this,"events").live||[],function(){if(a0===this.origType.replace(aC,"")){aY=false;return false}});if(aY){a.event.remove(this,aZ.origType,V)}}},beforeunload:{setup:function(a0,aZ,aY){if(this.setInterval){this.onbeforeunload=aY}return false},teardown:function(aZ,aY){if(this.onbeforeunload===aY){this.onbeforeunload=null}}}}};var ag=ab.removeEventListener?function(aZ,aY,a0){aZ.removeEventListener(aY,a0,false)}:function(aZ,aY,a0){aZ.detachEvent("on"+aY,a0)};a.Event=function(aY){if(!this.preventDefault){return new a.Event(aY)}if(aY&&aY.type){this.originalEvent=aY;this.type=aY.type}else{this.type=aY}this.timeStamp=aP();this[aI]=true};function aR(){return false}function f(){return true}a.Event.prototype={preventDefault:function(){this.isDefaultPrevented=f;var aY=this.originalEvent;if(!aY){return}if(aY.preventDefault){aY.preventDefault()}aY.returnValue=false},stopPropagation:function(){this.isPropagationStopped=f;var aY=this.originalEvent;if(!aY){return}if(aY.stopPropagation){aY.stopPropagation()}aY.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=f;this.stopPropagation()},isDefaultPrevented:aR,isPropagationStopped:aR,isImmediatePropagationStopped:aR};var Q=function(aZ){var aY=aZ.relatedTarget;try{while(aY&&aY!==this){aY=aY.parentNode}if(aY!==this){aZ.type=aZ.data;a.event.handle.apply(this,arguments)}}catch(a0){}},ay=function(aY){aY.type=aY.data;a.event.handle.apply(this,arguments)};a.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(aZ,aY){a.event.special[aZ]={setup:function(a0){a.event.add(this,aY,a0&&a0.selector?ay:Q,aZ)},teardown:function(a0){a.event.remove(this,aY,a0&&a0.selector?ay:Q)}}});if(!a.support.submitBubbles){a.event.special.submit={setup:function(aZ,aY){if(this.nodeName.toLowerCase()!=="form"){a.event.add(this,"click.specialSubmit",function(a2){var a1=a2.target,a0=a1.type;if((a0==="submit"||a0==="image")&&a(a1).closest("form").length){return aA("submit",this,arguments)}});a.event.add(this,"keypress.specialSubmit",function(a2){var a1=a2.target,a0=a1.type;if((a0==="text"||a0==="password")&&a(a1).closest("form").length&&a2.keyCode===13){return aA("submit",this,arguments)}})}else{return false}},teardown:function(aY){a.event.remove(this,".specialSubmit")}}}if(!a.support.changeBubbles){var aq=/textarea|input|select/i,aS,i=function(aZ){var aY=aZ.type,a0=aZ.value;if(aY==="radio"||aY==="checkbox"){a0=aZ.checked}else{if(aY==="select-multiple"){a0=aZ.selectedIndex>-1?a.map(aZ.options,function(a1){return a1.selected}).join("-"):""}else{if(aZ.nodeName.toLowerCase()==="select"){a0=aZ.selectedIndex}}}return a0},O=function O(a0){var aY=a0.target,aZ,a1;if(!aq.test(aY.nodeName)||aY.readOnly){return}aZ=a.data(aY,"_change_data");a1=i(aY);if(a0.type!=="focusout"||aY.type!=="radio"){a.data(aY,"_change_data",a1)}if(aZ===C||a1===aZ){return}if(aZ!=null||a1){a0.type="change";return a.event.trigger(a0,arguments[1],aY)}};a.event.special.change={filters:{focusout:O,click:function(a0){var aZ=a0.target,aY=aZ.type;if(aY==="radio"||aY==="checkbox"||aZ.nodeName.toLowerCase()==="select"){return O.call(this,a0)}},keydown:function(a0){var aZ=a0.target,aY=aZ.type;if((a0.keyCode===13&&aZ.nodeName.toLowerCase()!=="textarea")||(a0.keyCode===32&&(aY==="checkbox"||aY==="radio"))||aY==="select-multiple"){return O.call(this,a0)}},beforeactivate:function(aZ){var aY=aZ.target;a.data(aY,"_change_data",i(aY))}},setup:function(a0,aZ){if(this.type==="file"){return false}for(var aY in aS){a.event.add(this,aY+".specialChange",aS[aY])}return aq.test(this.nodeName)},teardown:function(aY){a.event.remove(this,".specialChange");return aq.test(this.nodeName)}};aS=a.event.special.change.filters}function aA(aZ,a0,aY){aY[0].type=aZ;return a.event.handle.apply(a0,aY)}if(ab.addEventListener){a.each({focus:"focusin",blur:"focusout"},function(a0,aY){a.event.special[aY]={setup:function(){this.addEventListener(a0,aZ,true)},teardown:function(){this.removeEventListener(a0,aZ,true)}};function aZ(a1){a1=a.event.fix(a1);a1.type=aY;return a.event.handle.call(this,a1)}})}a.each(["bind","one"],function(aZ,aY){a.fn[aY]=function(a5,a6,a4){if(typeof a5==="object"){for(var a2 in a5){this[aY](a2,a6,a5[a2],a4)}return this}if(a.isFunction(a6)){a4=a6;a6=C}var a3=aY==="one"?a.proxy(a4,function(a7){a(this).unbind(a7,a3);return a4.apply(this,arguments)}):a4;if(a5==="unload"&&aY!=="one"){this.one(a5,a6,a4)}else{for(var a1=0,a0=this.length;a1<a0;a1++){a.event.add(this[a1],a5,a3,a6)}}return this}});a.fn.extend({unbind:function(a2,a1){if(typeof a2==="object"&&!a2.preventDefault){for(var a0 in a2){this.unbind(a0,a2[a0])}}else{for(var aZ=0,aY=this.length;aZ<aY;aZ++){a.event.remove(this[aZ],a2,a1)}}return this},delegate:function(aY,aZ,a1,a0){return this.live(aZ,a1,a0,aY)},undelegate:function(aY,aZ,a0){if(arguments.length===0){return this.unbind("live")}else{return this.die(aZ,null,a0,aY)}},trigger:function(aY,aZ){return this.each(function(){a.event.trigger(aY,aZ,this)})},triggerHandler:function(aY,a0){if(this[0]){var aZ=a.Event(aY);aZ.preventDefault();aZ.stopPropagation();a.event.trigger(aZ,a0,this[0]);return aZ.result}},toggle:function(a0){var aY=arguments,aZ=1;while(aZ<aY.length){a.proxy(a0,aY[aZ++])}return this.click(a.proxy(a0,function(a1){var a2=(a.data(this,"lastToggle"+a0.guid)||0)%aZ;a.data(this,"lastToggle"+a0.guid,a2+1);a1.preventDefault();return aY[a2].apply(this,arguments)||false}))},hover:function(aY,aZ){return this.mouseenter(aY).mouseleave(aZ||aY)}});var aw={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};a.each(["live","die"],function(aZ,aY){a.fn[aY]=function(a7,a4,a9,a2){var a8,a5=0,a6,a1,ba,a3=a2||this.selector,a0=a2?this:a(this.context);if(a.isFunction(a4)){a9=a4;a4=C}a7=(a7||"").split(" ");while((a8=a7[a5++])!=null){a6=aC.exec(a8);a1="";if(a6){a1=a6[0];a8=a8.replace(aC,"")}if(a8==="hover"){a7.push("mouseenter"+a1,"mouseleave"+a1);continue}ba=a8;if(a8==="focus"||a8==="blur"){a7.push(aw[a8]+a1);a8=a8+a1}else{a8=(aw[a8]||a8)+a1}if(aY==="live"){a0.each(function(){a.event.add(this,m(a8,a3),{data:a4,selector:a3,handler:a9,origType:a8,origHandler:a9,preType:ba})})}else{a0.unbind(m(a8,a3),a9)}}return this}});function V(aY){var a8,aZ=[],bb=[],a7=arguments,ba,a6,a9,a1,a3,a5,a2,a4,bc=a.data(this,"events");if(aY.liveFired===this||!bc||!bc.live||aY.button&&aY.type==="click"){return}aY.liveFired=this;var a0=bc.live.slice(0);for(a3=0;a3<a0.length;a3++){a9=a0[a3];if(a9.origType.replace(aC,"")===aY.type){bb.push(a9.selector)}else{a0.splice(a3--,1)}}a6=a(aY.target).closest(bb,aY.currentTarget);for(a5=0,a2=a6.length;a5<a2;a5++){for(a3=0;a3<a0.length;a3++){a9=a0[a3];if(a6[a5].selector===a9.selector){a1=a6[a5].elem;ba=null;if(a9.preType==="mouseenter"||a9.preType==="mouseleave"){ba=a(aY.relatedTarget).closest(a9.selector)[0]}if(!ba||ba!==a1){aZ.push({elem:a1,handleObj:a9})}}}}for(a5=0,a2=aZ.length;a5<a2;a5++){a6=aZ[a5];aY.currentTarget=a6.elem;aY.data=a6.handleObj.data;aY.handleObj=a6.handleObj;if(a6.handleObj.origHandler.apply(a6.elem,a7)===false){a8=false;break}}return a8}function m(aZ,aY){return"live."+(aZ&&aZ!=="*"?aZ+".":"")+aY.replace(/\./g,"`").replace(/ /g,"&")}a.each(("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error").split(" "),function(aZ,aY){a.fn[aY]=function(a0){return a0?this.bind(aY,a0):this.trigger(aY)};if(a.attrFn){a.attrFn[aY]=true}});if(aM.attachEvent&&!aM.addEventListener){aM.attachEvent("onunload",function(){for(var aZ in a.cache){if(a.cache[aZ].handle){try{a.event.remove(a.cache[aZ].handle.elem)}catch(aY){}}}});
+/*
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+}(function(){var a9=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,ba=0,bc=Object.prototype.toString,a4=false,a3=true;[0,0].sort(function(){a3=false;return 0});var a0=function(bl,bg,bo,bp){bo=bo||[];var br=bg=bg||ab;if(bg.nodeType!==1&&bg.nodeType!==9){return[]}if(!bl||typeof bl!=="string"){return bo}var bm=[],bi,bt,bw,bh,bk=true,bj=a1(bg),bq=bl;while((a9.exec(""),bi=a9.exec(bq))!==null){bq=bi[3];bm.push(bi[1]);if(bi[2]){bh=bi[3];break}}if(bm.length>1&&a5.exec(bl)){if(bm.length===2&&a6.relative[bm[0]]){bt=bd(bm[0]+bm[1],bg)}else{bt=a6.relative[bm[0]]?[bg]:a0(bm.shift(),bg);while(bm.length){bl=bm.shift();if(a6.relative[bl]){bl+=bm.shift()}bt=bd(bl,bt)}}}else{if(!bp&&bm.length>1&&bg.nodeType===9&&!bj&&a6.match.ID.test(bm[0])&&!a6.match.ID.test(bm[bm.length-1])){var bs=a0.find(bm.shift(),bg,bj);bg=bs.expr?a0.filter(bs.expr,bs.set)[0]:bs.set[0]}if(bg){var bs=bp?{expr:bm.pop(),set:a8(bp)}:a0.find(bm.pop(),bm.length===1&&(bm[0]==="~"||bm[0]==="+")&&bg.parentNode?bg.parentNode:bg,bj);bt=bs.expr?a0.filter(bs.expr,bs.set):bs.set;if(bm.length>0){bw=a8(bt)}else{bk=false}while(bm.length){var bv=bm.pop(),bu=bv;if(!a6.relative[bv]){bv=""}else{bu=bm.pop()}if(bu==null){bu=bg}a6.relative[bv](bw,bu,bj)}}else{bw=bm=[]}}if(!bw){bw=bt}if(!bw){a0.error(bv||bl)}if(bc.call(bw)==="[object Array]"){if(!bk){bo.push.apply(bo,bw)}else{if(bg&&bg.nodeType===1){for(var bn=0;bw[bn]!=null;bn++){if(bw[bn]&&(bw[bn]===true||bw[bn].nodeType===1&&a7(bg,bw[bn]))){bo.push(bt[bn])}}}else{for(var bn=0;bw[bn]!=null;bn++){if(bw[bn]&&bw[bn].nodeType===1){bo.push(bt[bn])}}}}}else{a8(bw,bo)}if(bh){a0(bh,br,bo,bp);a0.uniqueSort(bo)}return bo};a0.uniqueSort=function(bh){if(bb){a4=a3;bh.sort(bb);if(a4){for(var bg=1;bg<bh.length;bg++){if(bh[bg]===bh[bg-1]){bh.splice(bg--,1)}}}}return bh};a0.matches=function(bg,bh){return a0(bg,null,null,bh)};a0.find=function(bn,bg,bo){var bm,bk;if(!bn){return[]}for(var bj=0,bi=a6.order.length;bj<bi;bj++){var bl=a6.order[bj],bk;if((bk=a6.leftMatch[bl].exec(bn))){var bh=bk[1];bk.splice(1,1);if(bh.substr(bh.length-1)!=="\\"){bk[1]=(bk[1]||"").replace(/\\/g,"");bm=a6.find[bl](bk,bg,bo);if(bm!=null){bn=bn.replace(a6.match[bl],"");break}}}}if(!bm){bm=bg.getElementsByTagName("*")}return{set:bm,expr:bn}};a0.filter=function(br,bq,bu,bk){var bi=br,bw=[],bo=bq,bm,bg,bn=bq&&bq[0]&&a1(bq[0]);while(br&&bq.length){for(var bp in a6.filter){if((bm=a6.leftMatch[bp].exec(br))!=null&&bm[2]){var bh=a6.filter[bp],bv,bt,bj=bm[1];bg=false;bm.splice(1,1);if(bj.substr(bj.length-1)==="\\"){continue}if(bo===bw){bw=[]}if(a6.preFilter[bp]){bm=a6.preFilter[bp](bm,bo,bu,bw,bk,bn);if(!bm){bg=bv=true}else{if(bm===true){continue}}}if(bm){for(var bl=0;(bt=bo[bl])!=null;bl++){if(bt){bv=bh(bt,bm,bl,bo);var bs=bk^!!bv;if(bu&&bv!=null){if(bs){bg=true}else{bo[bl]=false}}else{if(bs){bw.push(bt);bg=true}}}}}if(bv!==C){if(!bu){bo=bw}br=br.replace(a6.match[bp],"");if(!bg){return[]}break}}}if(br===bi){if(bg==null){a0.error(br)}else{break}}bi=br}return bo};a0.error=function(bg){throw"Syntax error, unrecognized expression: "+bg};var a6=a0.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(bg){return bg.getAttribute("href")}},relative:{"+":function(bm,bh){var bj=typeof bh==="string",bl=bj&&!/\W/.test(bh),bn=bj&&!bl;if(bl){bh=bh.toLowerCase()}for(var bi=0,bg=bm.length,bk;bi<bg;bi++){if((bk=bm[bi])){while((bk=bk.previousSibling)&&bk.nodeType!==1){}bm[bi]=bn||bk&&bk.nodeName.toLowerCase()===bh?bk||false:bk===bh}}if(bn){a0.filter(bh,bm,true)}},">":function(bm,bh){var bk=typeof bh==="string";if(bk&&!/\W/.test(bh)){bh=bh.toLowerCase();for(var bi=0,bg=bm.length;bi<bg;bi++){var bl=bm[bi];if(bl){var bj=bl.parentNode;bm[bi]=bj.nodeName.toLowerCase()===bh?bj:false}}}else{for(var bi=0,bg=bm.length;bi<bg;bi++){var bl=bm[bi];if(bl){bm[bi]=bk?bl.parentNode:bl.parentNode===bh}}if(bk){a0.filter(bh,bm,true)}}},"":function(bj,bh,bl){var bi=ba++,bg=be;if(typeof bh==="string"&&!/\W/.test(bh)){var bk=bh=bh.toLowerCase();bg=aY}bg("parentNode",bh,bi,bj,bk,bl)},"~":function(bj,bh,bl){var bi=ba++,bg=be;if(typeof bh==="string"&&!/\W/.test(bh)){var bk=bh=bh.toLowerCase();bg=aY}bg("previousSibling",bh,bi,bj,bk,bl)}},find:{ID:function(bh,bi,bj){if(typeof bi.getElementById!=="undefined"&&!bj){var bg=bi.getElementById(bh[1]);return bg?[bg]:[]}},NAME:function(bi,bl){if(typeof bl.getElementsByName!=="undefined"){var bh=[],bk=bl.getElementsByName(bi[1]);for(var bj=0,bg=bk.length;bj<bg;bj++){if(bk[bj].getAttribute("name")===bi[1]){bh.push(bk[bj])}}return bh.length===0?null:bh}},TAG:function(bg,bh){return bh.getElementsByTagName(bg[1])}},preFilter:{CLASS:function(bj,bh,bi,bg,bm,bn){bj=" "+bj[1].replace(/\\/g,"")+" ";if(bn){return bj}for(var bk=0,bl;(bl=bh[bk])!=null;bk++){if(bl){if(bm^(bl.className&&(" "+bl.className+" ").replace(/[\t\n]/g," ").indexOf(bj)>=0)){if(!bi){bg.push(bl)}}else{if(bi){bh[bk]=false}}}}return false},ID:function(bg){return bg[1].replace(/\\/g,"")},TAG:function(bh,bg){return bh[1].toLowerCase()},CHILD:function(bg){if(bg[1]==="nth"){var bh=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(bg[2]==="even"&&"2n"||bg[2]==="odd"&&"2n+1"||!/\D/.test(bg[2])&&"0n+"+bg[2]||bg[2]);bg[2]=(bh[1]+(bh[2]||1))-0;bg[3]=bh[3]-0}bg[0]=ba++;return bg},ATTR:function(bk,bh,bi,bg,bl,bm){var bj=bk[1].replace(/\\/g,"");if(!bm&&a6.attrMap[bj]){bk[1]=a6.attrMap[bj]}if(bk[2]==="~="){bk[4]=" "+bk[4]+" "}return bk},PSEUDO:function(bk,bh,bi,bg,bl){if(bk[1]==="not"){if((a9.exec(bk[3])||"").length>1||/^\w/.test(bk[3])){bk[3]=a0(bk[3],null,null,bh)}else{var bj=a0.filter(bk[3],bh,bi,true^bl);if(!bi){bg.push.apply(bg,bj)}return false}}else{if(a6.match.POS.test(bk[0])||a6.match.CHILD.test(bk[0])){return true}}return bk},POS:function(bg){bg.unshift(true);return bg}},filters:{enabled:function(bg){return bg.disabled===false&&bg.type!=="hidden"},disabled:function(bg){return bg.disabled===true},checked:function(bg){return bg.checked===true},selected:function(bg){bg.parentNode.selectedIndex;return bg.selected===true},parent:function(bg){return !!bg.firstChild},empty:function(bg){return !bg.firstChild},has:function(bi,bh,bg){return !!a0(bg[3],bi).length},header:function(bg){return/h\d/i.test(bg.nodeName)},text:function(bg){return"text"===bg.type},radio:function(bg){return"radio"===bg.type},checkbox:function(bg){return"checkbox"===bg.type},file:function(bg){return"file"===bg.type},password:function(bg){return"password"===bg.type},submit:function(bg){return"submit"===bg.type},image:function(bg){return"image"===bg.type},reset:function(bg){return"reset"===bg.type},button:function(bg){return"button"===bg.type||bg.nodeName.toLowerCase()==="button"},input:function(bg){return/input|select|textarea|button/i.test(bg.nodeName)}},setFilters:{first:function(bh,bg){return bg===0},last:function(bi,bh,bg,bj){return bh===bj.length-1},even:function(bh,bg){return bg%2===0},odd:function(bh,bg){return bg%2===1},lt:function(bi,bh,bg){return bh<bg[3]-0},gt:function(bi,bh,bg){return bh>bg[3]-0},nth:function(bi,bh,bg){return bg[3]-0===bh},eq:function(bi,bh,bg){return bg[3]-0===bh}},filter:{PSEUDO:function(bm,bi,bj,bn){var bh=bi[1],bk=a6.filters[bh];if(bk){return bk(bm,bj,bi,bn)}else{if(bh==="contains"){return(bm.textContent||bm.innerText||aZ([bm])||"").indexOf(bi[3])>=0}else{if(bh==="not"){var bl=bi[3];for(var bj=0,bg=bl.length;bj<bg;bj++){if(bl[bj]===bm){return false}}return true}else{a0.error("Syntax error, unrecognized expression: "+bh)}}}},CHILD:function(bg,bj){var bm=bj[1],bh=bg;switch(bm){case"only":case"first":while((bh=bh.previousSibling)){if(bh.nodeType===1){return false}}if(bm==="first"){return true}bh=bg;case"last":while((bh=bh.nextSibling)){if(bh.nodeType===1){return false}}return true;case"nth":var bi=bj[2],bp=bj[3];if(bi===1&&bp===0){return true}var bl=bj[0],bo=bg.parentNode;if(bo&&(bo.sizcache!==bl||!bg.nodeIndex)){var bk=0;for(bh=bo.firstChild;bh;bh=bh.nextSibling){if(bh.nodeType===1){bh.nodeIndex=++bk}}bo.sizcache=bl}var bn=bg.nodeIndex-bp;if(bi===0){return bn===0}else{return(bn%bi===0&&bn/bi>=0)}}},ID:function(bh,bg){return bh.nodeType===1&&bh.getAttribute("id")===bg},TAG:function(bh,bg){return(bg==="*"&&bh.nodeType===1)||bh.nodeName.toLowerCase()===bg},CLASS:function(bh,bg){return(" "+(bh.className||bh.getAttribute("class"))+" ").indexOf(bg)>-1},ATTR:function(bl,bj){var bi=bj[1],bg=a6.attrHandle[bi]?a6.attrHandle[bi](bl):bl[bi]!=null?bl[bi]:bl.getAttribute(bi),bm=bg+"",bk=bj[2],bh=bj[4];return bg==null?bk==="!=":bk==="="?bm===bh:bk==="*="?bm.indexOf(bh)>=0:bk==="~="?(" "+bm+" ").indexOf(bh)>=0:!bh?bm&&bg!==false:bk==="!="?bm!==bh:bk==="^="?bm.indexOf(bh)===0:bk==="$="?bm.substr(bm.length-bh.length)===bh:bk==="|="?bm===bh||bm.substr(0,bh.length+1)===bh+"-":false},POS:function(bk,bh,bi,bl){var bg=bh[2],bj=a6.setFilters[bg];if(bj){return bj(bk,bi,bh,bl)}}}};var a5=a6.match.POS;for(var a2 in a6.match){a6.match[a2]=new RegExp(a6.match[a2].source+/(?![^\[]*\])(?![^\(]*\))/.source);a6.leftMatch[a2]=new RegExp(/(^(?:.|\r|\n)*?)/.source+a6.match[a2].source.replace(/\\(\d+)/g,function(bh,bg){return"\\"+(bg-0+1)}))}var a8=function(bh,bg){bh=Array.prototype.slice.call(bh,0);if(bg){bg.push.apply(bg,bh);return bg}return bh};try{Array.prototype.slice.call(ab.documentElement.childNodes,0)[0].nodeType}catch(bf){a8=function(bk,bj){var bh=bj||[];if(bc.call(bk)==="[object Array]"){Array.prototype.push.apply(bh,bk)}else{if(typeof bk.length==="number"){for(var bi=0,bg=bk.length;bi<bg;bi++){bh.push(bk[bi])}}else{for(var bi=0;bk[bi];bi++){bh.push(bk[bi])}}}return bh}}var bb;if(ab.documentElement.compareDocumentPosition){bb=function(bh,bg){if(!bh.compareDocumentPosition||!bg.compareDocumentPosition){if(bh==bg){a4=true}return bh.compareDocumentPosition?-1:1}var bi=bh.compareDocumentPosition(bg)&4?-1:bh===bg?0:1;if(bi===0){a4=true}return bi}}else{if("sourceIndex" in ab.documentElement){bb=function(bh,bg){if(!bh.sourceIndex||!bg.sourceIndex){if(bh==bg){a4=true}return bh.sourceIndex?-1:1}var bi=bh.sourceIndex-bg.sourceIndex;if(bi===0){a4=true}return bi}}else{if(ab.createRange){bb=function(bj,bh){if(!bj.ownerDocument||!bh.ownerDocument){if(bj==bh){a4=true}return bj.ownerDocument?-1:1}var bi=bj.ownerDocument.createRange(),bg=bh.ownerDocument.createRange();bi.setStart(bj,0);bi.setEnd(bj,0);bg.setStart(bh,0);bg.setEnd(bh,0);var bk=bi.compareBoundaryPoints(Range.START_TO_END,bg);if(bk===0){a4=true}return bk}}}}function aZ(bg){var bh="",bj;for(var bi=0;bg[bi];bi++){bj=bg[bi];if(bj.nodeType===3||bj.nodeType===4){bh+=bj.nodeValue}else{if(bj.nodeType!==8){bh+=aZ(bj.childNodes)}}}return bh}(function(){var bh=ab.createElement("div"),bi="script"+(new Date).getTime();bh.innerHTML="<a name='"+bi+"'/>";var bg=ab.documentElement;bg.insertBefore(bh,bg.firstChild);if(ab.getElementById(bi)){a6.find.ID=function(bk,bl,bm){if(typeof bl.getElementById!=="undefined"&&!bm){var bj=bl.getElementById(bk[1]);return bj?bj.id===bk[1]||typeof bj.getAttributeNode!=="undefined"&&bj.getAttributeNode("id").nodeValue===bk[1]?[bj]:C:[]}};a6.filter.ID=function(bl,bj){var bk=typeof bl.getAttributeNode!=="undefined"&&bl.getAttributeNode("id");return bl.nodeType===1&&bk&&bk.nodeValue===bj}}bg.removeChild(bh);bg=bh=null})();(function(){var bg=ab.createElement("div");bg.appendChild(ab.createComment(""));if(bg.getElementsByTagName("*").length>0){a6.find.TAG=function(bh,bl){var bk=bl.getElementsByTagName(bh[1]);if(bh[1]==="*"){var bj=[];for(var bi=0;bk[bi];bi++){if(bk[bi].nodeType===1){bj.push(bk[bi])}}bk=bj}return bk}}bg.innerHTML="<a href='#'></a>";if(bg.firstChild&&typeof bg.firstChild.getAttribute!=="undefined"&&bg.firstChild.getAttribute("href")!=="#"){a6.attrHandle.href=function(bh){return bh.getAttribute("href",2)}}bg=null})();if(ab.querySelectorAll){(function(){var bg=a0,bi=ab.createElement("div");bi.innerHTML="<p class='TEST'></p>";if(bi.querySelectorAll&&bi.querySelectorAll(".TEST").length===0){return}a0=function(bm,bl,bj,bk){bl=bl||ab;if(!bk&&bl.nodeType===9&&!a1(bl)){try{return a8(bl.querySelectorAll(bm),bj)}catch(bn){}}return bg(bm,bl,bj,bk)};for(var bh in bg){a0[bh]=bg[bh]}bi=null})()}(function(){var bg=ab.createElement("div");bg.innerHTML="<div class='test e'></div><div class='test'></div>";if(!bg.getElementsByClassName||bg.getElementsByClassName("e").length===0){return}bg.lastChild.className="e";if(bg.getElementsByClassName("e").length===1){return}a6.order.splice(1,0,"CLASS");a6.find.CLASS=function(bh,bi,bj){if(typeof bi.getElementsByClassName!=="undefined"&&!bj){return bi.getElementsByClassName(bh[1])}};bg=null})();function aY(bh,bm,bl,bp,bn,bo){for(var bj=0,bi=bp.length;bj<bi;bj++){var bg=bp[bj];if(bg){bg=bg[bh];var bk=false;while(bg){if(bg.sizcache===bl){bk=bp[bg.sizset];break}if(bg.nodeType===1&&!bo){bg.sizcache=bl;bg.sizset=bj}if(bg.nodeName.toLowerCase()===bm){bk=bg;break}bg=bg[bh]}bp[bj]=bk}}}function be(bh,bm,bl,bp,bn,bo){for(var bj=0,bi=bp.length;bj<bi;bj++){var bg=bp[bj];if(bg){bg=bg[bh];var bk=false;while(bg){if(bg.sizcache===bl){bk=bp[bg.sizset];break}if(bg.nodeType===1){if(!bo){bg.sizcache=bl;bg.sizset=bj}if(typeof bm!=="string"){if(bg===bm){bk=true;break}}else{if(a0.filter(bm,[bg]).length>0){bk=bg;break}}}bg=bg[bh]}bp[bj]=bk}}}var a7=ab.compareDocumentPosition?function(bh,bg){return !!(bh.compareDocumentPosition(bg)&16)}:function(bh,bg){return bh!==bg&&(bh.contains?bh.contains(bg):true)};var a1=function(bg){var bh=(bg?bg.ownerDocument||bg:0).documentElement;return bh?bh.nodeName!=="HTML":false};var bd=function(bg,bn){var bj=[],bk="",bl,bi=bn.nodeType?[bn]:bn;while((bl=a6.match.PSEUDO.exec(bg))){bk+=bl[0];bg=bg.replace(a6.match.PSEUDO,"")}bg=a6.relative[bg]?bg+"*":bg;for(var bm=0,bh=bi.length;bm<bh;bm++){a0(bg,bi[bm],bj)}return a0.filter(bk,bj)};a.find=a0;a.expr=a0.selectors;a.expr[":"]=a.expr.filters;a.unique=a0.uniqueSort;a.text=aZ;a.isXMLDoc=a1;a.contains=a7;return;aM.Sizzle=a0})();var N=/Until$/,Y=/^(?:parents|prevUntil|prevAll)/,aL=/,/,F=Array.prototype.slice;var ai=function(a1,a0,aY){if(a.isFunction(a0)){return a.grep(a1,function(a3,a2){return !!a0.call(a3,a2,a3)===aY})}else{if(a0.nodeType){return a.grep(a1,function(a3,a2){return(a3===a0)===aY})}else{if(typeof a0==="string"){var aZ=a.grep(a1,function(a2){return a2.nodeType===1});if(aW.test(a0)){return a.filter(a0,aZ,!aY)}else{a0=a.filter(a0,aZ)}}}}return a.grep(a1,function(a3,a2){return(a.inArray(a3,a0)>=0)===aY})};a.fn.extend({find:function(aY){var a0=this.pushStack("","find",aY),a3=0;for(var a1=0,aZ=this.length;a1<aZ;a1++){a3=a0.length;a.find(aY,this[a1],a0);if(a1>0){for(var a4=a3;a4<a0.length;a4++){for(var a2=0;a2<a3;a2++){if(a0[a2]===a0[a4]){a0.splice(a4--,1);break}}}}}return a0},has:function(aZ){var aY=a(aZ);return this.filter(function(){for(var a1=0,a0=aY.length;a1<a0;a1++){if(a.contains(this,aY[a1])){return true}}})},not:function(aY){return this.pushStack(ai(this,aY,false),"not",aY)},filter:function(aY){return this.pushStack(ai(this,aY,true),"filter",aY)},is:function(aY){return !!aY&&a.filter(aY,this).length>0},closest:function(a7,aY){if(a.isArray(a7)){var a4=[],a6=this[0],a3,a2={},a0;if(a6&&a7.length){for(var a1=0,aZ=a7.length;a1<aZ;a1++){a0=a7[a1];if(!a2[a0]){a2[a0]=a.expr.match.POS.test(a0)?a(a0,aY||this.context):a0}}while(a6&&a6.ownerDocument&&a6!==aY){for(a0 in a2){a3=a2[a0];if(a3.jquery?a3.index(a6)>-1:a(a6).is(a3)){a4.push({selector:a0,elem:a6});delete a2[a0]}}a6=a6.parentNode}}return a4}var a5=a.expr.match.POS.test(a7)?a(a7,aY||this.context):null;return this.map(function(a8,a9){while(a9&&a9.ownerDocument&&a9!==aY){if(a5?a5.index(a9)>-1:a(a9).is(a7)){return a9}a9=a9.parentNode}return null})},index:function(aY){if(!aY||typeof aY==="string"){return a.inArray(this[0],aY?a(aY):this.parent().children())}return a.inArray(aY.jquery?aY[0]:aY,this)},add:function(aY,aZ){var a1=typeof aY==="string"?a(aY,aZ||this.context):a.makeArray(aY),a0=a.merge(this.get(),a1);return this.pushStack(y(a1[0])||y(a0[0])?a0:a.unique(a0))},andSelf:function(){return this.add(this.prevObject)}});function y(aY){return !aY||!aY.parentNode||aY.parentNode.nodeType===11}a.each({parent:function(aZ){var aY=aZ.parentNode;return aY&&aY.nodeType!==11?aY:null},parents:function(aY){return a.dir(aY,"parentNode")},parentsUntil:function(aZ,aY,a0){return a.dir(aZ,"parentNode",a0)},next:function(aY){return a.nth(aY,2,"nextSibling")},prev:function(aY){return a.nth(aY,2,"previousSibling")},nextAll:function(aY){return a.dir(aY,"nextSibling")},prevAll:function(aY){return a.dir(aY,"previousSibling")},nextUntil:function(aZ,aY,a0){return a.dir(aZ,"nextSibling",a0)},prevUntil:function(aZ,aY,a0){return a.dir(aZ,"previousSibling",a0)},siblings:function(aY){return a.sibling(aY.parentNode.firstChild,aY)},children:function(aY){return a.sibling(aY.firstChild)},contents:function(aY){return a.nodeName(aY,"iframe")?aY.contentDocument||aY.contentWindow.document:a.makeArray(aY.childNodes)}},function(aY,aZ){a.fn[aY]=function(a2,a0){var a1=a.map(this,aZ,a2);if(!N.test(aY)){a0=a2}if(a0&&typeof a0==="string"){a1=a.filter(a0,a1)}a1=this.length>1?a.unique(a1):a1;if((this.length>1||aL.test(a0))&&Y.test(aY)){a1=a1.reverse()}return this.pushStack(a1,aY,F.call(arguments).join(","))}});a.extend({filter:function(a0,aY,aZ){if(aZ){a0=":not("+a0+")"}return a.find.matches(a0,aY)},dir:function(a0,aZ,a2){var aY=[],a1=a0[aZ];while(a1&&a1.nodeType!==9&&(a2===C||a1.nodeType!==1||!a(a1).is(a2))){if(a1.nodeType===1){aY.push(a1)}a1=a1[aZ]}return aY},nth:function(a2,aY,a0,a1){aY=aY||1;var aZ=0;for(;a2;a2=a2[a0]){if(a2.nodeType===1&&++aZ===aY){break}}return a2},sibling:function(a0,aZ){var aY=[];for(;a0;a0=a0.nextSibling){if(a0.nodeType===1&&a0!==aZ){aY.push(a0)}}return aY}});var T=/ jQuery\d+="(?:\d+|null)"/g,Z=/^\s+/,H=/(<([\w:]+)[^>]*?)\/>/g,al=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,c=/<([\w:]+)/,t=/<tbody/i,L=/<|&#?\w+;/,E=/<script|<object|<embed|<option|<style/i,l=/checked\s*(?:[^=]|=\s*.checked.)/i,p=function(aZ,a0,aY){return al.test(aY)?aZ:a0+"></"+aY+">"},ac={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};ac.optgroup=ac.option;ac.tbody=ac.tfoot=ac.colgroup=ac.caption=ac.thead;ac.th=ac.td;if(!a.support.htmlSerialize){ac._default=[1,"div<div>","</div>"]}a.fn.extend({text:function(aY){if(a.isFunction(aY)){return this.each(function(a0){var aZ=a(this);aZ.text(aY.call(this,a0,aZ.text()))})}if(typeof aY!=="object"&&aY!==C){return this.empty().append((this[0]&&this[0].ownerDocument||ab).createTextNode(aY))}return a.text(this)},wrapAll:function(aY){if(a.isFunction(aY)){return this.each(function(a0){a(this).wrapAll(aY.call(this,a0))})}if(this[0]){var aZ=a(aY,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){aZ.insertBefore(this[0])}aZ.map(function(){var a0=this;while(a0.firstChild&&a0.firstChild.nodeType===1){a0=a0.firstChild}return a0}).append(this)}return this},wrapInner:function(aY){if(a.isFunction(aY)){return this.each(function(aZ){a(this).wrapInner(aY.call(this,aZ))})}return this.each(function(){var aZ=a(this),a0=aZ.contents();if(a0.length){a0.wrapAll(aY)}else{aZ.append(aY)}})},wrap:function(aY){return this.each(function(){a(this).wrapAll(aY)})},unwrap:function(){return this.parent().each(function(){if(!a.nodeName(this,"body")){a(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(aY){if(this.nodeType===1){this.appendChild(aY)}})},prepend:function(){return this.domManip(arguments,true,function(aY){if(this.nodeType===1){this.insertBefore(aY,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(aZ){this.parentNode.insertBefore(aZ,this)})}else{if(arguments.length){var aY=a(arguments[0]);aY.push.apply(aY,this.toArray());return this.pushStack(aY,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(aZ){this.parentNode.insertBefore(aZ,this.nextSibling)})}else{if(arguments.length){var aY=this.pushStack(this,"after",arguments);aY.push.apply(aY,a(arguments[0]).toArray());return aY}}},remove:function(aY,a1){for(var aZ=0,a0;(a0=this[aZ])!=null;aZ++){if(!aY||a.filter(aY,[a0]).length){if(!a1&&a0.nodeType===1){a.cleanData(a0.getElementsByTagName("*"));a.cleanData([a0])}if(a0.parentNode){a0.parentNode.removeChild(a0)}}}return this},empty:function(){for(var aY=0,aZ;(aZ=this[aY])!=null;aY++){if(aZ.nodeType===1){a.cleanData(aZ.getElementsByTagName("*"))}while(aZ.firstChild){aZ.removeChild(aZ.firstChild)}}return this},clone:function(aZ){var aY=this.map(function(){if(!a.support.noCloneEvent&&!a.isXMLDoc(this)){var a1=this.outerHTML,a0=this.ownerDocument;if(!a1){var a2=a0.createElement("div");a2.appendChild(this.cloneNode(true));a1=a2.innerHTML}return a.clean([a1.replace(T,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(Z,"")],a0)[0]}else{return this.cloneNode(true)}});if(aZ===true){q(this,aY);q(this.find("*"),aY.find("*"))}return aY},html:function(a0){if(a0===C){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(T,""):null}else{if(typeof a0==="string"&&!E.test(a0)&&(a.support.leadingWhitespace||!Z.test(a0))&&!ac[(c.exec(a0)||["",""])[1].toLowerCase()]){a0=a0.replace(H,p);try{for(var aZ=0,aY=this.length;aZ<aY;aZ++){if(this[aZ].nodeType===1){a.cleanData(this[aZ].getElementsByTagName("*"));this[aZ].innerHTML=a0}}}catch(a1){this.empty().append(a0)}}else{if(a.isFunction(a0)){this.each(function(a4){var a3=a(this),a2=a3.html();a3.empty().append(function(){return a0.call(this,a4,a2)})})}else{this.empty().append(a0)}}}return this},replaceWith:function(aY){if(this[0]&&this[0].parentNode){if(a.isFunction(aY)){return this.each(function(a1){var a0=a(this),aZ=a0.html();a0.replaceWith(aY.call(this,a1,aZ))})}if(typeof aY!=="string"){aY=a(aY).detach()}return this.each(function(){var a0=this.nextSibling,aZ=this.parentNode;a(this).remove();if(a0){a(a0).before(aY)}else{a(aZ).append(aY)}})}else{return this.pushStack(a(a.isFunction(aY)?aY():aY),"replaceWith",aY)}},detach:function(aY){return this.remove(aY,true)},domManip:function(a4,a9,a8){var a1,a2,a7=a4[0],aZ=[],a3,a6;if(!a.support.checkClone&&arguments.length===3&&typeof a7==="string"&&l.test(a7)){return this.each(function(){a(this).domManip(a4,a9,a8,true)})}if(a.isFunction(a7)){return this.each(function(bb){var ba=a(this);a4[0]=a7.call(this,bb,a9?ba.html():C);ba.domManip(a4,a9,a8)})}if(this[0]){a6=a7&&a7.parentNode;if(a.support.parentNode&&a6&&a6.nodeType===11&&a6.childNodes.length===this.length){a1={fragment:a6}}else{a1=J(a4,this,aZ)}a3=a1.fragment;if(a3.childNodes.length===1){a2=a3=a3.firstChild}else{a2=a3.firstChild}if(a2){a9=a9&&a.nodeName(a2,"tr");for(var a0=0,aY=this.length;a0<aY;a0++){a8.call(a9?a5(this[a0],a2):this[a0],a0>0||a1.cacheable||this.length>1?a3.cloneNode(true):a3)}}if(aZ.length){a.each(aZ,aV)}}return this;function a5(ba,bb){return a.nodeName(ba,"table")?(ba.getElementsByTagName("tbody")[0]||ba.appendChild(ba.ownerDocument.createElement("tbody"))):ba}}});function q(a0,aY){var aZ=0;aY.each(function(){if(this.nodeName!==(a0[aZ]&&a0[aZ].nodeName)){return}var a5=a.data(a0[aZ++]),a4=a.data(this,a5),a1=a5&&a5.events;if(a1){delete a4.handle;a4.events={};for(var a3 in a1){for(var a2 in a1[a3]){a.event.add(this,a3,a1[a3][a2],a1[a3][a2].data)}}}})}function J(a3,a1,aZ){var a2,aY,a0,a4=(a1&&a1[0]?a1[0].ownerDocument||a1[0]:ab);if(a3.length===1&&typeof a3[0]==="string"&&a3[0].length<512&&a4===ab&&!E.test(a3[0])&&(a.support.checkClone||!l.test(a3[0]))){aY=true;a0=a.fragments[a3[0]];if(a0){if(a0!==1){a2=a0}}}if(!a2){a2=a4.createDocumentFragment();a.clean(a3,a4,a2,aZ)}if(aY){a.fragments[a3[0]]=a0?a2:1}return{fragment:a2,cacheable:aY}}a.fragments={};a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(aY,aZ){a.fn[aY]=function(a0){var a3=[],a6=a(a0),a5=this.length===1&&this[0].parentNode;if(a5&&a5.nodeType===11&&a5.childNodes.length===1&&a6.length===1){a6[aZ](this[0]);return this}else{for(var a4=0,a1=a6.length;a4<a1;a4++){var a2=(a4>0?this.clone(true):this).get();a.fn[aZ].apply(a(a6[a4]),a2);a3=a3.concat(a2)}return this.pushStack(a3,aY,a6.selector)}}});a.extend({clean:function(a0,a2,a9,a4){a2=a2||ab;if(typeof a2.createElement==="undefined"){a2=a2.ownerDocument||a2[0]&&a2[0].ownerDocument||ab}var ba=[];for(var a8=0,a3;(a3=a0[a8])!=null;a8++){if(typeof a3==="number"){a3+=""}if(!a3){continue}if(typeof a3==="string"&&!L.test(a3)){a3=a2.createTextNode(a3)}else{if(typeof a3==="string"){a3=a3.replace(H,p);var bb=(c.exec(a3)||["",""])[1].toLowerCase(),a1=ac[bb]||ac._default,a7=a1[0],aZ=a2.createElement("div");aZ.innerHTML=a1[1]+a3+a1[2];while(a7--){aZ=aZ.lastChild}if(!a.support.tbody){var aY=t.test(a3),a6=bb==="table"&&!aY?aZ.firstChild&&aZ.firstChild.childNodes:a1[1]==="<table>"&&!aY?aZ.childNodes:[];for(var a5=a6.length-1;a5>=0;--a5){if(a.nodeName(a6[a5],"tbody")&&!a6[a5].childNodes.length){a6[a5].parentNode.removeChild(a6[a5])}}}if(!a.support.leadingWhitespace&&Z.test(a3)){aZ.insertBefore(a2.createTextNode(Z.exec(a3)[0]),aZ.firstChild)}a3=aZ.childNodes}}if(a3.nodeType){ba.push(a3)}else{ba=a.merge(ba,a3)}}if(a9){for(var a8=0;ba[a8];a8++){if(a4&&a.nodeName(ba[a8],"script")&&(!ba[a8].type||ba[a8].type.toLowerCase()==="text/javascript")){a4.push(ba[a8].parentNode?ba[a8].parentNode.removeChild(ba[a8]):ba[a8])}else{if(ba[a8].nodeType===1){ba.splice.apply(ba,[a8+1,0].concat(a.makeArray(ba[a8].getElementsByTagName("script"))))}a9.appendChild(ba[a8])}}}return ba},cleanData:function(aZ){var a2,a0,aY=a.cache,a5=a.event.special,a4=a.support.deleteExpando;for(var a3=0,a1;(a1=aZ[a3])!=null;a3++){a0=a1[a.expando];if(a0){a2=aY[a0];if(a2.events){for(var a6 in a2.events){if(a5[a6]){a.event.remove(a1,a6)}else{ag(a1,a6,a2.handle)}}}if(a4){delete a1[a.expando]}else{if(a1.removeAttribute){a1.removeAttribute(a.expando)}}delete aY[a0]}}}});var ar=/z-?index|font-?weight|opacity|zoom|line-?height/i,U=/alpha\([^)]*\)/,aa=/opacity=([^)]*)/,ah=/float/i,az=/-([a-z])/ig,v=/([A-Z])/g,aO=/^-?\d+(?:px)?$/i,aU=/^-?\d/,aK={position:"absolute",visibility:"hidden",display:"block"},W=["Left","Right"],aE=["Top","Bottom"],ak=ab.defaultView&&ab.defaultView.getComputedStyle,aN=a.support.cssFloat?"cssFloat":"styleFloat",k=function(aY,aZ){return aZ.toUpperCase()};a.fn.css=function(aY,aZ){return an(this,aY,aZ,true,function(a1,a0,a2){if(a2===C){return a.curCSS(a1,a0)}if(typeof a2==="number"&&!ar.test(a0)){a2+="px"}a.style(a1,a0,a2)})};a.extend({style:function(a2,aZ,a3){if(!a2||a2.nodeType===3||a2.nodeType===8){return C}if((aZ==="width"||aZ==="height")&&parseFloat(a3)<0){a3=C}var a1=a2.style||a2,a4=a3!==C;if(!a.support.opacity&&aZ==="opacity"){if(a4){a1.zoom=1;var aY=parseInt(a3,10)+""==="NaN"?"":"alpha(opacity="+a3*100+")";var a0=a1.filter||a.curCSS(a2,"filter")||"";a1.filter=U.test(a0)?a0.replace(U,aY):aY}return a1.filter&&a1.filter.indexOf("opacity=")>=0?(parseFloat(aa.exec(a1.filter)[1])/100)+"":""}if(ah.test(aZ)){aZ=aN}aZ=aZ.replace(az,k);if(a4){a1[aZ]=a3}return a1[aZ]},css:function(a1,aZ,a3,aY){if(aZ==="width"||aZ==="height"){var a5,a0=aK,a4=aZ==="width"?W:aE;function a2(){a5=aZ==="width"?a1.offsetWidth:a1.offsetHeight;if(aY==="border"){return}a.each(a4,function(){if(!aY){a5-=parseFloat(a.curCSS(a1,"padding"+this,true))||0}if(aY==="margin"){a5+=parseFloat(a.curCSS(a1,"margin"+this,true))||0}else{a5-=parseFloat(a.curCSS(a1,"border"+this+"Width",true))||0}})}if(a1.offsetWidth!==0){a2()}else{a.swap(a1,a0,a2)}return Math.max(0,Math.round(a5))}return a.curCSS(a1,aZ,a3)},curCSS:function(a4,aZ,a0){var a7,aY=a4.style,a1;if(!a.support.opacity&&aZ==="opacity"&&a4.currentStyle){a7=aa.test(a4.currentStyle.filter||"")?(parseFloat(RegExp.$1)/100)+"":"";return a7===""?"1":a7}if(ah.test(aZ)){aZ=aN}if(!a0&&aY&&aY[aZ]){a7=aY[aZ]}else{if(ak){if(ah.test(aZ)){aZ="float"}aZ=aZ.replace(v,"-$1").toLowerCase();var a6=a4.ownerDocument.defaultView;if(!a6){return null}var a8=a6.getComputedStyle(a4,null);if(a8){a7=a8.getPropertyValue(aZ)}if(aZ==="opacity"&&a7===""){a7="1"}}else{if(a4.currentStyle){var a3=aZ.replace(az,k);a7=a4.currentStyle[aZ]||a4.currentStyle[a3];if(!aO.test(a7)&&aU.test(a7)){var a2=aY.left,a5=a4.runtimeStyle.left;a4.runtimeStyle.left=a4.currentStyle.left;aY.left=a3==="fontSize"?"1em":(a7||0);a7=aY.pixelLeft+"px";aY.left=a2;a4.runtimeStyle.left=a5}}}}return a7},swap:function(a1,a0,a2){var aY={};for(var aZ in a0){aY[aZ]=a1.style[aZ];a1.style[aZ]=a0[aZ]}a2.call(a1);for(var aZ in a0){a1.style[aZ]=aY[aZ]}}});if(a.expr&&a.expr.filters){a.expr.filters.hidden=function(a1){var aZ=a1.offsetWidth,aY=a1.offsetHeight,a0=a1.nodeName.toLowerCase()==="tr";return aZ===0&&aY===0&&!a0?true:aZ>0&&aY>0&&!a0?false:a.curCSS(a1,"display")==="none"};a.expr.filters.visible=function(aY){return !a.expr.filters.hidden(aY)}}var af=aP(),aJ=/<script(.|\s)*?\/script>/gi,o=/select|textarea/i,aB=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,r=/=\?(&|$)/,D=/\?/,aX=/(\?|&)_=.*?(&|$)/,B=/^(\w+:)?\/\/([^\/?#]+)/,h=/%20/g,w=a.fn.load;a.fn.extend({load:function(a0,a3,a4){if(typeof a0!=="string"){return w.call(this,a0)}else{if(!this.length){return this}}var a2=a0.indexOf(" ");if(a2>=0){var aY=a0.slice(a2,a0.length);a0=a0.slice(0,a2)}var a1="GET";if(a3){if(a.isFunction(a3)){a4=a3;a3=null}else{if(typeof a3==="object"){a3=a.param(a3,a.ajaxSettings.traditional);a1="POST"}}}var aZ=this;a.ajax({url:a0,type:a1,dataType:"html",data:a3,complete:function(a6,a5){if(a5==="success"||a5==="notmodified"){aZ.html(aY?a("<div />").append(a6.responseText.replace(aJ,"")).find(aY):a6.responseText)}if(a4){aZ.each(a4,[a6.responseText,a5,a6])}}});return this},serialize:function(){return a.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?a.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||o.test(this.nodeName)||aB.test(this.type))}).map(function(aY,aZ){var a0=a(this).val();return a0==null?null:a.isArray(a0)?a.map(a0,function(a2,a1){return{name:aZ.name,value:a2}}):{name:aZ.name,value:a0}}).get()}});a.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(aY,aZ){a.fn[aZ]=function(a0){return this.bind(aZ,a0)}});a.extend({get:function(aY,a0,a1,aZ){if(a.isFunction(a0)){aZ=aZ||a1;a1=a0;a0=null}return a.ajax({type:"GET",url:aY,data:a0,success:a1,dataType:aZ})},getScript:function(aY,aZ){return a.get(aY,null,aZ,"script")},getJSON:function(aY,aZ,a0){return a.get(aY,aZ,a0,"json")},post:function(aY,a0,a1,aZ){if(a.isFunction(a0)){aZ=aZ||a1;a1=a0;a0={}}return a.ajax({type:"POST",url:aY,data:a0,success:a1,dataType:aZ})},ajaxSetup:function(aY){a.extend(a.ajaxSettings,aY)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:aM.XMLHttpRequest&&(aM.location.protocol!=="file:"||!aM.ActiveXObject)?function(){return new aM.XMLHttpRequest()}:function(){try{return new aM.ActiveXObject("Microsoft.XMLHTTP")}catch(aY){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(bd){var a8=a.extend(true,{},a.ajaxSettings,bd);var bi,bc,bh,bj=bd&&bd.context||a8,a0=a8.type.toUpperCase();if(a8.data&&a8.processData&&typeof a8.data!=="string"){a8.data=a.param(a8.data,a8.traditional)}if(a8.dataType==="jsonp"){if(a0==="GET"){if(!r.test(a8.url)){a8.url+=(D.test(a8.url)?"&":"?")+(a8.jsonp||"callback")+"=?"}}else{if(!a8.data||!r.test(a8.data)){a8.data=(a8.data?a8.data+"&":"")+(a8.jsonp||"callback")+"=?"}}a8.dataType="json"}if(a8.dataType==="json"&&(a8.data&&r.test(a8.data)||r.test(a8.url))){bi=a8.jsonpCallback||("jsonp"+af++);if(a8.data){a8.data=(a8.data+"").replace(r,"="+bi+"$1")}a8.url=a8.url.replace(r,"="+bi+"$1");a8.dataType="script";aM[bi]=aM[bi]||function(bk){bh=bk;a3();a6();aM[bi]=C;try{delete aM[bi]}catch(bl){}if(a1){a1.removeChild(bf)}}}if(a8.dataType==="script"&&a8.cache===null){a8.cache=false}if(a8.cache===false&&a0==="GET"){var aY=aP();var bg=a8.url.replace(aX,"$1_="+aY+"$2");a8.url=bg+((bg===a8.url)?(D.test(a8.url)?"&":"?")+"_="+aY:"")}if(a8.data&&a0==="GET"){a8.url+=(D.test(a8.url)?"&":"?")+a8.data}if(a8.global&&!a.active++){a.event.trigger("ajaxStart")}var bb=B.exec(a8.url),a2=bb&&(bb[1]&&bb[1]!==location.protocol||bb[2]!==location.host);if(a8.dataType==="script"&&a0==="GET"&&a2){var a1=ab.getElementsByTagName("head")[0]||ab.documentElement;var bf=ab.createElement("script");bf.src=a8.url;if(a8.scriptCharset){bf.charset=a8.scriptCharset}if(!bi){var ba=false;bf.onload=bf.onreadystatechange=function(){if(!ba&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){ba=true;a3();a6();bf.onload=bf.onreadystatechange=null;if(a1&&bf.parentNode){a1.removeChild(bf)}}}}a1.insertBefore(bf,a1.firstChild);return C}var a5=false;var a4=a8.xhr();if(!a4){return}if(a8.username){a4.open(a0,a8.url,a8.async,a8.username,a8.password)}else{a4.open(a0,a8.url,a8.async)}try{if(a8.data||bd&&bd.contentType){a4.setRequestHeader("Content-Type",a8.contentType)}if(a8.ifModified){if(a.lastModified[a8.url]){a4.setRequestHeader("If-Modified-Since",a.lastModified[a8.url])}if(a.etag[a8.url]){a4.setRequestHeader("If-None-Match",a.etag[a8.url])}}if(!a2){a4.setRequestHeader("X-Requested-With","XMLHttpRequest")}a4.setRequestHeader("Accept",a8.dataType&&a8.accepts[a8.dataType]?a8.accepts[a8.dataType]+", */*":a8.accepts._default)}catch(be){}if(a8.beforeSend&&a8.beforeSend.call(bj,a4,a8)===false){if(a8.global&&!--a.active){a.event.trigger("ajaxStop")}a4.abort();return false}if(a8.global){a9("ajaxSend",[a4,a8])}var a7=a4.onreadystatechange=function(bk){if(!a4||a4.readyState===0||bk==="abort"){if(!a5){a6()}a5=true;if(a4){a4.onreadystatechange=a.noop}}else{if(!a5&&a4&&(a4.readyState===4||bk==="timeout")){a5=true;a4.onreadystatechange=a.noop;bc=bk==="timeout"?"timeout":!a.httpSuccess(a4)?"error":a8.ifModified&&a.httpNotModified(a4,a8.url)?"notmodified":"success";var bm;if(bc==="success"){try{bh=a.httpData(a4,a8.dataType,a8)}catch(bl){bc="parsererror";bm=bl}}if(bc==="success"||bc==="notmodified"){if(!bi){a3()}}else{a.handleError(a8,a4,bc,bm)}a6();if(bk==="timeout"){a4.abort()}if(a8.async){a4=null}}}};try{var aZ=a4.abort;a4.abort=function(){if(a4){aZ.call(a4)}a7("abort")}}catch(be){}if(a8.async&&a8.timeout>0){setTimeout(function(){if(a4&&!a5){a7("timeout")}},a8.timeout)}try{a4.send(a0==="POST"||a0==="PUT"||a0==="DELETE"?a8.data:null)}catch(be){a.handleError(a8,a4,null,be);a6()}if(!a8.async){a7()}function a3(){if(a8.success){a8.success.call(bj,bh,bc,a4)}if(a8.global){a9("ajaxSuccess",[a4,a8])}}function a6(){if(a8.complete){a8.complete.call(bj,a4,bc)}if(a8.global){a9("ajaxComplete",[a4,a8])}if(a8.global&&!--a.active){a.event.trigger("ajaxStop")}}function a9(bl,bk){(a8.context?a(a8.context):a.event).trigger(bl,bk)}return a4},handleError:function(aZ,a1,aY,a0){if(aZ.error){aZ.error.call(aZ.context||aZ,a1,aY,a0)}if(aZ.global){(aZ.context?a(aZ.context):a.event).trigger("ajaxError",[a1,aZ,a0])}},active:0,httpSuccess:function(aZ){try{return !aZ.status&&location.protocol==="file:"||(aZ.status>=200&&aZ.status<300)||aZ.status===304||aZ.status===1223||aZ.status===0}catch(aY){}return false},httpNotModified:function(a1,aY){var a0=a1.getResponseHeader("Last-Modified"),aZ=a1.getResponseHeader("Etag");if(a0){a.lastModified[aY]=a0}if(aZ){a.etag[aY]=aZ}return a1.status===304||a1.status===0},httpData:function(a3,a1,a0){var aZ=a3.getResponseHeader("content-type")||"",aY=a1==="xml"||!a1&&aZ.indexOf("xml")>=0,a2=aY?a3.responseXML:a3.responseText;if(aY&&a2.documentElement.nodeName==="parsererror"){a.error("parsererror")}if(a0&&a0.dataFilter){a2=a0.dataFilter(a2,a1)}if(typeof a2==="string"){if(a1==="json"||!a1&&aZ.indexOf("json")>=0){a2=a.parseJSON(a2)}else{if(a1==="script"||!a1&&aZ.indexOf("javascript")>=0){a.globalEval(a2)}}}return a2},param:function(aY,a1){var aZ=[];if(a1===C){a1=a.ajaxSettings.traditional}if(a.isArray(aY)||aY.jquery){a.each(aY,function(){a3(this.name,this.value)})}else{for(var a2 in aY){a0(a2,aY[a2])}}return aZ.join("&").replace(h,"+");function a0(a4,a5){if(a.isArray(a5)){a.each(a5,function(a7,a6){if(a1||/\[\]$/.test(a4)){a3(a4,a6)}else{a0(a4+"["+(typeof a6==="object"||a.isArray(a6)?a7:"")+"]",a6)}})}else{if(!a1&&a5!=null&&typeof a5==="object"){a.each(a5,function(a7,a6){a0(a4+"["+a7+"]",a6)})}else{a3(a4,a5)}}}function a3(a4,a5){a5=a.isFunction(a5)?a5():a5;aZ[aZ.length]=encodeURIComponent(a4)+"="+encodeURIComponent(a5)}}});var G={},ae=/toggle|show|hide/,au=/^([+-]=)?([\d+-.]+)(.*)$/,aF,aj=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];a.fn.extend({show:function(aZ,a7){if(aZ||aZ===0){return this.animate(aD("show",3),aZ,a7)}else{for(var a4=0,a1=this.length;a4<a1;a4++){var aY=a.data(this[a4],"olddisplay");this[a4].style.display=aY||"";if(a.css(this[a4],"display")==="none"){var a6=this[a4].nodeName,a5;if(G[a6]){a5=G[a6]}else{var a0=a("<"+a6+" />").appendTo("body");a5=a0.css("display");if(a5==="none"){a5="block"}a0.remove();G[a6]=a5}a.data(this[a4],"olddisplay",a5)}}for(var a3=0,a2=this.length;a3<a2;a3++){this[a3].style.display=a.data(this[a3],"olddisplay")||""}return this}},hide:function(a3,a4){if(a3||a3===0){return this.animate(aD("hide",3),a3,a4)}else{for(var a2=0,aZ=this.length;a2<aZ;a2++){var aY=a.data(this[a2],"olddisplay");if(!aY&&aY!=="none"){a.data(this[a2],"olddisplay",a.css(this[a2],"display"))}}for(var a1=0,a0=this.length;a1<a0;a1++){this[a1].style.display="none"}return this}},_toggle:a.fn.toggle,toggle:function(a0,aZ){var aY=typeof a0==="boolean";if(a.isFunction(a0)&&a.isFunction(aZ)){this._toggle.apply(this,arguments)}else{if(a0==null||aY){this.each(function(){var a1=aY?a0:a(this).is(":hidden");a(this)[a1?"show":"hide"]()})}else{this.animate(aD("toggle",3),a0,aZ)}}return this},fadeTo:function(aY,a0,aZ){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:a0},aY,aZ)},animate:function(a2,aZ,a1,a0){var aY=a.speed(aZ,a1,a0);if(a.isEmptyObject(a2)){return this.each(aY.complete)}return this[aY.queue===false?"each":"queue"](function(){var a5=a.extend({},aY),a7,a6=this.nodeType===1&&a(this).is(":hidden"),a3=this;for(a7 in a2){var a4=a7.replace(az,k);if(a7!==a4){a2[a4]=a2[a7];delete a2[a7];a7=a4}if(a2[a7]==="hide"&&a6||a2[a7]==="show"&&!a6){return a5.complete.call(this)}if((a7==="height"||a7==="width")&&this.style){a5.display=a.css(this,"display");a5.overflow=this.style.overflow}if(a.isArray(a2[a7])){(a5.specialEasing=a5.specialEasing||{})[a7]=a2[a7][1];a2[a7]=a2[a7][0]}}if(a5.overflow!=null){this.style.overflow="hidden"}a5.curAnim=a.extend({},a2);a.each(a2,function(a9,bd){var bc=new a.fx(a3,a5,a9);if(ae.test(bd)){bc[bd==="toggle"?a6?"show":"hide":bd](a2)}else{var bb=au.exec(bd),be=bc.cur(true)||0;if(bb){var a8=parseFloat(bb[2]),ba=bb[3]||"px";if(ba!=="px"){a3.style[a9]=(a8||1)+ba;be=((a8||1)/bc.cur(true))*be;a3.style[a9]=be+ba}if(bb[1]){a8=((bb[1]==="-="?-1:1)*a8)+be}bc.custom(be,a8,ba)}else{bc.custom(be,bd,"")}}});return true})},stop:function(aZ,aY){var a0=a.timers;if(aZ){this.queue([])}this.each(function(){for(var a1=a0.length-1;a1>=0;a1--){if(a0[a1].elem===this){if(aY){a0[a1](true)}a0.splice(a1,1)}}});if(!aY){this.dequeue()}return this}});a.each({slideDown:aD("show",1),slideUp:aD("hide",1),slideToggle:aD("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(aY,aZ){a.fn[aY]=function(a0,a1){return this.animate(aZ,a0,a1)}});a.extend({speed:function(a0,a1,aZ){var aY=a0&&typeof a0==="object"?a0:{complete:aZ||!aZ&&a1||a.isFunction(a0)&&a0,duration:a0,easing:aZ&&a1||a1&&!a.isFunction(a1)&&a1};aY.duration=a.fx.off?0:typeof aY.duration==="number"?aY.duration:a.fx.speeds[aY.duration]||a.fx.speeds._default;aY.old=aY.complete;aY.complete=function(){if(aY.queue!==false){a(this).dequeue()}if(a.isFunction(aY.old)){aY.old.call(this)}};return aY},easing:{linear:function(a0,a1,aY,aZ){return aY+aZ*a0},swing:function(a0,a1,aY,aZ){return((-Math.cos(a0*Math.PI)/2)+0.5)*aZ+aY}},timers:[],fx:function(aZ,aY,a0){this.options=aY;this.elem=aZ;this.prop=a0;if(!aY.orig){aY.orig={}}}});a.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(a.fx.step[this.prop]||a.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(aZ){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var aY=parseFloat(a.css(this.elem,this.prop,aZ));return aY&&aY>-10000?aY:parseFloat(a.curCSS(this.elem,this.prop))||0},custom:function(a2,a1,a0){this.startTime=aP();this.start=a2;this.end=a1;this.unit=a0||this.unit||"px";this.now=this.start;this.pos=this.state=0;var aY=this;function aZ(a3){return aY.step(a3)}aZ.elem=this.elem;if(aZ()&&a.timers.push(aZ)&&!aF){aF=setInterval(a.fx.tick,13)}},show:function(){this.options.orig[this.prop]=a.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());a(this.elem).show()},hide:function(){this.options.orig[this.prop]=a.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a1){var a6=aP(),a2=true;if(a1||a6>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var a3 in this.options.curAnim){if(this.options.curAnim[a3]!==true){a2=false}}if(a2){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;var a0=a.data(this.elem,"olddisplay");this.elem.style.display=a0?a0:this.options.display;if(a.css(this.elem,"display")==="none"){this.elem.style.display="block"}}if(this.options.hide){a(this.elem).hide()}if(this.options.hide||this.options.show){for(var aY in this.options.curAnim){a.style(this.elem,aY,this.options.orig[aY])}}this.options.complete.call(this.elem)}return false}else{var aZ=a6-this.startTime;this.state=aZ/this.options.duration;var a4=this.options.specialEasing&&this.options.specialEasing[this.prop];var a5=this.options.easing||(a.easing.swing?"swing":"linear");this.pos=a.easing[a4||a5](this.state,aZ,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};a.extend(a.fx,{tick:function(){var aZ=a.timers;for(var aY=0;aY<aZ.length;aY++){if(!aZ[aY]()){aZ.splice(aY--,1)}}if(!aZ.length){a.fx.stop()}},stop:function(){clearInterval(aF);aF=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(aY){a.style(aY.elem,"opacity",aY.now)},_default:function(aY){if(aY.elem.style&&aY.elem.style[aY.prop]!=null){aY.elem.style[aY.prop]=(aY.prop==="width"||aY.prop==="height"?Math.max(0,aY.now):aY.now)+aY.unit}else{aY.elem[aY.prop]=aY.now}}}});if(a.expr&&a.expr.filters){a.expr.filters.animated=function(aY){return a.grep(a.timers,function(aZ){return aY===aZ.elem}).length}}function aD(aZ,aY){var a0={};a.each(aj.concat.apply([],aj.slice(0,aY)),function(){a0[this]=aZ});return a0}if("getBoundingClientRect" in ab.documentElement){a.fn.offset=function(a7){var a0=this[0];if(a7){return this.each(function(a8){a.offset.setOffset(this,a7,a8)})}if(!a0||!a0.ownerDocument){return null}if(a0===a0.ownerDocument.body){return a.offset.bodyOffset(a0)}var a2=a0.getBoundingClientRect(),a6=a0.ownerDocument,a3=a6.body,aY=a6.documentElement,a1=aY.clientTop||a3.clientTop||0,a4=aY.clientLeft||a3.clientLeft||0,a5=a2.top+(self.pageYOffset||a.support.boxModel&&aY.scrollTop||a3.scrollTop)-a1,aZ=a2.left+(self.pageXOffset||a.support.boxModel&&aY.scrollLeft||a3.scrollLeft)-a4;return{top:a5,left:aZ}}}else{a.fn.offset=function(a9){var a3=this[0];if(a9){return this.each(function(ba){a.offset.setOffset(this,a9,ba)})}if(!a3||!a3.ownerDocument){return null}if(a3===a3.ownerDocument.body){return a.offset.bodyOffset(a3)}a.offset.initialize();var a0=a3.offsetParent,aZ=a3,a8=a3.ownerDocument,a6,a1=a8.documentElement,a4=a8.body,a5=a8.defaultView,aY=a5?a5.getComputedStyle(a3,null):a3.currentStyle,a7=a3.offsetTop,a2=a3.offsetLeft;while((a3=a3.parentNode)&&a3!==a4&&a3!==a1){if(a.offset.supportsFixedPosition&&aY.position==="fixed"){break}a6=a5?a5.getComputedStyle(a3,null):a3.currentStyle;a7-=a3.scrollTop;a2-=a3.scrollLeft;if(a3===a0){a7+=a3.offsetTop;a2+=a3.offsetLeft;if(a.offset.doesNotAddBorder&&!(a.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(a3.nodeName))){a7+=parseFloat(a6.borderTopWidth)||0;a2+=parseFloat(a6.borderLeftWidth)||0}aZ=a0,a0=a3.offsetParent}if(a.offset.subtractsBorderForOverflowNotVisible&&a6.overflow!=="visible"){a7+=parseFloat(a6.borderTopWidth)||0;a2+=parseFloat(a6.borderLeftWidth)||0}aY=a6}if(aY.position==="relative"||aY.position==="static"){a7+=a4.offsetTop;a2+=a4.offsetLeft}if(a.offset.supportsFixedPosition&&aY.position==="fixed"){a7+=Math.max(a1.scrollTop,a4.scrollTop);a2+=Math.max(a1.scrollLeft,a4.scrollLeft)}return{top:a7,left:a2}}}a.offset={initialize:function(){var aY=ab.body,aZ=ab.createElement("div"),a2,a4,a3,a5,a0=parseFloat(a.curCSS(aY,"marginTop",true))||0,a1="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.extend(aZ.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});aZ.innerHTML=a1;aY.insertBefore(aZ,aY.firstChild);a2=aZ.firstChild;a4=a2.firstChild;a5=a2.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(a4.offsetTop!==5);this.doesAddBorderForTableAndCells=(a5.offsetTop===5);a4.style.position="fixed",a4.style.top="20px";this.supportsFixedPosition=(a4.offsetTop===20||a4.offsetTop===15);a4.style.position=a4.style.top="";a2.style.overflow="hidden",a2.style.position="relative";this.subtractsBorderForOverflowNotVisible=(a4.offsetTop===-5);this.doesNotIncludeMarginInBodyOffset=(aY.offsetTop!==a0);aY.removeChild(aZ);aY=aZ=a2=a4=a3=a5=null;a.offset.initialize=a.noop},bodyOffset:function(aY){var a0=aY.offsetTop,aZ=aY.offsetLeft;a.offset.initialize();if(a.offset.doesNotIncludeMarginInBodyOffset){a0+=parseFloat(a.curCSS(aY,"marginTop",true))||0;aZ+=parseFloat(a.curCSS(aY,"marginLeft",true))||0}return{top:a0,left:aZ}},setOffset:function(a3,aZ,a0){if(/static/.test(a.curCSS(a3,"position"))){a3.style.position="relative"}var a2=a(a3),a5=a2.offset(),aY=parseInt(a.curCSS(a3,"top",true),10)||0,a4=parseInt(a.curCSS(a3,"left",true),10)||0;if(a.isFunction(aZ)){aZ=aZ.call(a3,a0,a5)}var a1={top:(aZ.top-a5.top)+aY,left:(aZ.left-a5.left)+a4};if("using" in aZ){aZ.using.call(a3,a1)}else{a2.css(a1)}}};a.fn.extend({position:function(){if(!this[0]){return null}var a0=this[0],aZ=this.offsetParent(),a1=this.offset(),aY=/^body|html$/i.test(aZ[0].nodeName)?{top:0,left:0}:aZ.offset();a1.top-=parseFloat(a.curCSS(a0,"marginTop",true))||0;a1.left-=parseFloat(a.curCSS(a0,"marginLeft",true))||0;aY.top+=parseFloat(a.curCSS(aZ[0],"borderTopWidth",true))||0;aY.left+=parseFloat(a.curCSS(aZ[0],"borderLeftWidth",true))||0;return{top:a1.top-aY.top,left:a1.left-aY.left}},offsetParent:function(){return this.map(function(){var aY=this.offsetParent||ab.body;while(aY&&(!/^body|html$/i.test(aY.nodeName)&&a.css(aY,"position")==="static")){aY=aY.offsetParent}return aY})}});a.each(["Left","Top"],function(aZ,aY){var a0="scroll"+aY;a.fn[a0]=function(a3){var a1=this[0],a2;if(!a1){return null}if(a3!==C){return this.each(function(){a2=am(this);if(a2){a2.scrollTo(!aZ?a3:a(a2).scrollLeft(),aZ?a3:a(a2).scrollTop())}else{this[a0]=a3}})}else{a2=am(a1);return a2?("pageXOffset" in a2)?a2[aZ?"pageYOffset":"pageXOffset"]:a.support.boxModel&&a2.document.documentElement[a0]||a2.document.body[a0]:a1[a0]}}});function am(aY){return("scrollTo" in aY&&aY.document)?aY:aY.nodeType===9?aY.defaultView||aY.parentWindow:false}a.each(["Height","Width"],function(aZ,aY){var a0=aY.toLowerCase();a.fn["inner"+aY]=function(){return this[0]?a.css(this[0],a0,false,"padding"):null};a.fn["outer"+aY]=function(a1){return this[0]?a.css(this[0],a0,false,a1?"margin":"border"):null};a.fn[a0]=function(a1){var a2=this[0];if(!a2){return a1==null?null:this}if(a.isFunction(a1)){return this.each(function(a4){var a3=a(this);a3[a0](a1.call(this,a4,a3[a0]()))})}return("scrollTo" in a2&&a2.document)?a2.document.compatMode==="CSS1Compat"&&a2.document.documentElement["client"+aY]||a2.document.body["client"+aY]:(a2.nodeType===9)?Math.max(a2.documentElement["client"+aY],a2.body["scroll"+aY],a2.documentElement["scroll"+aY],a2.body["offset"+aY],a2.documentElement["offset"+aY]):a1===C?a.css(a2,a0):this.css(a0,typeof a1==="string"?a1:a1+"px")}});aM.jQuery=aM.$=a})(window); \ No newline at end of file
diff --git a/spec/doc/templates/magic.js b/spec/doc/templates/magic.js
new file mode 100644
index 000000000..a4f6f6da0
--- /dev/null
+++ b/spec/doc/templates/magic.js
@@ -0,0 +1,47 @@
+/*
+ * magic.js — makes rationales in the HTML-ified spec collapsible.
+ *
+ * Copyright © 2010 Collabora Ltd.
+ * Copyright © 2010 Nokia Corporation.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author: Will Thompson <will.thompson@collabora.co.uk>
+ */
+
+$(document).ready(main);
+
+function toggleRationale() {
+ /* Slide the rationale body open or closed */
+ $(this).next().slideToggle('fast');
+
+ /* Rotate the triangle */
+ $(this).children('span.ui-icon').toggleClass(
+ 'ui-icon-triangle-1-s ui-icon-triangle-1-e');
+}
+
+function main() {
+ h5s = $('.rationale h5')
+
+ /* Un-hide the rationale headers */
+ h5s.css('display', 'block');
+
+ /* Add a "collapsed" triangle beside all the headers, and collapse them all.
+ */
+ h5s.prepend("<span class='ui-icon ui-icon-triangle-1-e'/>");
+ h5s.next().hide();
+
+ h5s.click(toggleRationale);
+}
diff --git a/spec/doc/templates/style.css b/spec/doc/templates/style.css
new file mode 100644
index 000000000..45ce833f3
--- /dev/null
+++ b/spec/doc/templates/style.css
@@ -0,0 +1,350 @@
+html, body,
+h1, h2 {
+ margin: 0;
+ padding: 0;
+}
+
+h3 {
+ margin-top: 2pt;
+ margin-bottom: 2pt;
+}
+
+ul {
+ margin: 1ex;
+ margin-left: 1.5em;
+ padding: 0;
+}
+
+hr {
+ border-style: none;
+ color: #cccccc;
+ background-color: #cccccc;
+ height: 1px;
+}
+
+div.header {
+ position: fixed;
+ height: 4em;
+ background-color: white;
+ width: 100%;
+ margin: 0;
+ padding: 0.5ex;
+ border-bottom: 1px solid black;
+ top: 0;
+ left: 0;
+ z-index: 1;
+}
+
+div.header h1 {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+div.main {
+ margin-top: 5em;
+ margin-left: 1ex;
+ margin-right: 1ex;
+ margin-bottom: 1ex;
+}
+
+div.main a[name] {
+ display: block;
+ position: relative;
+ top: -5em;
+}
+
+div.outset {
+ padding: 1ex;
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+}
+
+div.inset {
+ background-color: white;
+ margin-top: 1ex;
+ margin-bottom: 1ex;
+ padding: 0.5ex;
+}
+
+div.indent {
+ margin-left: 1em;
+}
+
+div.methods {
+ background-color: #fcaf3e;
+}
+
+div.method {
+ border: 1px solid #f57900;
+}
+
+div.signals {
+ background-color: #729fcf;
+}
+
+div.signal {
+ border: 1px solid #3465a4;
+}
+
+div.properties {
+ background-color: #ad7fa8;
+}
+
+div.property {
+ border: 1px solid #75507b;
+}
+
+div.tpproperties {
+ background-color: #999999;
+}
+
+div.tpproperty {
+ border: 1px solid #333333;
+}
+
+div.contact-attributes {
+ background-color: #ccccff;
+ border: 1px solid #9999cc;
+}
+
+div.contact-attribute {
+ border: 1px solid #9999cc;
+}
+
+div.handler-capability-tokens {
+ background-color: #339933;
+ border: 1px solid #228822;
+}
+
+div.handler-capability-token {
+ border: 1px solid #228822;
+}
+
+div.client-interests {
+ background-color: #729fcf;
+}
+
+div.client-interest {
+ border: 1px solid #204a87;
+}
+
+div.types {
+ background-color: #e9b96e;
+}
+
+div.type {
+ border: 1px solid #c17d11;
+}
+
+div.errors {
+ background-color: #ef2929;
+}
+
+div.error {
+ border: 1px solid #cc0000;
+}
+
+div.access {
+ font-weight: bold;
+ margin-left: 1ex;
+}
+
+div.summary, div.legal {
+ padding: 0.5ex;
+ background-color: #eeeeec;
+ border: 1px solid #d3d7cf;
+}
+
+div.legal ul {
+ list-style: none;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+table.summary {
+ margin: 1ex;
+ font-size: small;
+}
+
+table.summary td {
+ padding-right: 1ex;
+}
+
+li.chapter {
+ margin-top: 1ex;
+ font-weight: bold;
+}
+
+li.causes-havoc {
+ font-style: italic;
+}
+
+li.deprecated,
+li.deprecated a,
+table.summary tr.deprecated td,
+table.summary tr.deprecated td a {
+ color: gray;
+}
+
+div.requires,
+div.docstring {
+ margin: 1ex;
+}
+
+div.annotation {
+ border-left: 2px solid;
+ margin: 1ex;
+ padding-left: 1ex;
+}
+
+div.annotation span.version, span.warning, span.note {
+ font-weight: bold;
+}
+
+div.added {
+ border-left-color: #4e9a06;
+}
+
+div.added span.version {
+ color: #4e9a06;
+}
+
+div.changed {
+ border-left-color: #8f5902;
+}
+
+div.changed span.version {
+ color: #8f5902;
+}
+
+div.deprecated,
+div.havoc {
+ border-left-color: #a40000;
+}
+
+div.deprecated span.version,
+div.deprecated.no-version,
+span.warning {
+ color: #a40000;
+}
+
+div.connection-parameter {
+ border-left-color: #0000a4;
+}
+
+div.connection-parameter .note {
+ color: #0000a4;
+}
+
+div.emits-changed {
+ border-left-color: #17BBC3;
+}
+
+div.immutable {
+ border-left-color: #02598f;
+}
+
+div.no-reply {
+ border-left-color: #9C11A1;
+}
+
+div.requestable {
+ border-left-color: #598f02;
+}
+
+div.rationale {
+ border: 1px solid gray;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ margin: 1ex;
+ padding: 0 1ex;
+}
+
+div.rationale h5 {
+ /* This'll be un-done if we have Javascript; it's just clutter unless
+ * we have Javascript, in which case it acts as the thing for
+ * expanding/collapsing rationales.
+ */
+ display: none;
+
+ /* And all this only matters if the script has un-hidden us. */
+ margin: 0;
+ text-height: 12px;
+ cursor: pointer;
+}
+
+/* The class names used for the expander icons, and the technique of using a
+ * fixed-size background image, offset into a grid of icons, is pinched from
+ * jQuery-UI, along with the icon grid itself. But I only use a 10×10 square
+ * out of the 16×16 icons, and didn't use their CSS, because jQuery-UI was
+ * overkill here.
+ */
+span.ui-icon {
+ text-decoration: none;
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin-right: 0.5em;
+ background-image: url(ui-icons_222222_256x240.png);
+ background-repeat: no-repeat;
+}
+
+span.ui-icon-triangle-1-e {
+ background-position:-35px -19px;
+}
+
+span.ui-icon-triangle-1-s {
+ background-position:-67px -19px;
+}
+
+span.permalink {
+ font-size: x-small;
+}
+
+div.inset span.permalink {
+ float: right;
+}
+
+li.chapter span.permalink {
+ font-weight: normal;
+}
+
+/* These rules make putting <p/> into <dd/> not leave ugly whitespace at the
+ * top and bottom of the <dd>, which looks particularly stupid when some <dd>s
+ * have <p>s in them and some just have text.
+ */
+p {
+ margin: 0.5em 0 0 0;
+}
+
+p:first-child {
+ margin-top: 0;
+}
+
+/* And since we use <pre>s pretty much only for paragraphs of code, we should
+ * style it the same.
+ */
+pre {
+ margin: 0.5em 0 0 0;
+}
+
+.docstring table {
+ border: 1px solid #d3d7cf;
+ background-color: #eeeeec;
+ margin: 0.5em 0 0 0;
+ border-collapse: collapse;
+}
+
+.docstring th,
+.docstring td {
+ padding: 4px;
+}
+
+.docstring th {
+ border-bottom: 1px dotted #d3d7cf;
+}
+
+.docstring tr:nth-child(even) {
+ background-color: #dddddc;
+}
diff --git a/spec/doc/templates/ui-icons_222222_256x240.png b/spec/doc/templates/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..b273ff111
--- /dev/null
+++ b/spec/doc/templates/ui-icons_222222_256x240.png
Binary files differ
diff --git a/spec/spec/Account.xml b/spec/spec/Account.xml
new file mode 100644
index 000000000..675ea8125
--- /dev/null
+++ b/spec/spec/Account.xml
@@ -0,0 +1,715 @@
+<?xml version="1.0" ?>
+<node name="/Account"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Account">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An Account object encapsulates the necessary details to make a
+ Telepathy connection.</p>
+
+ <p>Accounts are uniquely identified by object path. The object path
+ of an Account MUST take the form
+ <code>/org/freedesktop/Telepathy/Account/<em>cm</em>/<em>proto</em>/<em>acct</em></code>, where:</p>
+
+ <ul>
+ <li><em>cm</em> is the same <tp:type>Connection_Manager_Name</tp:type>
+ that appears in the connection manager's well-known bus name and
+ object path</li>
+ <li><em>proto</em> is the <tp:type>Protocol</tp:type> name as seen in
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ConnectionManager.ListProtocols</tp:dbus-ref>,
+ but with "-" replaced with "_"
+ (i.e. the same as in the object-path of a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>)</li>
+ <li><em>acct</em> is an arbitrary string of ASCII letters, digits
+ and underscores, starting with a letter or underscore, which
+ uniquely identifies this account</li>
+ <li>Clients SHOULD parse the object path to discover the
+ connection manager and protocol</li>
+ <li>Clients MUST NOT attempt to parse <em>acct</em></li>
+ <li>Clients MUST NOT assume that <em>acct</em> matches
+ the connection-specific part of a Connection's object-path and
+ bus name</li>
+ <li>The account manager SHOULD choose <em>acct</em> such that if
+ an account is deleted, its object path will be re-used if and only
+ if the new account is in some sense "the same"
+ (incorporating the 'account' parameter in some way is
+ recommended)</li>
+ </ul>
+
+ <tp:rationale>
+ <p>This API avoids specifying the "profiles" used in Mission Control
+ 4.x or the "presets" that have been proposed to replace them. An
+ optional interface will be provided for AM implementations
+ that want to provide presets.</p>
+
+ <p>There is deliberately no functionality here for opening channels;
+ we intend to provide that in the channel dispatcher.</p>
+
+ <p>Other missing features which would be better in their own
+ interfaces:</p>
+
+ <ul>
+ <li>dynamic parameter-providing (aka provisioning)</li>
+ <li>saved server capabilities</li>
+ <li>account conditions</li>
+ <li>account grouping</li>
+ </ul>
+ </tp:rationale>
+
+ </tp:docstring>
+ <tp:added version="0.17.2"/>
+ <tp:changed version="0.17.6">moved the Avatar property to a separate
+ interface</tp:changed>
+
+ <!-- Missing functionality compared with NMC 4.x account + profile,
+ apart from as listed above:
+
+ * vCard field, + default profile for each vCard field
+ (vCard field is per protocol and should be chosen by the
+ Telepathy <-> address-book bridge?; default profile is now
+ meaningless)
+
+ * "normalized name" (normalized handle?)
+
+ * branding icon (what's this and how does it differ from the icon?)
+
+ * configuration UI (not our problem - perhaps the UI could special-case
+ by cm,protocol,preset tuples?)
+
+ * default account domain (somewhat meaningless in general; specialized
+ account config UI can hard-code this)
+
+ * SPLIT_ACCOUNT (pseudo-capability - this is a property of the protocol,
+ not the profile, and in any case only the account config UI cares)
+
+ Missing functionality compared with Decibel accounts:
+
+ * we don't really know, they take arbitrary key/value pairs...
+ but display name, protocol, presence/message, current, autoreconnect
+ are the ones given special status by the source, and we have all of them
+ -->
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read">
+ <tp:docstring>
+ A list of the extra interfaces provided by this account.
+ </tp:docstring>
+ </property>
+
+ <method name="Remove" tp:name-for-bindings="Remove">
+ <tp:docstring>Delete the account.</tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="Removed" tp:name-for-bindings="Removed">
+ <tp:docstring>
+ This account has been removed.
+
+ <tp:rationale>
+ This is redundant with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.AccountManager">AccountRemoved</tp:dbus-ref>,
+ but it's still worth having,
+ to avoid having to bind to AccountManager.AccountRemoved to tell
+ you whether your Account is valid — ideally, an account-editing UI
+ should only care about a single Account.
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+
+ <signal name="AccountPropertyChanged"
+ tp:name-for-bindings="Account_Property_Changed">
+ <tp:docstring>
+ The values of one or more properties on this interface (that do not
+ specify that this signal does not apply to them) may have changed.
+ This does not cover properties of other interfaces, which must
+ provide their own change notification if appropriate.
+ </tp:docstring>
+
+ <arg name="Properties" type="a{sv}">
+ <tp:docstring>
+ A map from property names in this namespace (e.g.
+ <tp:member-ref>Nickname</tp:member-ref>) to
+ values. Properties whose values have not changed SHOULD be
+ omitted, but this need not be done.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="DisplayName" type="s" access="readwrite"
+ tp:name-for-bindings="Display_Name">
+ <tp:docstring>
+ The user-visible name of this account. This SHOULD be chosen by the
+ user at account creation time. The account creation user interface
+ is responsible for setting a reasonable default value in the user's
+ locale; something like "Jabber (bob@example.com)" would be sensible.
+ </tp:docstring>
+ </property>
+
+ <property name="Icon" tp:name-for-bindings="Icon"
+ type="s" access="readwrite">
+ <tp:docstring>
+ The name of an icon in the system's icon theme, such as "im-msn",
+ or the empty string to not specify an icon. If the icon is set to
+ an empty string, the account manager or any client MAY derive a
+ default icon, for instance from the protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="Valid" tp:name-for-bindings="Valid"
+ type="b" access="read">
+ <tp:docstring>
+ If true, this account is considered by the account manager to be
+ complete and usable. If false, user action is required to make it
+ usable, and it will never attempt to connect (for instance, this
+ might be caused by the absence of a required parameter).
+
+ <tp:rationale>
+ For connection managers with a plugin architecture, like
+ telepathy-haze, we have little or no control over the parameters
+ offered; for platforms with package management, we have little or
+ no control over the CMs offered. NMC 4.x would just pretend the
+ account didn't exist in these circumstances, but silent data loss
+ is bad, and UIs with CM-specific knowledge (or a user filling in
+ newly-required parameters) might be able to rescue a broken account.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Enabled" tp:name-for-bindings="Enabled"
+ type="b" access="readwrite">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This property gives the users the possibility to prevent an account
+ from being used. This flag does not change the validity of the
+ account.</p>
+
+ <p>A disabled account can never be put online.</p>
+
+ <tp:rationale>
+ <p>Use cases:</p>
+
+ <ul>
+ <li>user has two or more accounts capable of calling contact X, but
+ he doesn't want the UI to prompt him everytime about which one he
+ wants to use for the call. He can then disable all the equivalent
+ accounts but one.</li>
+
+ <li>There is some temporary server error and the user doesn't want
+ to be be bother by error messages, or change the account
+ configuration: temporarily disabling the account is quicker.</li>
+ </ul>
+ </tp:rationale>
+
+ <p>The AccountManager SHOULD allow this property to be set on invalid
+ accounts, but MUST NOT attempt to put invalid accounts online
+ even if they become Enabled.</p>
+
+ <tp:rationale>
+ <p>There doesn't seem to be any good reason not to allow this.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Nickname" tp:name-for-bindings="Nickname"
+ type="s" access="readwrite">
+ <tp:docstring>
+ The nickname to set on this account for display to other contacts,
+ as set by the user. When the account becomes connected, the
+ account manager SHOULD set this as the user's alias using <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Aliasing">SetAliases</tp:dbus-ref>
+ if appropriate.
+
+ <tp:rationale>
+ In a later specification revision, we plan to separate the concepts
+ of a contact's nickname as set by themselves, and the local
+ name for them in our contact list (a "handle" or "pet name" as
+ described in XEP-0165 and its references). The terminology change
+ from alias to nickname here is a step in that direction.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Service" tp:name-for-bindings="Service" type="s"
+ access="readwrite">
+ <tp:added version="0.19.8"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Some protocols, like XMPP and SIP, are used by various different
+ user-recognised brands, such as <i>Google Talk</i> and <i>Ovi by
+ Nokia</i>. On accounts for such services, this property SHOULD be
+ set to a string describing the service, which MUST consist only of
+ ASCII letters, numbers and hyphen/minus signs, and start with a
+ letter (matching the requirements for <tp:type>Protocol</tp:type>).
+ For the <tt>jabber</tt> protocol, one of the following service names
+ should be used if possible:</p>
+
+ <ul>
+ <li><tt>google-talk</tt> (for <a
+ href="http://www.google.com/talk/">Google's IM service</a>)</li>
+ <li><tt>ovi-chat</tt> (for <a href="http://www.ovi.com/">Ovi</a>'s IM
+ service)</li>
+ <li><tt>facebook</tt> (for <a
+ href="http://www.facebook.com/sitetour/chat.php">Facebook's IM
+ service</a>)</li>
+ <li><tt>lj-talk</tt> (for <a
+ href="http://www.livejournal.com/chat/">LiveJournal's IM
+ service</a>)</li>
+ <li><tt>windows-live</tt> (for <a
+ href="http://live.com">Windows Live Messenger IM service</a>)</li>
+
+ </ul>
+
+ <p>The <tp:member-ref>Icon</tp:member-ref> property SHOULD be set to a
+ corresponding brand-specific icon name, if possible. In the future,
+ this property may be used as an index into additional
+ service-specific customizations. If this property is the empty string
+ (or missing), the service is determined by the protocol name (either
+ because this is a single-service protocol like <tt>msn</tt>, or
+ because this is just a generic <tt>jabber</tt> or <tt>sip</tt>
+ account without specific branding).</p>
+
+ <p>This property MAY be set, if appropriate, when calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.AccountManager"
+ >CreateAccount</tp:dbus-ref>. Updating this property will fail on
+ externally-stored accounts whose <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account.Interface.Storage"
+ >StorageRestrictions</tp:dbus-ref> include
+ <code>Cannot_Set_Service</code>.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Parameters" tp:name-for-bindings="Parameters"
+ type="a{sv}" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from connection manager parameter names (as in the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ConnectionManager</tp:dbus-ref>
+ interface) to their values. This property includes
+ only those parameters that are stored for this account, and SHOULD
+ only include those parameters that the user has explicitly set.
+ </p>
+ <p>This property cannot be altered using
+ <code>org.freedesktop.DBus.Properties.Set()</code>; use
+ <tp:member-ref>UpdateParameters</tp:member-ref> instead.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="UpdateParameters" tp:name-for-bindings="Update_Parameters">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Change the value of the <tp:member-ref>Parameters</tp:member-ref>
+ property.</p>
+
+ <p>If any of the <var>Set</var> parameters’
+ <tp:type>Conn_Mgr_Param_Flags</tp:type> include
+ <code>DBus_Property</code>, the change will be applied immediately to
+ the corresponding D-Bus Property on the active
+ <tp:member-ref>Connection</tp:member-ref>, if there is one. If any of
+ the <var>Unset</var> parameters’
+ <tp:type>Conn_Mgr_Param_Flags</tp:type> include both
+ <code>DBus_Property</code> and <code>Has_Default</code>, the
+ corresponding D-Bus Property on the connection will be set to the
+ default value. Changes to other parameters will not take effect
+ until the next time the account is disconnected and reconnected. (If
+ parameters are explicitly set to their default value, or are unset
+ when previously set to their default value, the account manager MAY
+ decide that no reconnection is necessary to make the change take
+ effect.)</p>
+
+ <tp:rationale>
+ <p>In general, reconnecting is a destructive operation that shouldn't
+ happen as a side-effect. In particular, migration tools that
+ twiddle the settings of all accounts shouldn't cause an automatic
+ disconnect and reconnect.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:changed version="0.17.16">
+ parameters which are also D-Bus properties can and should be updated on
+ existing Connections
+ </tp:changed>
+
+ <tp:changed version="0.17.24">
+ return an array of the parameters that won't change until the account
+ is reconnected
+ </tp:changed>
+
+ <arg name="Set" type="a{sv}" direction="in">
+ <tp:docstring>
+ A mapping from parameter names to their values. These parameters
+ should be stored for future use.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Unset" type="as" direction="in">
+ <tp:docstring>
+ A list of the names of parameters to be removed from the set of
+ stored values, allowing the default values to be used.
+ If the given parameters were not, in fact, stored, or even if they
+ do not exist at all, the account manager MUST accept this without
+ error.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Reconnect_Required" type="as" direction="out">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If all of the updates could be applied to the active
+ <tp:member-ref>Connection</tp:member-ref> (if any),
+ the empty list, signifying that no reconnection is required for the
+ new parameters to take effect. For example, if the only parameter
+ updated is <tt>...Cellular.<tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Cellular">MessageValidityPeriod</tp:dbus-ref></tt>,
+ the new value can be applied immediately to the connection.</p>
+
+ <p>Otherwise, a list of the names of parameters with changes that
+ will not take effect until the account is reconnected. User
+ interfaces that require "instant apply" semantics MAY call
+ <tp:member-ref>Reconnect</tp:member-ref> in response to receiving a
+ non-empty list. For example, if the caller updates both
+ <tt>...Anonymity.<tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Anonymity">AnonymityMandatory</tp:dbus-ref></tt>
+ and <tt>require-encryption</tt>, the former can be applied to the
+ current connection, but the latter needs a reconnect to take
+ effect, so this method should return
+ <code>["require-encryption"]</code>.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="AutomaticPresence" type="(uss)" access="readwrite"
+ tp:type="Simple_Presence" tp:name-for-bindings="Automatic_Presence">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The presence status that this account should have if it is brought
+ online.</p>
+
+ <tp:rationale>
+ In ITOS2007 and ITOS2008 this is a global preference, not visible
+ on D-Bus (the "default presence"). "Automatic presence" better
+ describes when it is used.
+ </tp:rationale>
+
+ <p>Setting this property MUST NOT actually change the account's
+ status until the next time it is (re)connected for some reason.</p>
+
+ <p>The value of this property MUST be one that would be acceptable
+ for <tp:member-ref>RequestedPresence</tp:member-ref>,
+ with the additional restriction that the
+ <tp:type>Connection_Presence_Type</tp:type> MUST NOT be Offline.</p>
+
+ <tp:rationale>
+ <p>Otherwise, it would not be possible to use this presence to bring
+ the account online for a channel request.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectAutomatically" type="b" access="readwrite"
+ tp:name-for-bindings="Connect_Automatically">
+ <tp:docstring>
+ If true, the account manager SHOULD attempt to put this account
+ online with the <tp:member-ref>AutomaticPresence</tp:member-ref>
+ whenever possible (in the base
+ Account interface this is deliberately left vague). If false,
+ it MUST NOT put the account online automatically in response to,
+ for instance, connectivity changes, but SHOULD still put the account
+ online with the <tp:member-ref>AutomaticPresence</tp:member-ref> if
+ requested by the user (for
+ instance, if the user tries to start a conversation using this
+ account).
+ </tp:docstring>
+ </property>
+
+ <property name="Connection" tp:name-for-bindings="Connection"
+ type="o" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the object path of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref> to
+ this account, or the special value <code>'/'</code> if there is no
+ connection.</p>
+
+ <p>If this object path is not '/', the Connection's well-known bus
+ name can be derived from this object path by removing the first '/'
+ and replacing subsequent '/' characters with '.'.</p>
+
+ <tp:rationale>
+ Object paths aren't nullable, so we can't use an empty string.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectionStatus" type="u" tp:type="Connection_Status"
+ access="read" tp:name-for-bindings="Connection_Status">
+ <tp:docstring>
+ If the <tp:member-ref>Connection</tp:member-ref> property is non-empty,
+ the status of that connection.
+ If the Connection property is the empty string, this property may
+ either be Disconnected (indicating that the account manager is not
+ attempting to bring it online), or Connecting (indicating that the
+ account manager is attempting to connect).
+ The account manager is expected to set this by observing signals
+ from the Connection.
+
+ <tp:rationale>
+ If the AM is doing some sort of backoff/delay on reconnection
+ attempts, the account's status is conceptually "Connecting" even
+ though there is no Connection.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectionStatusReason" type="u"
+ tp:type="Connection_Status_Reason" access="read"
+ tp:name-for-bindings="Connection_Status_Reason">
+ <tp:docstring>
+ The reason for the last change to
+ <tp:member-ref>ConnectionStatus</tp:member-ref>.
+ The account manager is expected to set this by observing signals
+ from the Connection.
+
+ <tp:rationale>
+ If you weren't watching the Connection at the time it failed,
+ you can't tell why - unless the AM can tell you.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectionError" tp:name-for-bindings="Connection_Error"
+ access="read" type="s" tp:type="DBus_Error_Name">
+ <tp:added version="0.19.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If the last connection to this account failed with an error,
+ the D-Bus error name of that error; otherwise, the empty string.
+ The account manager is expected to set this by observing the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.ConnectionError</tp:dbus-ref> and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.StatusChanged</tp:dbus-ref>
+ signals.</p>
+
+ <p>If ConnectionError is received before the connection disconnects,
+ its first argument should be used to set this property;
+ otherwise, the Reason argument of StatusChanged should be converted
+ to a suitable D-Bus error name.</p>
+
+ <p>Whenever the Connection connects successfully, this property should
+ be reset to the empty string.</p>
+
+ <tp:rationale>
+ <p>This combines the state-recoverability of
+ <tp:member-ref>ConnectionStatusReason</tp:member-ref> with the
+ extensibility of Connection.ConnectionError.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectionErrorDetails"
+ tp:name-for-bindings="Connection_Error_Details"
+ access="read" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:added version="0.19.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If the last connection to this account failed with an error,
+ a mapping representing any additional information about the last
+ disconnection; otherwise, the empty map. The keys and values are
+ the same as for the second argument of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.ConnectionError</tp:dbus-ref>.</p>
+
+ <p>Whenever the Connection connects successfully, this property should
+ be reset to the empty map.</p>
+
+ <tp:rationale>
+ <p>This combines the state-recoverability of
+ <tp:member-ref>ConnectionStatusReason</tp:member-ref> with the
+ extensibility of Connection.ConnectionError.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="CurrentPresence" type="(uss)" access="read"
+ tp:type="Simple_Presence" tp:name-for-bindings="Current_Presence">
+ <tp:docstring>
+ The actual presence. If the connection is not online, the
+ <tp:type>Connection_Presence_Type</tp:type> SHOULD be
+ Connection_Presence_Type_Offline.
+ If the connection is online but does not support the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">SimplePresence</tp:dbus-ref>
+ interface, the type SHOULD be Connection_Presence_Type_Unset.
+ The account manager is expected to set this by observing signals
+ from the Connection.
+ </tp:docstring>
+ </property>
+
+ <property name="RequestedPresence" type="(uss)" access="readwrite"
+ tp:type="Simple_Presence" tp:name-for-bindings="Requested_Presence">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The requested presence for this account. When this is changed, the
+ account manager should attempt to manipulate the connection manager to
+ make <tp:member-ref>CurrentPresence</tp:member-ref> match
+ <tp:member-ref>RequestedPresence</tp:member-ref> as closely as
+ possible. It should not be saved to any sort of persistent
+ storage.</p>
+
+ <p>When the account manager automatically connects an account,
+ it must signal this by setting the RequestedPresence to the same
+ thing as the <tp:member-ref>AutomaticPresence</tp:member-ref>.</p>
+
+ <p>The <tp:type>Connection_Presence_Type</tp:type> in this property
+ MUST NOT be Unset, Unknown or Error.</p>
+
+ <tp:rationale>
+ <p>Requesting those presence types doesn't make sense.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ChangingPresence" tp:name-for-bindings="Changing_Presence"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, a change to the presence of this account is
+ in progress.</p>
+
+ <p>Whenever <tp:member-ref>RequestedPresence</tp:member-ref> is set on
+ an account that could go online, or whenever an account with a
+ non-offline <tp:member-ref>RequestedPresence</tp:member-ref> becomes
+ able to go online (for instance because
+ <tp:member-ref>Enabled</tp:member-ref> or
+ <tp:member-ref>Valid</tp:member-ref> changes to True),
+ ChangingPresence MUST change to True, and the two property changes MUST
+ be emitted in the same
+ <tp:member-ref>AccountPropertyChanged</tp:member-ref> signal, before the
+ Set method returns.</p>
+
+ <p>When the account manager succeeds or fails in changing the presence,
+ or the connection disconnects due to an error, ChangingPresence MUST
+ change to False as part of the same
+ <tp:member-ref>AccountPropertyChanged</tp:member-ref> signal.</p>
+
+ <tp:rationale>
+ <p>This allows UIs to indicate that a presence change is in progress
+ or has finished, even if the change was initiated by a different
+ UI.</p>
+
+ <p>For instance, Maemo 5 and Empathy indicate a presence change by
+ having the presence indicator alternate between the
+ <tp:member-ref>RequestedPresence</tp:member-ref>
+ and the <tp:member-ref>CurrentPresence</tp:member-ref>; they should
+ start blinking when ChangingPresence becomes true, and stop when it
+ becomes false.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </property>
+
+ <method name="Reconnect" tp:name-for-bindings="Reconnect">
+ <tp:added version="0.17.24"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Re-connect this account. If the account is currently disconnected
+ and the requested presence is offline, or if the account
+ is not <tp:member-ref>Enabled</tp:member-ref> or not
+ <tp:member-ref>Valid</tp:member-ref>, this does nothing.</p>
+
+ <p>If the account is disconnected and the requested presence is not
+ offline, this forces an attempt to connect with the requested
+ presence immediately.</p>
+
+ <p>If the account is connecting or connected, this is equivalent to
+ remembering the current value of
+ <tp:member-ref>RequestedPresence</tp:member-ref>, setting its value
+ to (OFFLINE, "offline", ""), waiting for the change to take effect,
+ then setting its value to the value that was previously
+ remembered.</p>
+
+ <tp:rationale>
+ <p>Clients desiring "instant apply" semantics for CM parameters MAY
+ call this method to achieve that.</p>
+ </tp:rationale>
+
+ <p>In particular, if the account's
+ <tp:member-ref>Connection</tp:member-ref> is in the Connecting
+ state, calling this method causes the attempt to connect to be
+ aborted and re-tried.</p>
+
+ <tp:rationale>
+ <p>This is necessary to ensure that the new parameters are
+ picked up.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <property name="NormalizedName" type="s" access="read"
+ tp:name-for-bindings="Normalized_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The normalized user ID of the local user on this account (i.e. the
+ string returned when the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>
+ method is called on the
+ result of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">GetSelfHandle</tp:dbus-ref>
+ for an active connection).</p>
+
+ <p>It is unspecified whether this user ID is globally unique.</p>
+
+ <tp:rationale>
+ <p>As currently implemented, IRC user IDs are only unique within
+ the same IRCnet. On some saner protocols, the user ID includes a
+ DNS name which provides global uniqueness.</p>
+ </tp:rationale>
+
+ <p>If this value is not known yet (which will always be the case for
+ accounts that have never been online), it will be an empty
+ string.</p>
+
+ <p>It is possible that this value will change if the connection
+ manager's normalization algorithm changes, although this SHOULD
+ be avoided.</p>
+
+ <tp:rationale>
+ <p>It's not always completely clear what normalization algorithm
+ should be used; for instance, in Gabble, we currently use JIDs,
+ but it would also have been reasonable to use xmpp URIs.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="HasBeenOnline" tp:name-for-bindings="Has_Been_Online"
+ type="b" access="read">
+ <tp:docstring>
+ If true, this account has successfully been put online at some point
+ in the past.
+
+ <tp:rationale>
+ UIs could apply a policy that the 'account' parameter can only be
+ edited in accounts that have never been online, or that
+ ConnectAutomatically cannot be set on such accounts. The account
+ manager should not enforce such policies, but it can expose enough
+ information to UIs that the UI can decide what to do.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Account_Interface_Addressing.xml b/spec/spec/Account_Interface_Addressing.xml
new file mode 100644
index 000000000..4b2846b68
--- /dev/null
+++ b/spec/spec/Account_Interface_Addressing.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_Addressing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Ltd</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Account.Interface.Addressing">
+ <tp:requires interface="org.freedesktop.Telepathy.Account"/>
+ <tp:added version="0.21.5">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Some accounts can be used for multiple protocols; for instance, SIP
+ and Skype accounts can often be used to contact the PSTN, MSN and
+ Yahoo accounts can contact each other, and XMPP accounts can
+ potentially contact many protocols via a transport.</p>
+ <p>However, if the user does not intend to make use of this functionality,
+ user interfaces can improve clarity by not displaying it: for instance,
+ if a user prefers to call phone numbers via a particular SIP account,
+ when an address book displays a contact with a phone number, it is
+ desirable to display a "call with SIP" button for that account, but
+ avoid displaying similar buttons for any other configured SIP or
+ Skype accounts.</p>
+ <p>The purpose of this interface is to allow this "for use with" information
+ to be recorded and retrieved.</p>
+ </tp:docstring>
+
+ <property name="URISchemes" type="as" access="read"
+ tp:name-for-bindings="URI_Schemes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of fields indicating the type of URI addressing scheme
+ the the account should be used for (eg 'tel') indicating the
+ account is intended for use by applications offering a telephony
+ UI, or 'sip' or 'xmpp' for those protocols</p>
+ <p>Note that these fields signify intent, not ability: It is
+ entirely possible that an account which can be used for a
+ given URI scheme is not wanted for it by the user, and
+ therefore not flagged as such in this field.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="SetURISchemeAssociation"
+ tp:name-for-bindings="Set_URI_Scheme_Association">
+ <tp:docstring>
+ <p>Associate (or disassociate) an account with a particular
+ URI addressing scheme, (such as 'tel' for telephony)</p>
+ </tp:docstring>
+
+ <arg name="URI_Scheme" direction="in" type="s">
+ <tp:docstring>
+ <p>URI scheme to associate/disassociate the account with/from</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Association" direction="in" type="b">
+ <tp:docstring>
+ <p>True to associate this account with a given addressing scheme</p>
+ <p>False if the account should not be associated with said scheme</p>
+ </tp:docstring>
+ </arg>
+
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Account_Interface_Avatar.xml b/spec/spec/Account_Interface_Avatar.xml
new file mode 100644
index 000000000..a6c516727
--- /dev/null
+++ b/spec/spec/Account_Interface_Avatar.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_Avatar"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Account.Interface.Avatar">
+ <tp:requires interface="org.freedesktop.Telepathy.Account"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface extends the core Account interface to provide a
+ user-settable avatar image.</p>
+
+ <tp:rationale>
+ <p>The avatar could have been a property on the core Account interface,
+ but was moved to a separate interface because it is likely to be
+ large. This means that clients can safely use GetAll to get
+ properties on the core Account interface without flooding the
+ session bus with large images.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ <tp:added version="0.17.6"/>
+
+ <tp:struct name="Avatar">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A struct containing avatar data marked with its MIME type.</p>
+
+ <p>May be set to an empty byte-array and an empty string, indicating
+ no avatar.</p>
+ </tp:docstring>
+ <tp:member type="ay" name="Avatar_Data"/>
+ <tp:member type="s" name="MIME_Type"/>
+ </tp:struct>
+
+ <property name="Avatar" tp:name-for-bindings="Avatar"
+ type="(ays)" tp:type="Avatar" access="readwrite">
+ <tp:docstring>
+ The avatar to set on this account for display to other contacts,
+ represented as a structure containing the bytes of the avatar,
+ and the MIME type as a string; may be set to an empty byte-array and
+ an empty string to indicate no avatar. When the account becomes
+ connected, the account manager SHOULD set this avatar using SetAvatar
+ if appropriate.
+ </tp:docstring>
+ </property>
+
+ <signal name="AvatarChanged" tp:name-for-bindings="Avatar_Changed">
+ <tp:docstring>
+ Emitted when the Avatar property changes.
+
+ <tp:rationale>The avatar itself is deliberately not included in this
+ signal, to reduce bus traffic in the (likely common) case where no
+ running application cares about the user's own avatar.</tp:rationale>
+ </tp:docstring>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Account_Interface_External_Password_Storage.xml b/spec/spec/Account_Interface_External_Password_Storage.xml
new file mode 100644
index 000000000..5bd1bfce0
--- /dev/null
+++ b/spec/spec/Account_Interface_External_Password_Storage.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_External_Password_Storage"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Account.Interface.ExternalPasswordStorage.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.10">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Account"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for Accounts whose passwords are stored externally and
+ SHOULD NOT be stored by either the
+ <tp:dbus-ref namespace="ofdT">AccountManager</tp:dbus-ref> nor any
+ <tp:dbus-ref namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ handler.</p>
+
+ <p>This interface SHOULD only appear on accounts for which the
+ related Connection Manager implements
+ <tp:dbus-ref namespace="ofdT">ConnectionManager.Interface.AccountStorage.DRAFT</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <method name="ForgetPassword" tp:name-for-bindings="Forget_Password">
+ <tp:docstring>
+ Clears any saved password associated with this account.
+ </tp:docstring>
+ </method>
+
+ <property name="PasswordSaved"
+ tp:name-for-bindings="Password_Saved"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Indicates whether the account has a saved password or not.</p>
+
+ <p>Change notification for this property is provided by the
+ standard D-Bus <code>PropertiesChanged</code> signal.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
diff --git a/spec/spec/Account_Interface_Hidden.xml b/spec/spec/Account_Interface_Hidden.xml
new file mode 100644
index 000000000..cb0019178
--- /dev/null
+++ b/spec/spec/Account_Interface_Hidden.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_Hidden"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Account.Interface.Hidden.DRAFT1"
+ tp:causes-havoc="outrageous">
+ <tp:added version="0.21.10">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for flagging certain accounts as hidden, so that they do
+ not appear in the account manager's standard lists of accounts.
+ Accounts whose <tp:member-ref>Hidden</tp:member-ref> property is
+ <code>True</code> are intended for non-interactive use (by
+ non-user-visible services), and appear on the <tp:dbus-ref
+ namespace='ofdT'>AccountManager.Interface.Hidden.DRAFT1</tp:dbus-ref>
+ interface; in all other respects, they behave like any other
+ account.</p>
+
+ <tp:rationale>
+ <p>XMPP, in particular, is increasingly used for purposes other than
+ instant messaging and VoIP. For instance, extensions exist for
+ inter-device bookmark synchronization.</p>
+
+ <p>While obviously these services could re-use connections intended for
+ instant messaging, in some cases you might want to use a different
+ account. (Perhaps your bookmark sync provider is not your IM
+ provider.) This API allows such auxiliary accounts to exist in
+ Telepathy, while not being displayed in standard user interfaces for
+ IM, VoIP, and friends.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <property name="Hidden" tp:name-for-bindings="Hidden"
+ type="b" access="read" tp:immutable='aye'>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <code>True</code>, this account is intended for non-interactive
+ use, and thus should not be presented to the user. It will not appear
+ in properties and signals on the main <tp:dbus-ref
+ namespace='ofdT'>AccountManager</tp:dbus-ref> interface; instead, it
+ will show up on <tp:dbus-ref
+ namespace='ofdT'>AccountManager.Interface.Hidden.DRAFT1</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Account_Interface_Storage.xml b/spec/spec/Account_Interface_Storage.xml
new file mode 100644
index 000000000..4e3ba5dca
--- /dev/null
+++ b/spec/spec/Account_Interface_Storage.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_Storage"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Account.Interface.Storage">
+ <tp:requires interface="org.freedesktop.Telepathy.Account"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ This interface extends the core Account interface to specify details
+ regarding the storage of this account.
+ </p>
+
+ <tp:rationale>
+ <p>
+ Single-sign-on systems do not generally have directly user-editable
+ properties for Accounts, and require the user to visit a specific UI
+ to alter their account properties. User interfaces should know not to
+ expose these account properties as user-editable, and instead
+ redirect the user to the appropriate interface.
+ </p>
+ </tp:rationale>
+
+ </tp:docstring>
+ <tp:added version="0.19.8"/>
+
+ <property name="StorageProvider" tp:name-for-bindings="Storage_Provider"
+ type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The name of the account storage implementation, which SHOULD start
+ with a reversed domain name in the same way as D-Bus interface names.
+ When this is the empty string the account is internally stored.
+ </p>
+ <p>
+ This property cannot change once an Account has been created.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <property name="StorageIdentifier"
+ tp:name-for-bindings="Storage_Identifier" type="v" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Unique identification of the account within the storage backend.
+ The contents of the variant are defined by the
+ <tp:member-ref>StorageProvider</tp:member-ref>.
+ </p>
+ <p>
+ This property cannot change once an Account has been created.
+ </p>
+ <tp:rationale>
+ <p>
+ Different storage systems will have their own way of uniquely
+ identifying an account, typically an integer or a string.
+ Given that all users of this property should have direct knowledge
+ of the backend they should know what types to expect and how to
+ handle it.
+ </p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="StorageSpecificInformation"
+ tp:name-for-bindings="Storage_Specific_Information" type="a{sv}"
+ access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Map containing information specific to the storage backend. The keys
+ and the types of their values are defined by the
+ <tp:member-ref>StorageProvider</tp:member-ref>, and are not
+ interpreted by the AccountManager implementation.
+ </p>
+ <p>
+ As the values in this map may change at any time (due to an external
+ application manipulating the storage provider directly), this
+ property should not be cached; it should instead be retrieved each
+ time it is needed.
+ </p>
+
+ <tp:rationale>
+ <p>
+ This can be used to provide additional hints to user interfaces
+ aware of a specific storage provider, without requiring those user
+ interfaces to use the
+ <tp:member-ref>StorageIdentifier</tp:member-ref> to query the
+ storage provider directly.
+ </p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="StorageRestrictions"
+ tp:name-for-bindings="Storage_Restrictions" type="u"
+ tp:type="Storage_Restriction_Flags"
+ access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Bitfield which defines what restrictions this Storage method has.
+ </p>
+ <p>
+ This property cannot change once an Account has been created.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Storage_Restriction_Flags"
+ value-prefix="Storage_Restriction_Flag" type="u">
+ <tp:docstring>
+ Flags indicating restrictions imposed on an Account by its storage
+ method.
+ </tp:docstring>
+
+ <tp:flag suffix="Cannot_Set_Parameters" value="1">
+ <tp:docstring>
+ The account's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account"
+ >Parameters</tp:dbus-ref> property can't be changed by calling
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Account"
+ >UpdateParameters</tp:dbus-ref>.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Cannot_Set_Enabled" value="2">
+ <tp:docstring>
+ The account can't be enabled/disabled by setting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account"
+ >Enabled</tp:dbus-ref> property.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Cannot_Set_Presence" value="4">
+ <tp:docstring>
+ The account's presence can't be changed by setting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account"
+ >RequestedPresence</tp:dbus-ref> and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account"
+ >AutomaticPresence</tp:dbus-ref> properties.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Cannot_Set_Service" value="8">
+ <tp:docstring>
+ The account's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Service</tp:dbus-ref>
+ property cannot be changed.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Account_Manager.xml b/spec/spec/Account_Manager.xml
new file mode 100644
index 000000000..52cd42a1e
--- /dev/null
+++ b/spec/spec/Account_Manager.xml
@@ -0,0 +1,288 @@
+<?xml version="1.0" ?>
+<node name="/Account_Manager"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.AccountManager">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The account manager is a central service used to store account
+ details.</p>
+
+ <p>The current account manager is defined to be the process that owns
+ the well-known bus name <tt>org.freedesktop.Telepathy.AccountManager</tt> on
+ the session bus. This process must export an
+ <tt>/org/freedesktop/Telepathy/AccountManager</tt> object with the
+ AccountManager interface.</p>
+ </tp:docstring>
+ <tp:added version="0.17.2"/>
+
+ <!-- Missing functionality compared with NMC 4.x:
+ * look up accounts by conditions (can be done client-side, less
+ efficiently, so not a blocker)
+ * global presence/... changes (can be done client-side, less efficiently -
+ we should add this)
+ * count used channels (what's this for?)
+ * get "average" status (not well-defined, UIs can do this)
+ * request channels (out of scope: Channel Dispatcher will do this)
+ * register filters (completely out of scope: Channel Dispatcher again)
+ -->
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read">
+ <tp:docstring>
+ A list of the interfaces provided by the account manager object.
+ </tp:docstring>
+ </property>
+
+ <property name="ValidAccounts" type="ao" access="read"
+ tp:name-for-bindings="Valid_Accounts">
+ <tp:docstring>
+ A list of the valid (complete, usable) <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>s. Change
+ notification is via
+ <tp:member-ref>AccountValidityChanged</tp:member-ref>.
+
+ <tp:rationale>
+ This split between valid and invalid accounts makes it easy to
+ ignore the invalid ones. The only things that should be manipulating
+ invalid accounts are account-editing UIs, which might be able to
+ rescue them.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InvalidAccounts" type="ao" access="read"
+ tp:name-for-bindings="Invalid_Accounts">
+ <tp:docstring>
+ A list of incomplete or otherwise unusable <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>s. Change
+ notification is via
+ <tp:member-ref>AccountValidityChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <signal name="AccountRemoved" tp:name-for-bindings="Account_Removed">
+ <tp:docstring>
+ The given account has been removed.
+
+ <tp:rationale>
+ This is effectively change notification for the valid and invalid
+ accounts lists. On emission of this signal, the Account indicated
+ will no longer be present in either of the lists.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Account" type="o">
+ <tp:docstring>
+ An Account, which must not be used any more.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="AccountValidityChanged"
+ tp:name-for-bindings="Account_Validity_Changed">
+ <tp:docstring>
+ The validity of the given account has changed. New accounts are
+ also indicated by this signal, as an account validity change
+ (usually to True) on an account that did not previously exist.
+
+ <tp:rationale>
+ This is effectively change notification for the valid and invalid
+ accounts lists.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Account" type="o">
+ <tp:docstring>
+ An <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Valid" type="b">
+ <tp:docstring>
+ True if the account is now valid.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="SupportedAccountProperties"
+ tp:name-for-bindings="Supported_Account_Properties"
+ type="as" tp:type="DBus_Qualified_Member[]" access="read">
+ <tp:added version="0.17.24"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of the fully qualified names of properties that can be set
+ via the Properties argument to
+ <tp:member-ref>CreateAccount</tp:member-ref> when an account is
+ created.</p>
+
+ <tp:rationale>
+ <p>Examples of good properties to support here include
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Icon</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Enabled</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Nickname</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">AutomaticPresence</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">ConnectAutomatically</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">RequestedPresence</tp:dbus-ref>
+ and
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account.Interface.Avatar">Avatar</tp:dbus-ref>.
+ </p>
+
+ <p>Examples of properties that would make no sense here include
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Valid</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Connection</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">ConnectionStatus</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">ConnectionStatusReason</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">CurrentPresence</tp:dbus-ref>
+ and
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">NormalizedName</tp:dbus-ref>.
+ </p>
+ </tp:rationale>
+
+ <p>This property MUST NOT include include the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">DisplayName</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Parameters</tp:dbus-ref>
+ properties, which are set using separate arguments.</p>
+
+ <p>This property MAY include the names of properties that, after
+ account creation, will be read-only: this indicates that the property
+ can be set at account creation but not changed later.</p>
+
+ <tp:rationale>
+ <p>For example, an account manager might support migration tools that
+ use this to preserve the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">HasBeenOnline</tp:dbus-ref>
+ property, even though that property is usually read-only.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="CreateAccount" tp:name-for-bindings="Create_Account">
+ <tp:docstring>
+ Request the creation of a new <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>. The
+ account manager SHOULD NOT allow invalid accounts to be created.
+ </tp:docstring>
+ <tp:changed version="0.17.24">added the Properties argument</tp:changed>
+
+ <arg name="Connection_Manager" direction="in" type="s"
+ tp:type="Connection_Manager_Name">
+ <tp:docstring>
+ The name of the connection manager, e.g. "salut".
+ </tp:docstring>
+ </arg>
+
+ <arg name="Protocol" direction="in" type="s"
+ tp:type="Protocol">
+ <tp:docstring>The protocol, e.g. "local-xmpp".</tp:docstring>
+ </arg>
+
+ <arg name="Display_Name" direction="in" type="s">
+ <tp:docstring>The initial value of the new account's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">DisplayName</tp:dbus-ref>
+ property. The account manager SHOULD modify this to make it unique if
+ an Account already exists with the same display name, for instance by
+ appending a number or the 'account' parameter. Account manager
+ implementations SHOULD accept an empty string, but account editing
+ user interfaces should avoid passing an empty string for this
+ parameter.
+
+ <tp:rationale>
+ <p>The account creation UI may ask the user for a name for the new
+ account. If the author of the UI chooses not to do this, the
+ account creation UI is better able to suggest a default display
+ name because it has protocol-specific knowledge which the account
+ manager does not.</p>
+
+ <p>The account manager always knows the complete list of accounts so
+ it can easily tell whether it should append something to the
+ display name to avoid presenting two identically-named accounts to
+ the user.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Parameters" direction="in" type="a{sv}">
+ <tp:docstring>Initial parameter values, as would be passed to
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ConnectionManager">RequestConnection</tp:dbus-ref>.</tp:docstring>
+ </arg>
+
+ <arg name="Properties" direction="in" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The values of any other properties to be set immediately on the
+ new Account.</p>
+
+ <p>Only the properties mentioned in
+ <tp:member-ref>SupportedAccountProperties</tp:member-ref> are
+ acceptable here. In particular, the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">DisplayName</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Parameters</tp:dbus-ref>
+ properties are never allowed here, since they are set using the other
+ arguments to this method.</p>
+
+ <p>Account manager implementations SHOULD support creating accounts
+ with an empty value for this argument.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Account" direction="out" type="o">
+ <tp:docstring>The new <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <var>Connection_Manager</var> is not installed or does not
+ implement the given <var>Protocol</var>.</p>
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <var>Parameters</var> provided were unacceptable: they might
+ omit a
+ <tp:value-ref type='Conn_Mgr_Param_Flags'>Required</tp:value-ref>
+ parameter, include an unsupported parameter, or have a value of
+ the wrong type.</p>
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
+
diff --git a/spec/spec/Account_Manager_Interface_Hidden.xml b/spec/spec/Account_Manager_Interface_Hidden.xml
new file mode 100644
index 000000000..284eb6428
--- /dev/null
+++ b/spec/spec/Account_Manager_Interface_Hidden.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" ?>
+<node name="/Account_Manager_Interface_Hidden"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.AccountManager.Interface.Hidden.DRAFT1"
+ tp:causes-havoc='kind of sketchy'>
+ <tp:requires interface='org.freedesktop.Telepathy.AccountManager'/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface lists accounts whose <tp:dbus-ref
+ namespace='ofdT.Account.Interface.Hidden.DRAFT1'>Hidden</tp:dbus-ref>
+ property is <code>True</code>.</p>
+ </tp:docstring>
+ <tp:added version="0.21.10">first draft</tp:added>
+
+ <property name="ValidHiddenAccounts" type="ao" access="read"
+ tp:name-for-bindings="Valid_Hidden_Accounts">
+ <tp:docstring>
+ A list of valid (complete, usable) <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>s intended
+ exclusively for noninteractive applications. These accounts are not
+ included in <tp:dbus-ref
+ namespace='ofdT'>AccountManager.ValidAccounts</tp:dbus-ref>. Change
+ notification is via
+ <tp:member-ref>HiddenAccountValidityChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <property name="InvalidHiddenAccounts" type="ao" access="read"
+ tp:name-for-bindings="Invalid_Hidden_Accounts">
+ <tp:docstring>
+ A list of incomplete or otherwise unusable <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>s intended
+ exclusively for noninteractive applications. Change notification is via
+ <tp:member-ref>HiddenAccountValidityChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <signal name="HiddenAccountRemoved"
+ tp:name-for-bindings="Hidden_Account_Removed">
+ <tp:docstring>
+ The given account has been removed from
+ <tp:member-ref>ValidHiddenAccounts</tp:member-ref> or
+ <tp:member-ref>InvalidHiddenAccounts</tp:member-ref>.
+ </tp:docstring>
+
+ <arg name="Account" type="o">
+ <tp:docstring>
+ An Account, which must not be used any more.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="HiddenAccountValidityChanged"
+ tp:name-for-bindings="Hidden_Account_Validity_Changed">
+ <tp:docstring>
+ The validity of the given account has changed. New magic
+ accounts are also indicated by this signal, as an account validity
+ change (usually to True) on an account that did not previously exist.
+
+ <tp:rationale>
+ This is effectively change notification for the valid and invalid
+ accounts lists.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Account" type="o">
+ <tp:docstring>
+ An <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Valid" type="b">
+ <tp:docstring>
+ True if the account is now valid.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Authentication_TLS_Certificate.xml b/spec/spec/Authentication_TLS_Certificate.xml
new file mode 100644
index 000000000..db1d76fd7
--- /dev/null
+++ b/spec/spec/Authentication_TLS_Certificate.xml
@@ -0,0 +1,305 @@
+<?xml version="1.0" ?>
+<node name="/Authentication_TLS_Certificate" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Limited</tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Authentication.TLSCertificate">
+ <tp:added version="0.19.13">(as stable API)</tp:added>
+
+ <tp:docstring>
+ This object represents a TLS certificate.
+ </tp:docstring>
+
+ <tp:simple-type name="Certificate_Data" array-name="Certificate_Data_List"
+ type="ay">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The raw data contained in a TLS certificate.</p>
+
+ <p>For X.509 certificates (<tp:member-ref>CertificateType</tp:member-ref>
+ = "x509"), this MUST be in DER format, as defined by the
+ <a href="http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf">X.690</a>
+ ITU standard.</p>
+
+ <p>For PGP certificates (<tp:member-ref>CertificateType</tp:member-ref>
+ = "pgp"), this MUST be a binary OpenPGP key as defined by section 11.1
+ of <a href="http://www.rfc-editor.org/rfc/4880.txt">RFC 4880</a>.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:struct name="TLS_Certificate_Rejection" array-name="TLS_Certificate_Rejection_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Struct representing one reason why a TLS certificate was rejected.</p>
+ <p>Since there can be multiple things wrong with a TLS certificate,
+ arrays of this type are used to represent lists of reasons for
+ rejection. In that case, the most important reason SHOULD be placed
+ first in the list.</p>
+ </tp:docstring>
+
+ <tp:member name="Reason" type="u"
+ tp:type="TLS_Certificate_Reject_Reason">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The value of the TLS_Certificate_Reject_Reason enumeration for
+ this certificate rejection.
+ <tp:rationale>
+ Clients that do not understand the <code>Error</code> member,
+ which may be implementation-specific, can use this property to
+ classify rejection reasons into common categories.
+ </tp:rationale>
+ </p>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Error" type="s"
+ tp:type="DBus_Error_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The DBus error name for this certificate rejection.</p>
+ <p>This MAY correspond to the value of the <code>Reason</code> member,
+ or MAY be a more specific D-Bus error name, perhaps implementation-specific.</p>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Details" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about why the certificate was rejected.
+ This MAY also include one or more of the following well-known keys:</p>
+ <p>
+ <dl>
+ <dt>user-requested (b)</dt>
+ <dd>True if the error was due to an user-requested rejection of
+ the certificate; False if there was an unrecoverable error in the
+ verification process.</dd>
+ <dt>expected-hostname (s)</dt>
+ <dd>If the rejection reason is Hostname_Mismatch, the hostname that
+ the server certificate was expected to have.</dd>
+ <dt>certificate-hostname (s)</dt>
+ <dd>If the rejection reason is Hostname_Mismatch, the hostname of
+ the certificate that was presented.
+ <tp:rationale>
+ <p>For instance, if you try to connect to gmail.com but are presented
+ with a TLS certificate issued to evil.example.org, the error details
+ for Hostname_Mismatch MAY include:</p>
+ <pre>
+ {
+ 'expected-hostname': 'gmail.com',
+ 'certificate-hostname': 'evil.example.org',
+ }
+ </pre>
+ </tp:rationale>
+ </dd>
+ <dt>debug-message (s)</dt>
+ <dd>Debugging information on the error, corresponding to the
+ message part of a D-Bus error message, which SHOULD NOT be
+ displayed to users under normal circumstances</dd>
+ </dl>
+ </p>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:enum type="u" name="TLS_Certificate_State">
+ <tp:docstring>
+ The possible states for a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Authentication">TLSCertificate</tp:dbus-ref>
+ object.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Pending" value="0">
+ <tp:docstring>
+ The certificate is currently waiting to be accepted or rejected.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Accepted" value="1">
+ <tp:docstring>
+ The certificate has been verified.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Rejected" value="2">
+ <tp:docstring>
+ The certificate has been rejected.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum type="u" name="TLS_Certificate_Reject_Reason">
+ <tp:docstring>
+ Possible reasons to reject a TLS certificate.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ The certificate has been rejected for another reason
+ not listed in this enumeration.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Untrusted" value="1">
+ <tp:docstring>
+ The certificate is not trusted.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Expired" value="2">
+ <tp:docstring>
+ The certificate is expired.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Not_Activated" value="3">
+ <tp:docstring>
+ The certificate is not active yet.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Fingerprint_Mismatch" value="4">
+ <tp:docstring>
+ The certificate provided does not have the expected
+ fingerprint.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Hostname_Mismatch" value="5">
+ <tp:docstring>
+ The hostname certified does not match the provided one.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Self_Signed" value="6">
+ <tp:docstring>
+ The certificate is self-signed.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Revoked" value="7">
+ <tp:docstring>
+ The certificate has been revoked.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Insecure" value="8">
+ <tp:docstring>
+ The certificate uses an insecure cipher algorithm, or is
+ cryptographically weak.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Limit_Exceeded" value="9">
+ <tp:docstring>
+ The length in bytes of the certificate, or the depth of the
+ certificate chain exceed the limits imposed by the crypto
+ library.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="State" type="u" access="read"
+ tp:type="TLS_Certificate_State"
+ tp:name-for-bindings="State">
+ <tp:docstring>
+ The current state of this certificate.
+ State change notifications happen by means of the
+ <tp:member-ref>Accepted</tp:member-ref> and
+ <tp:member-ref>Rejected</tp:member-ref> signals.
+ </tp:docstring>
+ </property>
+
+ <property name="Rejections" type="a(usa{sv})" access="read"
+ tp:type="TLS_Certificate_Rejection[]" tp:name-for-bindings="Rejections">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If the <tp:member-ref>State</tp:member-ref> is Rejected,
+ an array of <tp:type>TLS_Certificate_Rejection</tp:type>
+ structures containing the reason why the certificate is rejected.</p>
+ <p>If the <tp:member-ref>State</tp:member-ref> is not Rejected,
+ this property is not meaningful, and SHOULD be set to an empty
+ array.</p>
+ <p>The first rejection in the list MAY be assumed to be
+ the most important; if the array contains more than one
+ element, the CM MAY either use the values after the first,
+ or ignore them.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CertificateType" type="s" access="read"
+ tp:name-for-bindings="Certificate_Type">
+ <tp:docstring>
+ The type of this TLS certificate (e.g. 'x509' or 'pgp').
+ <p>This property is immutable</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CertificateChainData" type="aay" access="read"
+ tp:type="Certificate_Data[]" tp:name-for-bindings="Certificate_Chain_Data">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more TLS certificates forming a trust chain, each encoded as
+ specified by <tp:type>Certificate_Data</tp:type>.</p>
+ <p>The first certificate in the chain MUST be the server certificate,
+ followed by the issuer's certificate, followed by the issuer's issuer
+ and so on.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="Accepted"
+ tp:name-for-bindings="Accepted">
+ <tp:docstring>
+ The <tp:member-ref>State</tp:member-ref> of this certificate has changed to Accepted.
+ </tp:docstring>
+ </signal>
+
+ <signal name="Rejected"
+ tp:name-for-bindings="Rejected">
+ <tp:docstring>
+ The <tp:member-ref>State</tp:member-ref> of this certificate has changed to Rejected.
+ </tp:docstring>
+ <arg name="Rejections" type="a(usa{sv})" tp:type="TLS_Certificate_Rejection[]">
+ <tp:docstring>
+ The new value of the <tp:member-ref>Rejections</tp:member-ref> property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="Accept" tp:name-for-bindings="Accept">
+ <tp:docstring>
+ Accepts this certificate, i.e. marks it as verified.
+ </tp:docstring>
+ </method>
+
+ <method name="Reject" tp:name-for-bindings="Reject">
+ <tp:docstring>
+ Rejects this certificate.
+ </tp:docstring>
+ <arg direction="in" type="a(usa{sv})" name="Rejections"
+ tp:type="TLS_Certificate_Rejection[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The new value of the <tp:member-ref>Rejections</tp:member-ref> property.</p>
+ <p>This MUST NOT be an empty array.</p>
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Raised when the method is called on an object whose <tp:member-ref>State</tp:member-ref>
+ is not <code>Pending</code>, or when the provided rejection list is empty.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content.xml b/spec/spec/Call_Content.xml
new file mode 100644
index 000000000..ef08acc3b
--- /dev/null
+++ b/spec/spec/Call_Content.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This object represents one Content inside a <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>. For
+ example, in an audio/video call there would be one audio content
+ and one video content. Each content has one or more <tp:dbus-ref
+ namespace="ofdT.Call1">Stream</tp:dbus-ref> objects which
+ represent the actual transport to one or more remote contacts.</p>
+ <tp:rationale>
+ There are two cases where multiple streams may happen:
+ <ul>
+ <li>Calls with more than two participants, if the protocol does not
+ support multicast, and does not have mixer proxy.</li>
+ <li>With jingle, when calling a contact connected from multiple
+ resources, a stream is created for each resource. Once the remote
+ contact answered from one of its resources, all other streams get
+ removed.</li>
+ </ul>
+ </tp:rationale>
+ <p>For protocols that support muting all streams of a given content
+ separately, this object MAY also implement the <tp:dbus-ref
+ namespace="ofdT.Call1.Interface">Mute</tp:dbus-ref> interface</p>
+ </tp:docstring>
+
+ <method name="Remove" tp:name-for-bindings="Remove">
+ <tp:changed version="0.21.2">previously there were no
+ arguments</tp:changed>
+ <tp:docstring>
+ Remove the content from the call. This will cause
+ <tp:member-ref>Removed</tp:member-ref>((self_handle,
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>, "", "")) to be
+ emitted.
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError" />
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised when a Call doesn't support removing contents
+ (e.g. a Google Talk video call).
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="Removed" tp:name-for-bindings="Removed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the content is removed from the call. This
+ is the same as the <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1.ContentRemoved</tp:dbus-ref>
+ signal.</p>
+ </tp:docstring>
+ </signal>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read" tp:immutable="yes">
+ <tp:added version="0.19.11"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Extra interfaces provided by this content, such as <tp:dbus-ref
+ namespace="ofdT.Call1">Content.Interface.Media</tp:dbus-ref>,
+ <tp:dbus-ref namespace="ofdT.Channel">Interface.Hold</tp:dbus-ref> or
+ <tp:dbus-ref namespace="ofdT.Call1">Interface.Mute</tp:dbus-ref>.
+ This SHOULD NOT include the Content interface itself, and cannot
+ change once the content has been created.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Name" tp:name-for-bindings="Name" type="s" access="read"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the content.</p>
+
+ <tp:rationale>
+ The content name property should be meaningful, so should be
+ given a name which is significant to the user. The name
+ could be the "audio" or "video" string localized, or perhaps
+ include some string identifying the source, such as a webcam
+ identifier.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Type" tp:name-for-bindings="Type"
+ type="u" tp:type="Media_Stream_Type" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The media type of this content.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="Call_Content_Disposition" type="u">
+ <tp:docstring>
+ The disposition of this content, which defines whether to
+ automatically start sending data on the streams when
+ <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">Accept</tp:dbus-ref> is
+ called on the channel.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The content has no specific disposition.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Initial" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The content was initially part of the call. When
+ <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">Accept</tp:dbus-ref>
+ is called on the channel, all streams of this content with
+ <tp:dbus-ref
+ namespace="ofdT.Call1.Stream">LocalSendingState</tp:dbus-ref>
+ set to <tp:value-ref type="Sending_State">Pending_Send</tp:value-ref> will be
+ moved to <tp:value-ref type="Sending_State">Sending</tp:value-ref> as if
+ <tp:dbus-ref
+ namespace="ofdT.Call1.Stream">SetSending</tp:dbus-ref>
+ (True) had been called.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="Disposition" tp:name-for-bindings="Disposition"
+ type="u" tp:type="Call_Content_Disposition" access="read"
+ tp:immutable="yes">
+ <tp:docstring>
+ The disposition of this content.
+ </tp:docstring>
+ </property>
+
+ <signal name="StreamsAdded" tp:name-for-bindings="Streams_Added">
+ <tp:changed version="0.21.2">plural version, renamed from
+ StreamAdded</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when streams are added to a call.</p>
+ </tp:docstring>
+ <arg name="Streams" type="ao">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="ofdT.Call1">Stream</tp:dbus-ref>s which were
+ added.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="StreamsRemoved" tp:name-for-bindings="Streams_Removed">
+ <tp:changed version="0.21.2">plural version, renamed from
+ StreamRemoved</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when streams are removed from a call</p>
+ </tp:docstring>
+ <arg name="Streams" type="ao">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="ofdT.Call1">Stream</tp:dbus-ref>s which were
+ removed.
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ Why the content was removed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Streams" tp:name-for-bindings="Streams"
+ type="ao" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of <tp:dbus-ref namespace="ofdT.Call1"
+ >Stream</tp:dbus-ref> objects that exist in this
+ content.</p>
+
+ <tp:rationale>
+ In a conference call multiple parties can share one media
+ content (say, audio), but the streaming of that media can
+ either be shared or separate. For example, in a multicast
+ conference all contacts would share one stream, while in a
+ Muji conference there would be a stream for each
+ participant.
+ </tp:rationale>
+
+ <p>Change notification is through the
+ <tp:member-ref>StreamsAdded</tp:member-ref> and
+ <tp:member-ref>StreamsRemoved</tp:member-ref> signals.</p>
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content_Interface_Audio_Control.xml b/spec/spec/Call_Content_Interface_Audio_Control.xml
new file mode 100644
index 000000000..b13e02f52
--- /dev/null
+++ b/spec/spec/Call_Content_Interface_Audio_Control.xml
@@ -0,0 +1,111 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/Call_Content_Interface_Audio_Control"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.Interface.AudioControl"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.25.1">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content.Interface.Media"/>
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface allows the connection manager to be kept informed of,
+ and control, the input and output volumes of an audio stream.
+ While generally not needed, if the connection manager needs to
+ handle stream volumes directly (typically when using
+ <tp:value-ref>Call_Content_Packetization_Type_Raw</tp:value-ref>),
+ this interface may be necessary.</p>
+
+ <p>If this interface is present, the handler should call
+ <tp:member-ref>ReportInputVolume</tp:member-ref>
+ and <tp:member-ref>ReportOutputVolume</tp:member-ref> whenever the
+ input and output volume change, both when the user manually modifies
+ the volume and when the volumes are adjusted in response to
+ <tp:member-ref>RequestedInputVolume</tp:member-ref> and
+ <tp:member-ref>RequestedOutputVolume</tp:member-ref> changing.</p>
+
+ <p>The maximum volume as used in this interface represent the unamplified
+ hardware volume (0 dB). No software amplification should be used to
+ boost the signal to a higher level when this Interface is in use</p>
+ </tp:docstring>
+
+ <property name="RequestedInputVolume" tp:type="Audio_Control_Volume"
+ type="i" access="read" tp:name-for-bindings="Requested_Input_Volume">
+ <tp:docstring>
+ The input volume as requested by the Connection Manager.
+ Initially and on any changes the client should change its input volume
+ to match the requested volume.
+ </tp:docstring>
+ </property>
+
+ <method name="ReportInputVolume" tp:name-for-bindings="Report_Input_Volume">
+ <arg direction="in" name="Volume" tp:type="Audio_Control_Volume" type="i">
+ <tp:docstring>
+ Report the input volume level as set by the client.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ <p>Report to the CM that the Content input volume has been
+ changed by the client.</p>
+
+ <p>It is the client's responsibility to change the input volume used for
+ the content. However, the client MUST call this whenever it changes
+ input volume for the content.</p>
+ </tp:docstring>
+ </method>
+
+ <property name="RequestedOutputVolume" tp:type="Audio_Control_Volume"
+ type="i" access="read" tp:name-for-bindings="Requested_Output_Volume">
+ <tp:docstring>
+ The input volume as requested by the Connection Manager.
+ Initially and on any changes the client should change its input volume
+ to match the requested volume.
+ </tp:docstring>
+ </property>
+
+ <method name="ReportOutputVolume"
+ tp:name-for-bindings="Report_Output_Volume">
+ <arg direction="in" name="Volume" tp:type="Audio_Control_Volume" type="i">
+ <tp:docstring>
+ Report the output volume level as set by the client.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ <p>Report to the CM that the content output volume has been
+ changed by the client.</p>
+
+ <p>It is the client's responsibility to change the output volume used
+ for the content. However, the client MUST call this whenever it
+ changes output volume for the content.</p>
+ </tp:docstring>
+ </method>
+
+ <tp:simple-type name="Audio_Control_Volume" type="i">
+ <tp:docstring>
+ <p>A volume value either reported to or requested by the Connection
+ Manager. This value should either be -1 for an unknown value or in the
+ range of 0-255, with 0 being the minimal volume and 255 being the
+ highest unamplified volume the input or output is capable of (known
+ as 0 dB)
+ </p>
+ </tp:docstring>
+ </tp:simple-type>
+ </interface>
+</node>
diff --git a/spec/spec/Call_Content_Interface_Media.xml b/spec/spec/Call_Content_Interface_Media.xml
new file mode 100644
index 000000000..ca5ed36bf
--- /dev/null
+++ b/spec/spec/Call_Content_Interface_Media.xml
@@ -0,0 +1,581 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content_Interface_Media"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Call1.Content.Interface.Media"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.23.4">(draft 2)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface to use by a software implementation of media
+ streaming. The reason behind splitting the members of this
+ interface out from the main <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref> interface is
+ that the software is not necessarily what controls the
+ media. An example of this is in GSM phones, where the CM just
+ tells the phone to dial a number and it does the audio routing
+ in a device specific hardware way and the CM does not need
+ to concern itself with codecs.</p>
+
+ <h4>Codec Negotiation</h4>
+
+ <p>When a new <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref> channel
+ appears (whether it was requested or not) a <tp:dbus-ref
+ namespace="ofdT.Call1.Content">MediaDescription</tp:dbus-ref>
+ object will either be waiting in the
+ <tp:member-ref>MediaDescriptionOffer</tp:member-ref> property, or will
+ appear at some point via the
+ <tp:member-ref>NewMediaDescriptionOffer</tp:member-ref> signal.</p>
+
+ <p>If nothing is known about the remote side's Media capabilities
+ (e.g. outgoing SIP/XMPP call), this <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> will pop up with {<tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >HasRemoteInformation</tp:dbus-ref> = false, <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >FurtherNegotiationRequired</tp:dbus-ref> = true}, and the local
+ user's streaming implementation SHOULD call
+ <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >Accept</tp:dbus-ref>,
+ with a description of all supported codecs and other features.
+ The CM will then send this information to the remote side (and
+ <tp:member-ref>LocalMediaDescriptionChanged</tp:member-ref> will fire
+ with details of the description passed into <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >Accept</tp:dbus-ref> for debugging purposes).
+ </p>
+ <p>When the remote codecs and other content information are available
+ (e.g. Remote user replies to initial offer, or sends a new offer of
+ their own, a new <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> will appear, with {<tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >HasRemoteInformation</tp:dbus-ref> = true, <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >FurtherNegotiationRequired</tp:dbus-ref> = false},
+ and the <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >Codecs</tp:dbus-ref>
+ property on the description offer set to the codecs which are
+ supported by the remote contact. The local user's streaming
+ implementation SHOULD then call Accept, with a description
+ that is compatible with the one one in the offer. After the codec
+ set is accepted, both
+ <tp:member-ref>LocalMediaDescriptionChanged</tp:member-ref> and
+ <tp:member-ref>RemoteMediaDescriptionsChanged</tp:member-ref>
+ will fire to signal their respective changes, to aid with debugging.
+ Note that if <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >Accept</tp:dbus-ref> is called, with <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >FurtherNegotiationRequired</tp:dbus-ref> set to false,
+ the CM should be able to rely on the fact that the
+ description passed into Accept is compatible with the one in the
+ offer, and the description passed into Accept will not be signalled to
+ the remote side.
+ </p>
+
+ <h4>Changing codecs mid-call</h4>
+
+ <p>To update the codecs in the local (and optionally remote) media
+ descriptions mid-call, the
+ <tp:member-ref>UpdateLocalMediaDescription</tp:member-ref> method
+ should be called with details of the new codec list. If this is
+ accepted, then
+ <tp:member-ref>LocalMediaDescriptionChanged</tp:member-ref>
+ will be emitted with the new codec set.
+ </p>
+ <p> If parameters requiring negotiation are changed, then the
+ <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >FurtherNegotiationRequired</tp:dbus-ref> property should be set to
+ TRUE, and the new media description should
+ only be used once they come in a new MediaDescriptionOffer
+ </p>
+
+ <p>If the other side decides to update his or her codec list
+ during a call, a new <tp:dbus-ref
+ namespace="ofdT.Call1.Content">MediaDescription</tp:dbus-ref>
+ object will appear through
+ <tp:member-ref>NewMediaDescriptionOffer</tp:member-ref> which should be
+ acted on as documented above.</p>
+
+ <h4>Protocols without negotiation</h4>
+
+ <p>For protocols where the codecs are not negotiable, the initial content's <tp:dbus-ref
+ namespace="ofdT.Call1.Content">MediaDescription</tp:dbus-ref>
+ object will appear with <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >HasRemoteInformation</tp:dbus-ref>,
+ set to true and the known supported codec values in <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >Codecs</tp:dbus-ref>.
+ </p>
+ </tp:docstring>
+
+ <tp:struct name="Codec" array-name="Codec_List">
+ <tp:docstring>
+ A description of a codec.
+ </tp:docstring>
+ <tp:member name="Identifier" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Numeric identifier for the codec. This will be used as the PT in the
+ SDP or content description.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Name" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The name of the codec.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Clockrate" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The clockrate of the codec.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Channels" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Number of channels of the codec if applicable, otherwise 0.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Updated" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ This should be set to true in calls to <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >Accept</tp:dbus-ref> and
+ <tp:member-ref>UpdateLocalMediaDescription</tp:member-ref> if this
+ codec has changed in a way that needs to be signalled over the
+ network. If it is set to false, the CM is allowed ignore any
+ differences between the current parameters and the previous ones
+ <tp:rationale>
+ This mechanism may be used to save bandwidth and avoid the CM
+ having to calculate diffs against previous versions of this
+ struct, which can lead to false-positives (e.g. redundant ptime
+ updates).
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Parameters" type="a{ss}" tp:type="String_String_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Extra parameters for this codec.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Contact_Codec_Map">
+ <tp:docstring>
+ A map from contact to the list of codecs he or she supports.
+ </tp:docstring>
+ <tp:member name="Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ A contact handle.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Codecs" type="a(usuuba{ss})" tp:type="Codec[]">
+ <tp:docstring>
+ The codecs that the contact supports.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:mapping name="Contact_Media_Description_Properties_Map">
+ <tp:member name="Remote_Contact" type="u" tp:type="Handle">
+ <tp:docstring>
+ The remote contact this description refers to or 0. This matches the
+ <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >RemoteContact</tp:dbus-ref> property on
+ <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref>
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Media_Description_Properties" type="a{sv}"
+ tp:type="Media_Description_Properties">
+ <tp:docstring>
+ The properties of the description
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:struct name="Media_Description_Offer">
+ <tp:docstring>
+ The remote description offer and its information
+ </tp:docstring>
+ <tp:member name="Media_Description" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The object path to the <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref>
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Remote_Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The contact handle that this description applies to.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Properties" type="a{sv}"
+ tp:type="Media_Description_Properties">
+ <tp:docstring>
+ The immutable properties of all interfaces of the codec description.
+
+ <tp:rationale>
+ Having all the codec description properties here saves a D-Bus
+ round-trip - it shouldn't be necessary to get the properties from the
+ MediaDescription object, in practice.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="UpdateLocalMediaDescription"
+ tp:name-for-bindings="Update_Local_Media_Description">
+ <tp:docstring>
+ Update the local codec mapping and other interfaces of the
+ MediaDescription. This method should only be
+ used during an existing call to update the local media description.
+ This may trigger a re-negotiation which may result in new
+ new MediaDescriptionOffers if the "FurtherNegotiationRequired"
+ property is TRUE.
+ Otherwise, only parameters which strictly describe the media being sent
+ can be changed.
+ </tp:docstring>
+ <arg name="Remote_Contact" type="u" tp:type="Handle" direction="in">
+ <tp:docstring>
+ The remote contact that this description should be negotiated with
+ (or 0 to mean "negotiate this with everyone"). Note that encoding
+ the same video multiple times is often needlessly expensive, so
+ differences in MediaDescriptions negotiated with different parties
+ in the call should be limited to payloading parameters if possible.
+ </tp:docstring>
+ </arg>
+ <arg name="MediaDescription" direction="in" type="a{sv}"
+ tp:type="Media_Description_Properties">
+ <tp:docstring>
+ The updated media description that the local side wants to use.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The protocol does not support changing the codecs mid-call.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The description given is invalid in some way.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <property name="RemoteMediaDescriptions"
+ tp:name-for-bindings="Remote_Media_Descriptions"
+ type="a{ua{sv}}"
+ tp:type="Contact_Media_Description_Properties_Map" access="read">
+ <tp:docstring>
+ <p>A map from contact handles to descriptions supported by that
+ contact.</p>
+
+ <p>Keys of this map will appear in at most one <tp:dbus-ref
+ namespace="ofdT.Call1.Stream">RemoteMembers</tp:dbus-ref>.
+ See <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >RemoteContact</tp:dbus-ref> for more details on how to map between
+ MediaDescriptions and Streams.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="LocalMediaDescriptions"
+ tp:name-for-bindings="Local_Media_Descriptions"
+ type="a{ua{sv}}"
+ tp:type="Contact_Media_Description_Properties_Map" access="read">
+ <tp:docstring>
+ <p>A map from contact handles to the descriptions the local side
+ responsed with.</p> </tp:docstring>
+ </property>
+
+ <signal name="NewMediaDescriptionOffer"
+ tp:name-for-bindings="New_Media_Description_Offer">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a new <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> appears. The streaming
+ >implementation MUST respond by calling the
+ <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >Accept</tp:dbus-ref> or <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription"
+ >Reject</tp:dbus-ref> method on the description object appeared.</p>
+
+ <p>Emission of this signal indicates that the
+ <tp:member-ref>MediaDescriptionOffer</tp:member-ref> property has
+ changed to
+ <code>(Description, Contact, MediaDescriptionProperties)</code>.</p>
+
+ <p>When the MediaDescriptionOffer has been dealt with then
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >MediaDescriptionOfferDone</tp:dbus-ref> must be emitted
+ before <tp:dbus-ref
+ namespace="ofdT.Call1.Content.Interface.Media"
+ >NewMediaDescriptionOffer</tp:dbus-ref> is emitted again.
+ </p>
+
+ </tp:docstring>
+ <arg name="Media_Description" type="o">
+ <tp:docstring>
+ The object path of the new media description. This replaces any
+ previous media description.
+ </tp:docstring>
+ </arg>
+ <arg name="Contact" type="u">
+ <tp:docstring>
+ The remote contact the media description belongs to.
+ </tp:docstring>
+ </arg>
+ <arg name="Properties" type="a{sv}"
+ tp:type="Media_Description_Properties">
+ <tp:docstring>
+ The immutable properties of the remote media description.
+
+ <tp:rationale>
+ Having all the MediaDescription properties here saves a D-Bus
+ round-trip - it shouldn't be necessary to get the properties from the
+ MediaDescription object, in practice.
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="MediaDescriptionOfferDone"
+ tp:name-for-bindings="Media_Description_Offer_Done">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> has been handled. </p>
+ <p>Emission of this signal indicates that the
+ <tp:member-ref>MediaDescriptionOffer</tp:member-ref> property has
+ changed to
+ <code>("/", 0, {})</code>.</p>
+ </tp:docstring>
+ </signal>
+
+
+ <signal name="LocalMediaDescriptionChanged"
+ tp:name-for-bindings="Local_Media_Description_Changed">
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Change notification for
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >LocalMediaDescriptions</tp:dbus-ref>
+ </p>
+ </tp:docstring>
+
+ <arg name="Remote_Contact" type="u" tp:type="Handle">
+ <tp:docstring>
+ The remote contact that this description was negotiated with
+ (or 0 to mean "negotiated with everyone").
+ </tp:docstring>
+ </arg>
+
+ <arg name="Updated_Media_Description" type="a{sv}"
+ tp:type="Media_Description_Properties">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The local content description that was updated</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="RemoteMediaDescriptionsChanged"
+ tp:name-for-bindings="Remote_Media_Descriptions_Changed">
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Change notification for
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >RemoteMediaDescriptions</tp:dbus-ref>
+ </p>
+ </tp:docstring>
+
+ <arg name="Updated_Media_Descriptions" type="a{ua{sv}}"
+ tp:type="Contact_Media_Description_Properties_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The remote content descriptions that were updated</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="MediaDescriptionsRemoved"
+ tp:name-for-bindings="Media_Descriptions_Removed">
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Removal notification for
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >RemoteMediaDescriptions</tp:dbus-ref>
+ and
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >LocalMediaDescriptions</tp:dbus-ref>
+ </p>
+ </tp:docstring>
+
+ <arg name="Removed_Media_Descriptions" type="au"
+ tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The local and remote content descriptions that are no longer part
+ of this content</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="MediaDescriptionOffer"
+ tp:name-for-bindings="Media_Description_Offer"
+ type="(oua{sv})" tp:type="Media_Description_Offer" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The object path to the current
+ <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> object, its
+ <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >RemoteContact</tp:dbus-ref> and
+ a mapping of the MediaDescriptions properties.
+ If the object path is "/" then there isn't an outstanding
+ content description, and the mapping MUST be empty.</p>
+
+ <tp:rationale>
+ Having all <tp:dbus-ref
+ namespace="ofdT.Call1.Content">MediaDescription</tp:dbus-ref>
+ properties here saves a D-Bus round-trip - it shouldn't be
+ necessary to get these properties from the Content MediaDescription
+ object, in practice.
+ </tp:rationale>
+
+ <p>Change notification is via the
+ <tp:member-ref>NewMediaDescriptionOffer</tp:member-ref> and
+ <tp:member-ref>MediaDescriptionOfferDone</tp:member-ref> signals.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="Call_Content_Packetization_Type" type="u">
+ <tp:added version="0.21.2"/>
+ <tp:docstring>
+ A packetization method that can be used for a content.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="RTP" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Real-time Transport Protocol, as documented by RFC 3550.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Raw" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Raw media.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="MSN_Webcam" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ MSN webcam. This is the video-only one-way type which was
+ used in earlier versions of WLM. Although no longer used,
+ modern WLM clients still support the MSN webcam protocol.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="Packetization" tp:name-for-bindings="Packetization"
+ type="u" tp:type="Call_Content_Packetization_Type" access="read"
+ tp:immutable="yes">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The packetization method in use for this content.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="DTMFChangeRequested"
+ tp:name-for-bindings="DTMF_Change_Requested">
+ <tp:docstring>
+ Used by the CM to relay instructions from <tp:dbus-ref
+ namespace="ofdT">Channel.Interface.DTMF</tp:dbus-ref> to the streaming
+ implementation. If any contact in this call supports the
+ telephone-event codec in their MediaDescription, this event should be
+ sent as outlined in RFC 4733. Otherwise, it should be sent as an
+ audible tone.
+ </tp:docstring>
+ <arg name="Event" type="y" tp:type="DTMF_Event">
+ <tp:docstring>
+ The event to send (or stop sending).
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Sending_State">
+ <tp:docstring>
+ Either <tp:value-ref type="Sending_State">Pending_Send</tp:value-ref> or
+ <tp:value-ref type="Sending_State">Pending_Stop_Sending</tp:value-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="AcknowledgeDTMFChange"
+ tp:name-for-bindings="Acknowledge_DTMF_Change">
+ <tp:docstring>
+ Called by the streaming implementation in response to
+ <tp:member-ref>DTMFChangeRequested</tp:member-ref> to confirm that it
+ has started or stopped sending the event in question.
+ </tp:docstring>
+ <arg name="Event" type="y" tp:type="DTMF_Event" direction="in">
+ <tp:docstring>
+ The event referred to in the corresponding
+ <tp:member-ref>DTMFChangeRequested</tp:member-ref> signal.
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Sending_State" direction="in">
+ <tp:docstring>
+ Either <tp:value-ref type="Sending_State">Sending</tp:value-ref> or
+ <tp:value-ref type="Sending_State">None</tp:value-ref>.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <property name="CurrentDTMFEvent"
+ tp:name-for-bindings="Current_DTMF_Event" type="y" tp:type="DTMF_Event"
+ access="read">
+ <tp:docstring>
+ The currently requested DTMF event (for state-recoverability of
+ <tp:member-ref>DTMFChangeRequested</tp:member-ref>). Should be ignored
+ if <tp:member-ref>CurrentDTMFState</tp:member-ref> is None.
+ </tp:docstring>
+ </property>
+
+ <property name="CurrentDTMFState"
+ tp:name-for-bindings="Current_DTMF_State" type="u" tp:type="Sending_State"
+ access="read">
+ <tp:docstring>
+ The current DTMF state (for state-recoverability of
+ <tp:member-ref>DTMFChangeRequested</tp:member-ref>).
+ </tp:docstring>
+ </property>
+
+ <method name="Fail" tp:name-for-bindings="Fail">
+ <tp:docstring>
+ Signal an unrecoverable error for this content, and remove it.
+ </tp:docstring>
+ <arg direction="in" name="Reason" type="(uuss)"
+ tp:type="Call_State_Reason">
+ <tp:docstring>
+ A reason struct describing the error.
+ </tp:docstring>
+ </arg>
+ </method>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content_Interface_Video_Control.xml b/spec/spec/Call_Content_Interface_Video_Control.xml
new file mode 100644
index 000000000..086d47581
--- /dev/null
+++ b/spec/spec/Call_Content_Interface_Video_Control.xml
@@ -0,0 +1,136 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/Call_Content_Interface_Video_Control"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.Interface.VideoControl"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.10">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content.Interface.Media"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface that allows the connection manager to control the video
+ stream.</p>
+ <p>This interface is generally not needed. In cases where the connection
+ manager handles the network communication and the media is transferred
+ from the client to the connection manager via shared memory, it can
+ sometimes be beneficial for the connection manager to be able to
+ control certain aspects of the video stream.</p>
+ </tp:docstring>
+
+ <signal name="KeyFrameRequested" tp:name-for-bindings="Key_Frame_Requested">
+ <tp:docstring>
+ Request that the video encoder produce a new key frame as soon as
+ possible.
+ </tp:docstring>
+ </signal>
+
+ <tp:struct name="Video_Resolution"
+ array-name="Video_Resolution_Struct">
+ <tp:member type="u" name="Width">
+ <tp:docstring>
+ With of the video stream.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Height">
+ <tp:docstring>
+ Height of the video stream.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="VideoResolution" type="(uu)" tp:type="Video_Resolution"
+ access="read" tp:name-for-bindings="Video_Resolution">
+ <tp:docstring>
+ The resolution at which the streaming engine should be sending.
+
+ <p>Change notification is via the
+ <tp:member-ref>VideoResolutionChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="VideoResolutionChanged"
+ tp:name-for-bindings="Video_Resolution_Changed">
+ <tp:docstring>
+ The desired video resolution has changed.
+ </tp:docstring>
+ <arg type="(uu)" tp:type="Video_Resolution" name="NewResolution" />
+ </signal>
+
+ <property name="Bitrate" type="u" access="read"
+ tp:name-for-bindings="Bitrate">
+ <tp:docstring>
+ The bitrate the streaming engine should be sending at.
+
+ <p>Change notification is via the
+ <tp:member-ref>BitrateChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="BitrateChanged"
+ tp:name-for-bindings="Bitrate_Changed">
+ <tp:docstring>
+ The desired bitrate has changed
+ </tp:docstring>
+ <arg type="u" name="NewBitrate" />
+ </signal>
+
+ <property name="Framerate" type="u" access="read"
+ tp:name-for-bindings="Framerate">
+ <tp:docstring>
+ The framerate the streaming engine should be sending at.
+
+ <p>Change notification is via the
+ <tp:member-ref>FramerateChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="FramerateChanged"
+ tp:name-for-bindings="Framerate_Changed">
+ <tp:docstring>
+ The desired framerate has changed
+ </tp:docstring>
+ <arg type="u" name="NewFramerate" />
+ </signal>
+
+ <property name="MTU" type="u" access="read"
+ tp:name-for-bindings="MTU">
+ <tp:docstring>
+ The Maximum Transmission Unit
+
+ <p>Change notification is via the
+ <tp:member-ref>MTUChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="MTUChanged" tp:name-for-bindings="MTU_Changed">
+ <tp:docstring>
+ The Maximum Transmission Unit has changed
+ </tp:docstring>
+ <arg type="u" name="NewMTU" />
+ </signal>
+
+ <property name="ManualKeyFrames" type="b" access="read"
+ tp:name-for-bindings="Manual_Key_Frames">
+ <tp:docstring>
+ Only send key frames when manually requested
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
diff --git a/spec/spec/Call_Content_Media_Description.xml b/spec/spec/Call_Content_Media_Description.xml
new file mode 100644
index 000000000..fd8ab89fe
--- /dev/null
+++ b/spec/spec/Call_Content_Media_Description.xml
@@ -0,0 +1,236 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content_Media_Description"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.MediaDescription"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.23.4">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ This object represents a remote Description Offer to which the local
+ streaming implementation should reply with its local Description.
+
+ This is intended as a temporary transactional object for use with <tp:dbus-ref
+ namespace="ofdT.Call1">Content.Interface.Media</tp:dbus-ref>.
+ There will always be 0 or 1 MediaDescription object per Content.
+ In most cases, this object will stay alive until you call either
+ <tp:member-ref>Accept</tp:member-ref> or
+ <tp:member-ref>Reject</tp:member-ref>, and then disappear.
+ There are some cases (e.g. an endpoint being removed from the call)
+ where a MediaDescription object will disappear before you have had a
+ chance to either Accept or Reject it.
+ </tp:docstring>
+
+ <method name="Accept" tp:name-for-bindings="Accept">
+ <arg name="Local_Media_Description" direction="in"
+ type="a{sv}" tp:type="Media_Description_Properties">
+ <tp:docstring>
+ The local description to send to the remote contacts and
+ to use in the <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Accepts the updated Description and update the corresponding
+ local description. If FurtherNegotiationRequired is True,
+ calling this method will generally cause a network round-trip
+ and a new MediaDescription to be offered (hopefully with
+ FurtherNegotiationRequired set to False).
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The description given is invalid in some way.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Reject" tp:name-for-bindings="Reject">
+ <tp:docstring>
+ Reject the proposed update to the remote description.
+ </tp:docstring>
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason"
+ direction="in">
+ <tp:docstring>
+ A structured reason for the rejection.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Extra interfaces provided by this media description. This SHOULD
+ NOT include the Description interface itself.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="FurtherNegotiationRequired"
+ tp:name-for-bindings="Further_Negotiation_Required" type="b"
+ access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml" >
+ <p> If this is set to True by the CM in a MediaDescriptionOffer, it
+ means "This is an offer under the SDP Offer/Answer model. Whatever
+ you accept this offer with is what I will send to the other side in
+ my answer."
+
+ If this is set to False by the CM then it means "This is an Answer
+ under the SDP Offer/Answer model, and if it remains False in the
+ Accept(), no further codec negotiation needs to happen."
+
+ If this is set to True by the streaming implementation (e.g. in an
+ Accept or UpdateLocalMediaDescription call) then a new SDP
+ Offer/Answer round-trip will be initiated.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <property name="HasRemoteInformation"
+ tp:name-for-bindings="Has_Remote_Information" type="b"
+ access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml" >
+ <p> True if this offer contains information from the remote side:
+ If False then the Accept response solely depends on the
+ capabilities and preferences of the local side.
+
+ In most protocols this property will be False for the initial
+ DescriptionOffer on an outgoing call.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <property name="Codecs"
+ tp:name-for-bindings="Codecs"
+ type="a(usuuba{ss})" tp:type="Codec[]" access="read"
+ tp:immutable="yes">
+ <tp:docstring>
+ A list of codecs the remote contact supports. When used with
+ <tp:member-ref>Accept</tp:member-ref>, it means the locally supported
+ codecs.
+ </tp:docstring>
+ </property>
+
+ <property name="RemoteContact" tp:name-for-bindings="Remote_Contact"
+ type="u" tp:type="Contact_Handle" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The contact handle that this description applies to.
+
+ This property can be used as an opaque identifier, and searched for in
+ <tp:dbus-ref namespace="ofdT.Call1.Stream"
+ >RemoteMembers</tp:dbus-ref> for each Stream in this Content, to
+ determine which Stream this MediaDescription applies to. If multiple
+ MediaDescriptions apply to the same Stream, the
+ <tp:member-ref>SSRCs</tp:member-ref> property should be used to
+ separate media before decoding.
+
+ If this property is 0, this MediaDescription applies to all streams,
+ so the above matching method is unneccesary (e.g. in conference calls
+ with a mixer, media from all participants is mixed into one stream).
+
+ When calling Accept or UpdateLocalMediaDescription, this should always
+ be set to 0, or omitted, because it is assumed that you send the same
+ MediaDescription to everyone (Encoding a stream separately for each
+ contact in a call is inefficient, and should be avoided).
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="Contact_SSRCs_Map">
+ <tp:member name="Contact" type="u" tp:type="Handle">
+ <tp:docstring>
+ The remote contact these SSRCs belong to or 0.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="SSRCs" type="au">
+ <tp:docstring>
+ The list of Synchronisation Sources.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="SSRCs" tp:name-for-bindings="SSRCs"
+ type="a{uau}" tp:type="Contact_SSRCs_Map" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from Handle to list of Synchronisation Sources, as defined by
+ RFC 3550.</p>
+
+ <p>Some protocols require the negotiation of SSRC identifiers for RTP
+ streams. If this is the case, then MediaDescription offers will appear
+ with this property set. The streaming implementation should then call
+ <tp:member-ref>Accept</tp:member-ref> with a map from 0 to a
+ list containing a single SSRC (which does not collide with these,
+ or any previously seen SSRCs). If a new MediaDescription offer
+ appears with an SSRC the same as one in <tp:dbus-ref
+ namespace="ofdT.Call1.Content.Interface.Media"
+ >LocalMediaDescriptions</tp:dbus-ref>, then the streaming
+ implementation should pick a new SSRC to resolve the collision.</p>
+
+ <p>It is expected that this list will normally be at most one element long,
+ but it is kept as a list for extensibility. The concatenation of all
+ SSRCs associated with a Stream should contain no duplicate entries. If
+ there are collisions, then it is the responsibility of the protocol
+ implementation to resolve them and generate new offers.</p>
+
+ <p>If this property is omitted, then the streaming implementation can
+ assume that there is only one MediaDescription per Stream.</p>
+
+ <p>If there is a single multicast Call Stream with multiple
+ Remote Members, and all members are forced to use the same
+ MediaDescription, this map can be used by the streaming implementation
+ to determine which video sources belong to which contacts (e.g. in
+ order to put a name under each face in the call)</p>
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="Media_Description_Properties">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ A mapping containing all properties that define the information from a
+ <tp:dbus-ref
+ namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref> and its interfaces.
+ </p>
+
+ <p>
+ If <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >HasRemoteInformation</tp:dbus-ref> is True, then this mapping
+ will always contains at least
+ <tp:dbus-ref namespace="ofdT.Call1.Content.MediaDescription"
+ >Codecs</tp:dbus-ref>
+ </p>
+ </tp:docstring>
+
+ <tp:member name="Media_Description_Property"
+ type="s" tp:type="DBus_Qualified_Member">
+ <tp:docstring>
+ A D-Bus interface name, followed by a dot and a D-Bus property name.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Media_Description_Property_Value" type="v">
+ <tp:docstring>
+ The value of the property
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml b/spec/spec/Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml
new file mode 100644
index 000000000..f973306cb
--- /dev/null
+++ b/spec/spec/Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content_Media_Description_Interface_RTCP_Extended_Reports" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.MediaDescription.Interface.RTCPExtendedReports"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.23.4">(draft version, not API-stable)</tp:added>
+ <tp:requires
+ interface="org.freedesktop.Telepathy.Call1.Content.MediaDescription"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This codec offer interface provides a method of signalling for
+ RTCP extended reports, documented by <em>RTP Control Protocol
+ Extended Reports (RTCP XR)</em> (RFC 3611). CMs should ignore
+ all RTCP Extended Report parameters that are not listed
+ in this spec at the time of implementation. More parameters can be
+ added to the spec as required.</p>
+
+ <p>For more details on what RTCP extended reports can do and how
+ to use them, one should refer to
+ <a href="http://www.faqs.org/rfcs/rfc3611.html">RFC 3611</a>.</p>
+
+ </tp:docstring>
+
+ <property access="read" type="u" name="LossRLEMaxSize" tp:name-for-bindings="Loss_RLE_Max_Size">
+ <tp:docstring>
+ If non-zero, enable Loss Run Length Encoded Report Blocks. The value
+ of this integer represents the max-size of report blocks, as specified
+ in RFC 3611 section 5.1. MAXUINT32 is used to indicate that there is
+ no limit.
+ </tp:docstring>
+ </property>
+ <property access="read" type="u" name="DuplicateRLEMaxSize" tp:name-for-bindings="Duplicate_RLE_Max_Size">
+ <tp:docstring>
+ If non-zero, enable Duplicate Run-Length-Encoded Report Blocks. The
+ value of this integer represents the max-size of report blocks, as
+ specified in RFC 3611 section 5.1. MAXUINT32 is used to indicate that
+ there is no limit.
+ </tp:docstring>
+ </property>
+ <property access="read" type="u" name="PacketReceiptTimesMaxSize" tp:name-for-bindings="Packet_Receipt_Times_Max_Size">
+ <tp:docstring>
+ If non-zero, enable Packet Receipt Times Report Blocks. The
+ value of this integer represents the max-size of report blocks, as
+ specified in RFC 3611 section 5.1. MAXUINT32 is used to indicate that
+ there is no limit.
+ </tp:docstring>
+ </property>
+ <property access="read" type="u" name="DLRRMaxSize" tp:name-for-bindings="DLRR_Max_Size">
+ <tp:docstring>
+ If non-zero, enable Receiver Reference Time and Delay since Last
+ Receiver Report Blocks (for estimating Round Trip Times between
+ non-senders and other parties in the call. The value of this integer
+ represents the max-size of report blocks, as specified in RFC 3611
+ section 5.1. MAXUINT32 is used to indicate that there is no limit.
+ </tp:docstring>
+ </property>
+ <property access="read" type="u" tp:type="RCPT_XR_RTT_Mode"
+ name="RTTMode" tp:name-for-bindings="RTT_Mode">
+ <tp:docstring>
+ Who is allowed to send Delay since Last Receiver Reports.
+ </tp:docstring>
+ </property>
+
+ <property access="read" type="u" tp:type="RTCP_XR_Statistics_Flags"
+ name="StatisticsFlags" tp:name-for-bindings="Statistics_Flags">
+ <tp:docstring>
+ Which fields SHOULD be included in the statistics summary
+ report blocks that are sent, and whether to send VoIP Metrics Report
+ Blocks. There can be zero or more flags
+ set.
+ </tp:docstring>
+ </property>
+
+ <property access="read" type="b" name="EnableMetrics" tp:name-for-bindings="Enable_Metrics">
+ <tp:docstring>
+ Whether to enable VoIP Metrics Report Blocks. These blocks are of a
+ fixed size.
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="RTCP_XR_Statistics_Flags" type="u">
+ <tp:flag suffix="Loss" value="1">
+ <tp:docstring>
+ Loss report flag, as defined in RFC3611 section 4.6.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Duplicate" value="2">
+ <tp:docstring>
+ Duplicate report flag, as defined in RFC3611 section 4.6.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Jitter" value="4">
+ <tp:docstring>
+ Jitter flag, as defined in RFC3611 section 4.6.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="TTL" value="8">
+ <tp:docstring>
+ First bit of TTL or Hop Limit flag, as defined in RFC3611 section
+ 4.6.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="HL" value="16">
+ <tp:docstring>
+ Second bit of TTL or Hop Limit flag, as defined in RFC3611 section
+ 4.6.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:enum name="RCPT_XR_RTT_Mode" type="u">
+ <tp:enumvalue suffix="All" value="0">
+ <tp:docstring>
+ Both RTP data senders and data receivers MAY send DLRR
+ blocks.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Sender" value="1">
+ <tp:docstring>
+ Only active RTP senders MAY send DLRR blocks, i.e., non RTP
+ senders SHALL NOT send DLRR blocks.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content_Media_Description_Interface_RTCP_Feedback.xml b/spec/spec/Call_Content_Media_Description_Interface_RTCP_Feedback.xml
new file mode 100644
index 000000000..f586fe4c2
--- /dev/null
+++ b/spec/spec/Call_Content_Media_Description_Interface_RTCP_Feedback.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content_Media_Description_Interface_RTCP_Feedback" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.MediaDescription.Interface.RTCPFeedback"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.23.4">(draft version, not API-stable)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content.MediaDescription"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This codec offer interface provides a method of signalling
+ support for RTCP feedback, documented by <em>Extended RTP
+ Profile for Real-time Transport Control Protocol (RTCP)-Based
+ Feedback (RTP/AVPF)</em> (RFC 4585).</p>
+
+ <p>The codec identifiers used in the description of the Feedback Messages
+ sent in the <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription">Accept</tp:dbus-ref>'s
+ should match those used for the RemoteCodecs in the same Accept call.
+ </p>
+
+ <p>For more details on what RTCP Feedback can do and how to use
+ it, one should refer to
+ <a href="http://www.faqs.org/rfcs/rfc4585.html">RFC 4585</a>.</p>
+
+ </tp:docstring>
+
+ <property name="FeedbackMessages" type="a{u(ua(sss))}"
+ tp:type="RTCP_Feedback_Message_Map"
+ access="read" tp:name-for-bindings="Feedback_Messages">
+ <tp:docstring>
+ A map of remote feedback codec properties that are supported.
+ </tp:docstring>
+ </property>
+
+ <property name="DoesAVPF" type="b"
+ access="read" tp:name-for-bindings="Does_AVPF">
+ <tp:docstring>
+ True if the remote contact supports Audio-Visual Profile
+ Feedback (AVPF), otherwise False.
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml b/spec/spec/Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml
new file mode 100644
index 000000000..a35615add
--- /dev/null
+++ b/spec/spec/Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" ?>
+<node name="/Call_Content_Media_Description_Interface_RTP_Header_Extensions" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Content.MediaDescription.Interface.RTPHeaderExtensions"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.23.4">(draft version, not API-stable)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content.MediaDescription"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This media description interface provides a method of signalling
+ support for RTP Header Extensions, documented by
+ <em>A General Mechanism for RTP Header Extensions (RFC 5285)</em>.</p>
+
+ <p>For more details on the General Mechanism for RTP Header Extensions
+ and how to use them, one should refer to
+ <a href="http://www.faqs.org/rfcs/rfc5285.html">RFC 5285</a>.</p>
+
+ </tp:docstring>
+
+ <tp:struct name="RTP_Header_Extension"
+ array-name="RTP_Header_Extensions_List">
+ <tp:docstring>
+ A struct defining a RTP Header extension.
+ </tp:docstring>
+ <tp:member type="u" name="ID">
+ <tp:docstring>
+ Identifier to be negotiated.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Media_Stream_Direction" name="Direction">
+ <tp:docstring>
+ Direction in which the Header Extension is negotiated.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="URI">
+ <tp:docstring>
+ URI defining the extension.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Parameters">
+ <tp:docstring>
+ Feedback parameters as a string. Format is defined in the relevant RFC.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="HeaderExtensions" type="a(uuss)"
+ tp:type="RTP_Header_Extension[]"
+ access="read" tp:name-for-bindings="Header_Extensions">
+ <tp:docstring>
+ A list of remote header extensions which are supported.
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Interface_Mute.xml b/spec/spec/Call_Interface_Mute.xml
new file mode 100644
index 000000000..1202383f7
--- /dev/null
+++ b/spec/spec/Call_Interface_Mute.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" ?>
+<node name="/Call_Interface_Mute" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Interface.Mute" tp:causes-havoc="experimental">
+ <tp:added version="0.19.6">(draft version, not API-stable)</tp:added>
+ <tp:xor-requires>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Call1"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Stream"/>
+ </tp:xor-requires>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for calls which may be muted. This only makes sense
+ for channels where audio or video is streaming between members.</p>
+
+ <p>Muting a call content indicates that the user does not wish to send
+ outgoing audio or video.</p>
+
+ <p>It should always be possible to mute an entire call. It is sometimes
+ also possible to mute individual Contents (e.g. to prevent background
+ noise from disturbing other participants, but remain visible on
+ webcam) or to mute individual streams (e.g. to "whisper" to other call
+ participants)</p>
+
+ <tp:rationale>
+ For some protocols, the fact that the content is muted needs
+ to be transmitted to the peer; for others, the notification
+ to the peer is only informational (eg. XMPP), and some
+ protocols may have no notion of muting at all.
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:enum name="Local_Mute_State" type="u">
+ <tp:docstring>
+ The mute state of (at least part of) the call. See
+ <tp:member-ref>LocalMuteState</tp:member-ref> for more details.
+ </tp:docstring>
+
+ <tp:enumvalue value="0" suffix="Unmuted">
+ <tp:docstring>
+ All streams are unmuted (the call is active). New channels SHOULD
+ have this mute state.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="1" suffix="Muted">
+ <tp:docstring>
+ All streams are Muted.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="2" suffix="Pending_Mute">
+ <tp:docstring>
+ The connection manager is attempting to move to state Muted, but
+ has not yet completed that operation. It is unspecified whether
+ any, all or none of the streams making up the channel are muted.
+ Examining the Mute state of Call Contents (if applicable) may
+ provide more useful information.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="3" suffix="Pending_Unmute">
+ <tp:docstring>
+ The connection manager is attempting to move to state Unmuted, but
+ has not yet completed that operation. It is unspecified whether
+ any, all or none of the streams making up the channel are muted.
+ Examining the Mute state of Call Contents or Streams may
+ provide more useful information.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="4" suffix="Partially_Muted">
+ <tp:docstring>
+ Some of the constituent Streams are Muted. This state only makes
+ sense on Call Channels or Contents.
+ Examining the Mute state of Call Contents or Streams should
+ provide more useful information.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <signal name="MuteStateChanged" tp:name-for-bindings="Mute_State_Changed">
+ <tp:docstring>
+ Emitted to indicate that the mute state has changed for this call content.
+ This may occur as a consequence of the client calling
+ <tp:member-ref>RequestMuted</tp:member-ref>, or as an indication that another
+ client has (un)muted the content.
+ </tp:docstring>
+ <arg name="MuteState" type="u" tp:type="Local_Mute_State">
+ <tp:docstring>
+ The new mute state.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="LocalMuteState" type="u" tp:type="Local_Mute_State"
+ access="read" tp:name-for-bindings="Local_Mute_State">
+ <tp:docstring>
+ The current mute state of this part of the call. New
+ <tp:dbus-ref namespace="ofdT.Call1">Content</tp:dbus-ref>s should
+ inherit the value of this property from the parent
+ <tp:dbus-ref namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>.
+ Similarly, <tp:dbus-ref namespace="ofdT.Call1">Stream</tp:dbus-ref>s
+ should inherit it from the parent <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref>.
+ </tp:docstring>
+ </property>
+
+ <method name="RequestMuted" tp:name-for-bindings="Request_Muted">
+ <tp:changed version="0.21.2">renamed from SetMuted to Mute</tp:changed>
+ <tp:changed version="0.21.3">renamed back from Mute to SetMuted</tp:changed>
+ <arg direction="in" name="Muted" type="b">
+ <tp:docstring>
+ True if the client wishes to mute the Content or Call.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ <p>Inform the CM that the Call, Content or Stream should be muted or
+ unmuted.</p>
+
+ <p>The CM will tell the streaming implementation to Mute Streams as
+ required, and emit <tp:member-ref>MuteStateChanged</tp:member-ref>
+ when done.</p>
+ </tp:docstring>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Stream.xml b/spec/spec/Call_Stream.xml
new file mode 100644
index 000000000..b8b347d48
--- /dev/null
+++ b/spec/spec/Call_Stream.xml
@@ -0,0 +1,309 @@
+<?xml version="1.0" ?>
+<node name="/Call_Stream"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Stream"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One stream inside a <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref>. A stream is
+ a single flow of packets to and from a single remote endpoint.
+ If your call connects to multiple people, you could have
+ multiple streams.</p>
+ <p>For protocols that support muting streams separately, this object MAY
+ also implement the <tp:dbus-ref
+ namespace="ofdT.Call1.Interface">Mute</tp:dbus-ref> interface</p>
+ </tp:docstring>
+
+ <method name="SetSending" tp:name-for-bindings="Set_Sending">
+ <tp:docstring>
+ Set the stream to start or stop sending media from the local
+ user to other contacts.
+ </tp:docstring>
+
+ <arg name="Send" type="b" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If True, the
+ <tp:member-ref>LocalSendingState</tp:member-ref> should
+ change to <tp:value-ref type="Sending_State">Sending</tp:value-ref>, if it isn't
+ already.</p>
+
+ <p>If False, the
+ <tp:member-ref>LocalSendingState</tp:member-ref> should
+ change to <tp:value-ref type="Sending_State">None</tp:value-ref>, if it isn't
+ already.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented" />
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring>If the call has not been accepted yet, calling
+ SetSending(True) is an error. See
+ <tp:member-ref>LocalSendingState</tp:member-ref> for details.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestReceiving" tp:name-for-bindings="Request_Receiving">
+ <tp:docstring>
+ <p>Request that a remote contact stops or starts sending on
+ this stream.</p>
+
+ <p>The <tp:member-ref>CanRequestReceiving</tp:member-ref>
+ property defines whether the protocol allows the local user to
+ request the other side start sending on this stream.</p>
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Contact from which sending is requested</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Receive" type="b" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, request that the given contact starts to send media.
+ If false, request that the given contact stops sending media.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The request contact is valid but is not involved in this
+ stream.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The protocol does not allow the local user to request the
+ other side starts sending on this stream.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="RemoteMembersChanged"
+ tp:name-for-bindings="Remote_Members_Changed">
+ <tp:changed version="0.21.2">renamed from SendersChanged to MembersChanged</tp:changed>
+ <tp:changed version="0.21.3">renamed from MembersChanged to RemoteMembersChanged</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Emitted when <tp:member-ref>RemoteMembers</tp:member-ref> changes.
+ </tp:docstring>
+
+ <arg name="Updates" type="a{uu}" tp:type="Contact_Sending_State_Map">
+ <tp:docstring>
+ A mapping from channel-specific handles to their updated sending
+ state, whose keys include at least the members who were added,
+ and the members whose states changed.
+ </tp:docstring>
+ </arg>
+ <arg name="Identifiers" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The identifiers of the contacts in the <var>Updates</var> map.
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The channel-specific handles that were removed from the keys
+ of the <tp:member-ref>RemoteMembers</tp:member-ref>
+ property, as a result of the contact leaving this stream
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ A structured reason for the change.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="LocalSendingStateChanged"
+ tp:name-for-bindings="Local_Sending_State_Changed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Emitted when <tp:member-ref>LocalSendingState</tp:member-ref> changes.
+ </tp:docstring>
+
+ <arg name="State" type="u" tp:type="Sending_State">
+ <tp:docstring>
+ The new value of
+ <tp:member-ref>LocalSendingState</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ A structured reason for the change.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="Sending_State" type="u">
+ <tp:docstring>
+ Enum indicating whether a contact is sending media.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ The contact is not sending media and has not been asked to
+ do so.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Pending_Send" value="1">
+ <tp:docstring>
+ The contact has been asked to start sending media.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Sending" value="2">
+ <tp:docstring>
+ The contact is sending media.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Pending_Stop_Sending" value="3">
+ <tp:docstring>
+ The contact has been asked to stop sending media.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:mapping name="Contact_Sending_State_Map">
+ <tp:docstring>
+ A map from a contact to his or her sending state.
+ </tp:docstring>
+ <tp:member name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact handle.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Sending" type="u" tp:type="Sending_State">
+ <tp:docstring>
+ The sending state of the contact.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read" tp:immutable="yes">
+ <tp:added version="0.19.11"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Extra interfaces provided by this stream, such as <tp:dbus-ref
+ namespace="ofdT.Call1">Stream.Interface.Media</tp:dbus-ref>.
+ This SHOULD NOT include the Stream interface itself, and cannot
+ change once the stream has been created.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="RemoteMembers" tp:name-for-bindings="Remote_Members"
+ type="a{uu}" access="read" tp:type="Contact_Sending_State_Map">
+ <tp:changed version="0.21.2">renamed from Senders</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from remote contacts to their sending state.</p>
+
+ <p>Media sent to this stream will be sent to all members listed here.
+ All members listed here will also appear in <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">CallMembers</tp:dbus-ref>,
+ and each CallMembers member will be listed in at most one Stream per
+ Content. Therefore, to hide things from a member of the
+ call, UIs only need to mute one Stream per Content.</p>
+
+ <p>Contacts' handles in this map indicate whether they are
+ sending media to this stream. Sending_State_Pending_Send indicates
+ contacts who are not sending but have been asked to do so. The
+ local user's sending state is shown in <tp:member-ref
+ >LocalSendingState</tp:member-ref>.</p>
+
+ <p>This mapping is also used by the streaming implementation to map
+ from <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >MediaDescription</tp:dbus-ref>s to Streams. In this use-case,
+ all of the senders in this stream will be represented in
+ <tp:dbus-ref namespace="ofdT.Call1.Content.Interface.Media"
+ >RemoteMediaDescriptions</tp:dbus-ref>. This use-case should not
+ affect anything that does not handle media streaming.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="RemoteMemberIdentifiers" type="a{us}" tp:type="Handle_Identifier_Map"
+ access="read" tp:name-for-bindings="Remote_Member_Identifiers">
+ <tp:docstring>
+ The string identifiers for handles mentioned in
+ <tp:member-ref>RemoteMembers</tp:member-ref>, to
+ give clients the minimal information necessary to create contacts
+ without waiting for round-trips.
+ </tp:docstring>
+ </property>
+
+ <property name="LocalSendingState" tp:name-for-bindings="Local_Sending_State"
+ type="u" access="read" tp:type="Sending_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The local user's sending state. Media sent on this stream
+ should be assumed to be received, directly or indirectly, by
+ every other contact in the
+ <tp:member-ref>RemoteMembers</tp:member-ref> mapping. Change
+ notification is given via the
+ <tp:member-ref>LocalSendingStateChanged</tp:member-ref>
+ signal.</p>
+
+ <tp:rationale>
+ Implementations of the first Call draft had the self handle
+ in the <tp:member-ref>RemoteMembers</tp:member-ref> (then
+ called Members) map and this showed that it's annoying
+ having to keep track of the self handle so that it can be
+ special-cased.
+ </tp:rationale>
+
+ <p>A value of <tp:value-ref type="Sending_State">Pending_Send</tp:value-ref> for
+ this property indicates that the other side requested the
+ local user start sending media (which can be done by calling either
+ <tp:member-ref>SetSending</tp:member-ref> or <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">Accept</tp:dbus-ref>).</p>
+
+ <p>When <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">Accept</tp:dbus-ref> is
+ called, all streams with a local sending state of
+ <tp:value-ref type="Sending_State">Pending_Send</tp:value-ref> and the associated
+ <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >Disposition</tp:dbus-ref> set to
+ <tp:value-ref type="Call_Content_Disposition">Initial</tp:value-ref> are
+ automatically set to sending.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CanRequestReceiving" tp:name-for-bindings="Can_Request_Receiving"
+ type="b" access="read" tp:immutable="yes">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, the user can request that a remote contact starts
+ sending on this stream.</p>
+
+ <tp:rationale>Not all protocols allow the user to ask the
+ other side to start sending media.</tp:rationale>
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Stream_Endpoint.xml b/spec/spec/Call_Stream_Endpoint.xml
new file mode 100644
index 000000000..2aa7e52f3
--- /dev/null
+++ b/spec/spec/Call_Stream_Endpoint.xml
@@ -0,0 +1,400 @@
+<?xml version="1.0" ?>
+<node name="/Call_Stream_Endpoint"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Stream.Endpoint"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This object represents an endpoint for a stream. In a one-to-one
+ call, there will be one (bidirectional) stream per content and
+ one endpoint per stream (as there is only one remote
+ contact). In a multi-user call there is a stream for each remote
+ contact and each stream has one endpoint as it refers to the one
+ physical machine on the other end of the stream.</p>
+
+ <p>The multiple endpoint use case appears when SIP call forking
+ is used. Unlike jingle call forking (which is just making
+ multiple jingle calls to different resources appear as one
+ call), SIP call forking is actually done at the server so you
+ have one stream to the remote contact and then and endpoint for
+ each SIP client to be called.</p>
+ </tp:docstring>
+
+ <property name="RemoteCredentials"
+ tp:name-for-bindings="Remote_Credentials"
+ type="(ss)" tp:type="Stream_Credentials" access="read">
+ <tp:docstring>
+ The ICE credentials used for all candidates. If each candidate
+ has different credentials, then this property SHOULD be ("",
+ ""). Per-candidate credentials are set in the
+ <tp:type>Candidate</tp:type>'s
+ <tp:type>Candidate_Info</tp:type> a{sv}.
+ </tp:docstring>
+ </property>
+
+ <signal name="RemoteCredentialsSet"
+ tp:name-for-bindings="Remote_Credentials_Set">
+ <arg name="Username" type="s">
+ <tp:docstring>
+ The username set.
+ </tp:docstring>
+ </arg>
+ <arg name="Password" type="s">
+ <tp:docstring>
+ The password set.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the remote ICE credentials for the endpoint are
+ set. If each candidate has different credentials, then this
+ signal will never be fired.
+ </tp:docstring>
+ </signal>
+
+ <property name="RemoteCandidates" tp:name-for-bindings="Remote_Candidates"
+ type="a(usua{sv})" tp:type="Candidate[]" access="read">
+ <tp:docstring>
+ A list of candidates for this endpoint.
+ </tp:docstring>
+ </property>
+
+ <signal name="RemoteCandidatesAdded"
+ tp:name-for-bindings="Remote_Candidates_Added">
+ <tp:docstring>
+ Emitted when remote candidates are added to the
+ <tp:member-ref>RemoteCandidates</tp:member-ref> property.
+ </tp:docstring>
+ <arg name="Candidates"
+ type="a(usua{sv})" tp:type="Candidate[]">
+ <tp:docstring>
+ The candidates that were added.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:struct name="Candidate_Pair" array-name="Candidate_Pair_List">
+ <tp:docstring>A Pair of candidates.</tp:docstring>
+ <tp:member name="Local" type="(usua{sv})" tp:type="Candidate">
+ <tp:docstring>The local candidate.</tp:docstring>
+ </tp:member>
+ <tp:member name="Remote" type="(usua{sv})" tp:type="Candidate">
+ <tp:docstring>The remote candidate.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <signal name="CandidatePairSelected"
+ tp:name-for-bindings="Candidate_Pair_Selected">
+ <tp:docstring>
+ Emitted when a candidate is selected for use in the stream by the
+ controlling side of an ICE session.
+ The controlled side should call
+ <tp:member-ref>AcceptSelectedCandidatePair</tp:member-ref> or
+ <tp:member-ref>RejectSelectedCandidatePair</tp:member-ref> when
+ connectivity checks have either succeeded or failed for this candidate
+ pair. See also: <tp:member-ref>SelectedCandidatePairs</tp:member-ref>.
+ </tp:docstring>
+ <arg name="Local_Candidate"
+ type="(usua{sv})" tp:type="Candidate">
+ <tp:docstring>
+ The local candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Candidate"
+ type="(usua{sv})" tp:type="Candidate">
+ <tp:docstring>
+ The remote candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="SelectedCandidatePairs"
+ tp:name-for-bindings="Selected_Candidate_Pairs"
+ type="a((usua{sv})(usua{sv}))" tp:type="Candidate_Pair[]"
+ access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The candidates that have been selected for use to stream packets
+ to the remote contact for each component of the stream.
+ Change notification is given via the
+ the <tp:member-ref>CandidatePairSelected</tp:member-ref> signal.</p>
+
+ <p>Note to client implementors (from <a
+ href="http://tools.ietf.org/html/rfc5245#section-9.2.2.3">RFC 5245
+ section 9.2.2.3</a>):</p>
+
+ <blockquote>
+ <p>If at least one of the pairs is In-Progress, the agent SHOULD wait
+ for those checks to complete, and as each completes, redo the
+ processing in this section until there are no losing pairs.</p>
+ </blockquote>
+
+ <p>Also note that some or all of the local candidates in this list may
+ represent a peer-reflexive candidate that do not appear in
+ <tp:dbus-ref namespace="ofdT.Call1.Stream.Interface.Media"
+ >LocalCandidates</tp:dbus-ref>.</p>
+
+ <p>See <a href='http://tools.ietf.org/html/rfc5245#appendix-B.6'>RFC
+ 5245 Appendix B.6.</a> for more details about why this is.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="SetSelectedCandidatePair"
+ tp:name-for-bindings="Set_Selected_Candidate_Pair">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Update the entry in
+ <tp:member-ref>SelectedCandidatePairs</tp:member-ref>
+ for a particular component, and signal it to the remote side.</p>
+
+ <p>This method should only be called by the controlling side of an
+ ICE session. See <tp:member-ref>CandidatePairSelected</tp:member-ref>
+ for details.</p>
+
+ <tp:rationale>
+ <p>In the SDP offer/answer model, this signalling will take place as
+ generating an updated offer.
+ Note that updates may be queued up until information about all
+ components of all streams is gathered.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <arg name="Local_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The local candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The remote candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Stream_Endpoint_State" type="u">
+ <tp:docstring>
+ Represents the state of ICE negotiation for a single component of a
+ stream to an endpoint.
+ </tp:docstring>
+ <tp:enumvalue suffix="Connecting" value="0">
+ <tp:docstring>
+ Candidate gathering and connectivity checks are in progress.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Provisionally_Connected" value="1">
+ <tp:docstring>
+ The streaming implementation has found at least one working
+ candidate pair. It is possible to send media at this point, but the
+ controlling side has yet to negotiate the final candidates for use
+ in this call.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Fully_Connected" value="2">
+ <tp:docstring>
+ This component of the stream is connected, and an updated offer has
+ been sent and accepted (finalising the candidates to be used for the
+ call). This should be set by the CM in response to
+ <tp:member-ref>AcceptSelectedCandidatePair</tp:member-ref>.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Exhausted_Candidates" value="3">
+ <tp:docstring>
+ The streaming implementation has tried connecting to all of the
+ available candidates and none of them have connected. This is
+ distinct from Failed, because the CM might be able to provide more
+ candidates later (more likely in XMPP than SIP).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Failed" value="4">
+ <tp:docstring>
+ The CM and streaming implementation are in agreement that it is
+ impossible to connect to this endpoint. This value should only be
+ set by the CM.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:mapping name="Component_State_Map">
+ <tp:member name="Component" type="u" tp:type="Stream_Component"/>
+ <tp:member name="State" type="u" tp:type="Stream_Endpoint_State"/>
+ </tp:mapping>
+
+ <property name="EndpointState" tp:name-for-bindings="Endpoint_State"
+ type="a{uu}" tp:type="Component_State_Map"
+ access="read">
+ <tp:docstring>
+ The state of ICE negotiation with this Endpoint for each component of
+ the stream.
+ </tp:docstring>
+ </property>
+
+ <signal name="EndpointStateChanged"
+ tp:name-for-bindings="Endpoint_State_Changed">
+ <tp:docstring>
+ Emitted when the <tp:member-ref>EndpointState</tp:member-ref>
+ property changes.
+ </tp:docstring>
+ <arg name="Component" type="u" tp:type="Stream_Component">
+ <tp:docstring>
+ The component whose state has changed.
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Stream_Endpoint_State">
+ <tp:docstring>
+ The new state of this component.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="SetEndpointState"
+ tp:name-for-bindings="Set_Endpoint_State">
+ <tp:docstring>
+ Change the <tp:member-ref>EndpointState</tp:member-ref> of the
+ endpoint.
+ </tp:docstring>
+ <arg direction="in" name="Component" type="u" tp:type="Stream_Component">
+ <tp:docstring>
+ The component whose state needs updating.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="State" type="u" tp:type="Stream_Endpoint_State">
+ <tp:docstring>
+ The new state of this component.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AcceptSelectedCandidatePair"
+ tp:name-for-bindings="Accept_Selected_Candidate_Pair">
+ <tp:docstring>
+ Called in response to
+ <tp:member-ref>CandidatePairSelected</tp:member-ref> if/when this
+ candidate pair is known to have passed its connectivity checks.
+ </tp:docstring>
+ <arg name="Local_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The local candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The remote candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RejectSelectedCandidatePair"
+ tp:name-for-bindings="Reject_Selected_Candidate_Pair">
+ <tp:docstring>
+ Called in response to
+ <tp:member-ref>CandidatePairSelected</tp:member-ref> if/when this
+ candidate pair is known to have failed its connectivity checks.
+ </tp:docstring>
+ <arg name="Local_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The local candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Candidate"
+ type="(usua{sv})" tp:type="Candidate" direction="in">
+ <tp:docstring>
+ The remote candidate that has been selected.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="Transport" tp:name-for-bindings="Transport"
+ type="u" tp:type="Stream_Transport_Type" access="read">
+ <tp:docstring>
+ The transport type for the stream endpoint.
+ </tp:docstring>
+ </property>
+
+ <property name="Controlling" tp:name-for-bindings="Controlling"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The local side is taking the controlling role (as defined by ICE RFC
+ 5245). Change notification is given via the
+ <tp:member-ref>ControllingChanged</tp:member-ref> signal.</p>
+
+ <tp:rationale>In ICE, the Caller is normally in controlling mode (and
+ the Callee in controlled-mode), except if the Caller is doing ICE-Lite,
+ in which case it's reversed. The Controlling side is responsible for
+ selecting nominated pairs, and generating updated offers upon
+ conclusion of ICE.</tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="SetControlling"
+ tp:name-for-bindings="Set_Controlling">
+ <tp:docstring>
+ Set whether the local side is taking the Controlling role. Note that
+ if there are multiple endpoints (e.g. SIP call forking) it may be the
+ case that all endpoints need to have the same controlling/controlled
+ orientation.
+ </tp:docstring>
+ <arg name="Controlling" type="b" direction="in">
+ <tp:docstring>
+ The new value of <tp:member-ref>Controlling</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="ControllingChanged"
+ tp:name-for-bindings="Controlling_Changed">
+ <tp:docstring>
+ The value of <tp:member-ref>Controlling</tp:member-ref> has changed.
+ </tp:docstring>
+ <arg name="Controlling" type="b">
+ <tp:docstring>
+ The new value of <tp:member-ref>Controlling</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="IsICELite" tp:name-for-bindings="Is_ICE_Lite"
+ type="b" access="read">
+ <tp:docstring>
+ The Remote side is an ICE Lite endpoint. (The local side is assumed to
+ always be an ICE Full implementation.)
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Call_Stream_Interface_Media.xml b/spec/spec/Call_Stream_Interface_Media.xml
new file mode 100644
index 000000000..450d5ea42
--- /dev/null
+++ b/spec/spec/Call_Stream_Interface_Media.xml
@@ -0,0 +1,770 @@
+<?xml version="1.0" ?>
+<node name="/Call_Stream_Interface_Media"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Call1.Stream.Interface.Media"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Stream"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface deals with how to connect a stream to an
+ endpoint. It contains all that is required to describe the
+ local endpoint, to succesfully establish a connection. While a
+ call is established, one may try to connect to multiple remote
+ endpoints at the same time. This is called forking in the SIP
+ jargon. Informations related to the connections are on the
+ <tp:dbus-ref
+ namespace="ofdT.Call1.Stream">Endpoint</tp:dbus-ref>
+ objects. Once the call is established, there MUST be a single
+ endpoint left.</p>
+
+ <h4>ICE restarts</h4>
+
+ <p>If the CM wants to do an ICE restart, then the
+ <tp:member-ref>ICERestartPending</tp:member-ref> property is set,
+ and the <tp:member-ref>ICERestartRequested</tp:member-ref> signal is
+ emitted. The streaming implementation should then call
+ <tp:member-ref>SetCredentials</tp:member-ref> again. This will trigger
+ the actual ICE restart, and cause
+ <tp:member-ref>LocalCandidates</tp:member-ref> to be cleared.</p>
+
+ <p>For more information on ICE restarts see
+ <a href="http://tools.ietf.org/html/rfc5245#section-9.1.1.1">RFC 5245
+ section 9.1.1.1</a></p>
+ </tp:docstring>
+
+ <tp:enum type="u" name="Stream_Flow_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The type of <tp:member-ref>SendingState</tp:member-ref>
+ and <tp:member-ref>ReceivingState</tp:member-ref>.
+ </tp:docstring>
+ <tp:enumvalue suffix="Stopped" value="0">
+ <tp:docstring>
+ No data is flowing (or expected to be flowing) at this time.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Pending_Start" value="1">
+ <tp:docstring>
+ The streaming implementation has been told to start or receiving,
+ but has not yet indicated that it is doing so.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Pending_Stop" value="2">
+ <tp:docstring>
+ The streaming implementation has been told to stop sending or
+ receiving data, but it has not yet indicated that it has done so.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Started" value="3">
+ <tp:docstring>
+ The streaming implementation is successfully sending or receiving
+ data, and everything is going swimmingly.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Pending_Pause" value="4">
+ <tp:docstring>
+ The streaming implementation has been told to pause sending or
+ displaying data, but it has not yet indicated that it has done so.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Paused" value="5">
+ <tp:docstring>
+ The streaming implementation has successfully paused either sending or
+ displaying data, and the local user's privacy or peace-and-quiet is
+ protected.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="SendingState" tp:name-for-bindings="Sending_State"
+ type="u" tp:type="Stream_Flow_State" access="read">
+ <tp:docstring>
+ Indicates whether the streaming implementation is/should be sending
+ media for this stream. The streaming implementation should be able to
+ rely on reading this value and listening to
+ <tp:member-ref>SendingStateChanged</tp:member-ref> to
+ determine whether it should be sending media or not. It should not
+ need to listen to the Mute/Hold interfaces on the Call/Content.
+ Feedback on success should be given via
+ <tp:member-ref>CompleteSendingStateChange</tp:member-ref>. Failures
+ should be reported via <tp:member-ref>ReportSendingFailure</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <signal name="SendingStateChanged"
+ tp:name-for-bindings="Sending_State_Changed">
+ <tp:docstring>
+ Change notification for <tp:member-ref>SendingState</tp:member-ref>.
+ Note that this information is duplicated onto the Stream interface, so
+ that UIs can ignore the Media interface, and streaming implementations
+ can ignore everything but the media interface.
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="Stream_Flow_State">
+ <tp:docstring>
+ The new value of SendingState.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="CompleteSendingStateChange"
+ tp:name-for-bindings="Complete_Sending_State_Change">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called in response to
+ <tp:member-ref>SendingStateChanged</tp:member-ref>(Pending_*, *) to
+ indicate that the media state has successfully progressed from
+ Pending_{Start, Stop, Pause} to the corresponding non-pending
+ state.</p>
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="Stream_Flow_State" direction="in">
+ <tp:docstring>
+ The new (non-pending) value of SendingState.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The state change made no sense, and was ignored by the CM. The
+ most likely cause for this is a race-condition between the CM
+ emitting a new state change and the streaming implementation
+ responding to the previous state change.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="ReportSendingFailure"
+ tp:name-for-bindings="Report_Sending_Failure">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Can be called at any point to indicate a failure in the outgoing
+ portion of the stream.
+ </tp:docstring>
+ <arg name="Reason" type="u" tp:type="Call_State_Change_Reason"
+ direction="in"/>
+ <arg name="Error" type="s" tp:type="DBus_Error_Name" direction="in"/>
+ <arg name="Message" type="s" direction="in"/>
+ </method>
+
+ <property name="ReceivingState" tp:name-for-bindings="Receiving_State"
+ type="u" tp:type="Stream_Flow_State" access="read">
+ <tp:docstring>
+ The counterpart of <tp:member-ref>SendingState</tp:member-ref>.
+ Indicates whether the streaming implementation is/should be expecting
+ to receive media for this stream. The CM should only tell the
+ streaming implementation to stop receiving if it has been told to put
+ the stream on hold, or the stream has been removed from the call.
+ </tp:docstring>
+ </property>
+
+ <signal name="ReceivingStateChanged"
+ tp:name-for-bindings="Receiving_State_Changed">
+ <tp:docstring>
+ Change notification for <tp:member-ref>ReceivingState</tp:member-ref>.
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="Stream_Flow_State">
+ <tp:docstring>
+ The new value of ReceivingState.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="CompleteReceivingStateChange"
+ tp:name-for-bindings="Complete_Receiving_State_Change">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called in response to
+ <tp:member-ref>ReceivingStateChanged</tp:member-ref>(Pending_*, *) to
+ indicate that the media state has successfully progressed from
+ Pending_{Start, Stop, Pause} to the corresponding non-pending
+ state.</p>
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="Stream_Flow_State" direction="in">
+ <tp:docstring>
+ The new (non-pending) value of ReceivingState.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The state change made no sense, and was ignored by the CM. The
+ most likely cause for this is a race-condition between the CM
+ emitting a new state change and the streaming implementation
+ responding to the previous state change.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="ReportReceivingFailure"
+ tp:name-for-bindings="Report_Receiving_Failure">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Can be called at any point to indicate a failure in the outgoing
+ portion of the stream.
+ </tp:docstring>
+ <arg name="Reason" type="u" tp:type="Call_State_Change_Reason"
+ direction="in"/>
+ <arg name="Error" type="s" tp:type="DBus_Error_Name" direction="in"/>
+ <arg name="Message" type="s" direction="in"/>
+ </method>
+
+ <method name="SetCredentials" tp:name-for-bindings="Set_Credentials">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Used to set the username fragment and password for streams that have
+ global credentials.</p>
+ </tp:docstring>
+ <arg name="Username" type="s" direction="in">
+ <tp:docstring>
+ The username to use when authenticating on the stream.
+ </tp:docstring>
+ </arg>
+ <arg name="Password" type="s" direction="in">
+ <tp:docstring>
+ The password to use when authenticating on the stream.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <tp:enum type="u" name="Call_Stream_Candidate_Type">
+ <tp:docstring>
+ The network topology that an IP candidate represents. This can
+ sometimes be used to infer what kind of performance characteristics
+ (latency, bandwith, etc) can be expected of connections made to this
+ candidate.
+ </tp:docstring>
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ This is not an IP candidate. This is a reserved value, and should
+ not be seen on the bus.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Host" value="1">
+ <tp:docstring>
+ This candidate represents a direct connection to the host, as its
+ address is taken directly the host's IP stack.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Server_Reflexive" value="2">
+ <tp:docstring>
+ This candidate probably represents a connection to the host through
+ a NAT device, as its address was discovered by sending a binding
+ request to a STUN server or similar.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Peer_Reflexive" value="3">
+ <tp:docstring>
+ This candidate probably represents a good route between the host and
+ its peer, as its address was discovered by sending a STUN binding
+ request to one of the candidates advertised by the peer.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Relay" value="4">
+ <tp:docstring>
+ This candidate represents the address of a relay server (usually
+ somewhere on the public internet). This candidate is the most likely
+ to work, but all media will go via a relay server, so latency is
+ likely to be higher than other types of candidate.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Multicast" value="5">
+ <tp:docstring>
+ This candidate represents a Multicast group. This value should only
+ appear if the Stream's <tp:member-ref>Transport</tp:member-ref> is
+ set to Multicast.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+
+ <tp:mapping name="Candidate_Info">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Extra information about the candidate. Allowed and mandatory keys
+ depend on the transport protocol used. The following keys are commenly
+ used:</p>
+
+ <dl>
+ <dt><code>type</code> - u</dt>
+ <dd>The type of candidate
+ (<tp:type>Call_Stream_Candidate_Type</tp:type>)</dd>
+
+ <dt><code>foundation</code> - s</dt>
+ <dd>The foundation of this candidate</dd>
+
+ <dt><code>protocol</code> - u</dt>
+ <dd>Underlying protocol of the candidate
+ (<tp:type>Media_Stream_Base_Proto</tp:type>) </dd>
+
+ <dt><code>priority</code> - u</dt>
+ <dd>Priority of the candidate (should be a number between 0 and
+ 65535). Most ICE implementations will prefer the highest priority
+ candidate pair that manages to connect. For backwards
+ compatibility with non-ICE SIP clients, the lowest priority
+ candidate may be sent as a raw UDP fallback candidate.
+ It is recommended that a relay candidate is used as the lowest
+ priority candidate if possible. If both IPv4 and IPv6 raw udp
+ fallback candidates are available, they should be set to the
+ same priority and advertised to the CM at the same time. The CM
+ will decide which to advertise to the remote end.</dd>
+
+ <dt><code>base-ip</code> - s</dt>
+ <dd>The underlying Host address where media sent to this
+ (non-host-type) candidate will eventually arrive.</dd>
+
+ <dt><code>base-port</code> - u</dt>
+ <dd>The underlying Host port where media sent to this
+ (non-host-type) candidate will eventually arrive.</dd>
+
+ <dt><code>username</code> - s</dt>
+ <dd>Username of this candidate
+ (only if credentials are per candidate)</dd>
+
+ <dt><code>password</code> - s</dt>
+ <dd>Password of this candidate
+ (only if credentials are per candidate)</dd>
+
+ <dt><code>ttl</code> - u</dt>
+ <dd>The TTL mandated for RTP/RTCP packets sent to a multicast group
+ (only valid for Multicast Streams)</dd>
+ </dl>
+ </tp:docstring>
+ <tp:member name="Key" type="s">
+ <tp:docstring>One of the well-known keys documented here, or an
+ implementation-specific key.</tp:docstring>
+ </tp:member>
+ <tp:member name="Value" type="v">
+ <tp:docstring>The value corresponding to that key.</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:enum type="u" name="Stream_Component">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Media streams can use more than one UDP socket: one for RTP (data)
+ and one for RTCP (control). Most of the time, they are adjacent
+ to each other, but some protocols (xmpp) signal each port separately.
+ </tp:docstring>
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ The stream transport type is unknown or not applicable
+ (should not appear over dbus).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Data" value="1">
+ <tp:docstring>
+ This is the high-traffic data socket, containing the audio/video
+ data for the stream.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Control" value="2">
+ <tp:docstring>
+ This is the low-traffic control socket, usually containing feedback
+ about packet loss etc.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Candidate" array-name="Candidate_List">
+ <tp:docstring>A Stream Candidate.</tp:docstring>
+ <tp:member name="Component" type="u" tp:type="Stream_Component">
+ <tp:docstring>The component number.</tp:docstring>
+ </tp:member>
+ <tp:member name="IP" type="s">
+ <tp:docstring>The IP address to use.</tp:docstring>
+ </tp:member>
+ <tp:member name="Port" type="u">
+ <tp:docstring>The port number to use.</tp:docstring>
+ </tp:member>
+ <tp:member name="Info" type="a{sv}" tp:type="Candidate_Info">
+ <tp:docstring>Additional information about the candidate.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="AddCandidates" tp:name-for-bindings="Add_Candidates">
+ <tp:docstring>
+ Add candidates to the
+ <tp:member-ref>LocalCandidates</tp:member-ref> property and
+ signal them to the remote contact(s). Note that connection managers
+ MAY delay the sending of candidates until
+ <tp:member-ref>FinishInitialCandidates</tp:member-ref> is called.
+ </tp:docstring>
+ <arg name="Candidates" direction="in"
+ type="a(usua{sv})" tp:type="Candidate[]">
+ <tp:docstring>
+ The candidates to be added.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="FinishInitialCandidates"
+ tp:name-for-bindings="Finish_Initial_Candidates">
+ <tp:docstring>
+ This indicates to the CM that the initial batch of candidates
+ has been added, and should now be processed/sent to the remote side.
+ <tp:rationale>
+ Protocols supporting Raw UDP SHOULD wait for FinishInitialCandidates,
+ and then set the lowest priority candidate as the Raw UDP candidate.
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <tp:enum type="u" name="Stream_Transport_Type">
+ <tp:changed version="0.21.2">WLM_8_5 was removed</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A transport that can be used for streaming.
+ </tp:docstring>
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ The stream transport type is unknown or not applicable
+ (for streams that do not have a configurable transport).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Raw_UDP" value="1">
+ <tp:docstring>
+ Raw UDP, with or without STUN. All streaming clients are assumed to
+ support this transport, so there is no handler capability token for
+ it in the <tp:dbus-ref namespace="ofdT.Channel.Type"
+ >Call1</tp:dbus-ref> interface.
+ [This corresponds to "none" or "stun" in the old Media.StreamHandler
+ interface.]
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="ICE" value="2">
+ <tp:docstring>
+ Interactive Connectivity Establishment, as defined by RFC
+ 5245. Note that this value covers ICE-UDP only.
+ [This corresponds to "ice-udp" in the old
+ Media.StreamHandler interface.]
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="GTalk_P2P" value="3">
+ <tp:docstring>
+ Google Talk peer-to-peer connectivity establishment, as implemented
+ by libjingle 0.3.
+ [This corresponds to "gtalk-p2p" in the old Media.StreamHandler
+ interface.]
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="WLM_2009" value="4">
+ <tp:docstring>
+ The transport used by Windows Live Messenger 2009 or later, which
+ resembles ICE draft 19.
+ [This corresponds to "wlm-2009" in the old Media.StreamHandler
+ interface.]
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="SHM" value="5">
+ <tp:added version="0.21.2"/>
+ <tp:docstring>
+ Shared memory transport, as implemented by the GStreamer
+ shmsrc and shmsink plugins.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Multicast" value="6">
+ <tp:added version="0.21.5"/>
+ <tp:docstring>
+ Multicast transport.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="Transport" tp:name-for-bindings="Transport"
+ type="u" tp:type="Stream_Transport_Type" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The transport for this stream.
+ </tp:docstring>
+ </property>
+
+ <property name="LocalCandidates" tp:name-for-bindings="Local_Candidates"
+ type="a(usua{sv})" tp:type="Candidate[]" access="read">
+ <tp:docstring>
+ [FIXME]. Change notification is via the
+ <tp:member-ref>LocalCandidatesAdded</tp:member-ref> signal.
+ </tp:docstring>
+ </property>
+
+ <signal name="LocalCandidatesAdded"
+ tp:name-for-bindings="Local_Candidates_Added">
+ <tp:docstring>
+ Emitted when local candidates are added to the
+ <tp:member-ref>LocalCandidates</tp:member-ref> property.
+ </tp:docstring>
+ <arg name="Candidates" type="a(usua{sv})" tp:type="Candidate[]">
+ <tp:docstring>
+ Candidates that have been added.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:struct name="Stream_Credentials">
+ <tp:docstring>A username and password pair.</tp:docstring>
+
+ <tp:member name="Username" type="s">
+ <tp:docstring>The username.</tp:docstring>
+ </tp:member>
+
+ <tp:member name="Password" type="s">
+ <tp:docstring>The password.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="LocalCredentials" tp:name-for-bindings="Local_Credentials"
+ type="(ss)" tp:type="Stream_Credentials" access="read">
+ <tp:docstring>
+ The local credentials are sent to the remote site over the
+ signalling protocol. They are used in ICE to make sure that
+ the connectivity checks come from the right peer. Change
+ notification is via the
+ <tp:member-ref>LocalCredentialsChanged</tp:member-ref> signal.
+
+ This property will be a pair of empty strings if ICE has not yet been
+ started.
+ </tp:docstring>
+ </property>
+
+ <signal name="LocalCredentialsChanged"
+ tp:name-for-bindings="Local_Credentials_Changed">
+ <tp:changed version="0.21.2">renamed from LocalCredentailsSet</tp:changed>
+ <tp:docstring>
+ Emitted when the value of
+ <tp:member-ref>LocalCredentials</tp:member-ref> changes to a non-empty
+ value. This should only happen when the streaming implementation calls
+ <tp:member-ref>SetCredentials</tp:member-ref>, so this signal is
+ mostly useful for debugging.
+ </tp:docstring>
+ <arg name="Username" type="s" />
+ <arg name="Password" type="s" />
+ </signal>
+
+ <signal name="RelayInfoChanged"
+ tp:name-for-bindings="Relay_Info_Changed">
+ <tp:docstring>
+ Emitted when the value of
+ <tp:member-ref>RelayInfo</tp:member-ref> changes.
+ </tp:docstring>
+ <arg name="Relay_Info" type="aa{sv}" tp:type="String_Variant_Map[]" />
+ </signal>
+
+ <signal name="STUNServersChanged"
+ tp:name-for-bindings="STUN_Servers_Changed">
+ <tp:docstring>
+ Emitted when the value of
+ <tp:member-ref>STUNServers</tp:member-ref> changes.
+ </tp:docstring>
+ <arg name="Servers" type="a(sq)" tp:type="Socket_Address_IP[]" />
+ </signal>
+
+ <property name="STUNServers" tp:name-for-bindings="STUN_Servers"
+ type="a(sq)" tp:type="Socket_Address_IP[]" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The IP addresses of possible STUN servers to use for NAT
+ traversal, as dotted-quad IPv4 address literals or RFC2373
+ IPv6 address literals. Change notification is via the
+ <tp:member-ref>STUNServersChanged</tp:member-ref>
+ signal. The IP addresses MUST NOT be given as DNS hostnames.</p>
+
+ <tp:rationale>
+ High-quality connection managers already need an asynchronous
+ DNS resolver, so they might as well resolve this name to an IP
+ to make life easier for streaming implementations.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="RelayInfo" type="aa{sv}" access="read"
+ tp:type="String_Variant_Map[]" tp:name-for-bindings="Relay_Info">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of mappings describing TURN or Google relay servers
+ available for the client to use in its candidate gathering, as
+ determined from the protocol. Well-known map keys are:</p>
+
+ <dl>
+ <dt><code>ip</code> - s</dt>
+ <dd>The IP address of the relay server as a dotted-quad IPv4
+ address literal or an RFC2373 IPv6 address literal. This MUST NOT
+ be a DNS hostname.
+
+ <tp:rationale>
+ High-quality connection managers already need an asynchronous
+ DNS resolver, so they might as well resolve this name to an IP
+ and make life easier for streaming implementations.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>type</code> - s</dt>
+ <dd>
+ <p>Either <code>udp</code> for UDP (UDP MUST be assumed if this
+ key is omitted), <code>tcp</code> for TCP, or
+ <code>tls</code>.</p>
+
+ <p>The precise meaning of this key depends on the
+ <tp:member-ref>Transport</tp:member-ref> property: if
+ Transport is ICE, <code>tls</code> means
+ TLS over TCP as referenced by ICE draft 19, and if
+ Transport is GTalk_P2P, <code>tls</code> means
+ a fake SSL session over TCP as implemented by libjingle.</p>
+ </dd>
+
+ <dt><code>port</code> - q</dt>
+ <dd>The UDP or TCP port of the relay server as an ASCII unsigned
+ integer</dd>
+
+ <dt><code>unique-id</code> - s</dt>
+ <dd>A string identifying the relay server. If two RelayInfo entries
+ have the same unique-id, but different <code>type</code>s, there
+ is usually little point in connecting to both. Use
+ <code>priority</code> to determine which version to prefer in this
+ case. Can also be used by the streaming implementation to avoid
+ connecting to the same relay multiple times if relaying is
+ required for both audio and video.</dd>
+
+ <dt><code>priority</code> - u</dt>
+ <dd>A number determining which version of a server to prefer (if
+ multiple are present with the same <code>unique-id</code>,
+ the one with the highest priority should be used, or the streaming
+ implementation should use the one whose <code>type</code> has the
+ most desirable properties)</dd>
+
+ <dt><code>username</code> - s</dt>
+ <dd>The username to use</dd>
+
+ <dt><code>password</code> - s</dt>
+ <dd>The password to use</dd>
+
+ <dt><code>component</code> - u</dt>
+ <dd>The component number to use this relay server for, as an
+ ASCII unsigned integer; if not included, this relay server
+ may be used for any or all components.
+
+ <tp:rationale>
+ In ICE draft 6, as used by Google Talk, credentials are only
+ valid once, so each component needs relaying separately.
+ </tp:rationale>
+ </dd>
+ </dl>
+
+ <tp:rationale>
+ <p>An equivalent of the gtalk-p2p-relay-token property on
+ MediaSignalling channels is not included here. The connection
+ manager should be responsible for making the necessary HTTP
+ requests to turn the token into a username and password.</p>
+ </tp:rationale>
+
+ <p>The type of relay server that this represents depends on
+ the value of the <tp:member-ref>Transport</tp:member-ref>
+ property. If Transport is ICE, this is a TURN server;
+ if Transport is GTalk_P2P, this is a Google relay server;
+ otherwise, the meaning of RelayInfo is undefined.</p>
+
+ <p>If relaying is not possible for this stream, the list is
+ empty.</p>
+
+ <p>Change notification is given via the
+ <tp:member-ref>RelayInfoChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="ServerInfoRetrieved"
+ tp:name-for-bindings="Server_Info_Retrieved">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Signals that the initial information about STUN and Relay servers
+ has been retrieved, i.e. the
+ <tp:member-ref>HasServerInfo</tp:member-ref> property is
+ now true.</p>
+ </tp:docstring>
+ </signal>
+
+ <property name="HasServerInfo" type="b"
+ tp:name-for-bindings="Has_Server_Info" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if all the initial information about STUN servers and Relay
+ servers has been retrieved. Change notification is via the
+ <tp:member-ref>ServerInfoRetrieved</tp:member-ref> signal.</p>
+
+ <tp:rationale>
+ Streaming implementations that can't cope with STUN and
+ relay servers being added later SHOULD wait for this
+ property to become true before proceeding.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <signal name="EndpointsChanged"
+ tp:name-for-bindings="Endpoints_Changed">
+ <tp:docstring>
+ Emitted when the <tp:member-ref>Endpoints</tp:member-ref> property
+ changes.
+ </tp:docstring>
+ <arg name="Endpoints_Added" type="ao">
+ <tp:docstring>
+ Endpoints that were added.
+ </tp:docstring>
+ </arg>
+ <arg name="Endpoints_Removed" type="ao">
+ <tp:docstring>
+ Endpoints that no longer exist.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Endpoints" tp:name-for-bindings="Endpoints"
+ type="ao" access="read">
+ <tp:docstring>
+ <p>The list of <tp:dbus-ref namespace="ofdT.Call1.Stream"
+ >Endpoint</tp:dbus-ref> objects that exist for this
+ stream.</p>
+
+ <p>Change notification is via the
+ <tp:member-ref>EndpointsChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="ICERestartRequested"
+ tp:name-for-bindings="ICE_Restart_Requested">
+ <tp:docstring>
+ Emitted when the remote side requests an ICE restart (e.g. third party
+ call control, when the remote endpoint changes). The streaming
+ implementation should call
+ <tp:member-ref>SetCredentials</tp:member-ref> again.
+ </tp:docstring>
+ </signal>
+
+ <property name="ICERestartPending"
+ tp:name-for-bindings="ICE_Restart_Pending" access="read" type="b">
+ <tp:docstring>
+ State recovery for <tp:member-ref>ICERestartRequested</tp:member-ref>.
+ Set when the signal is emitted, and unset when
+ <tp:member-ref>SetCredentials</tp:member-ref> is called.
+ Useful for debugging.
+ </tp:docstring>
+ </property>
+
+ <method name="Fail" tp:name-for-bindings="Fail">
+ <tp:docstring>
+ Signal an unrecoverable error for this stream, and remove it. If all
+ streams are removed from a content, then it will also be removed.
+ </tp:docstring>
+ <arg direction="in" name="Reason" type="(uuss)"
+ tp:type="Call_State_Reason">
+ <tp:docstring>
+ A structured reason for stream removal.
+ </tp:docstring>
+ </arg>
+ </method>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel.xml b/spec/spec/Channel.xml
new file mode 100644
index 000000000..11d3e509c
--- /dev/null
+++ b/spec/spec/Channel.xml
@@ -0,0 +1,557 @@
+<?xml version="1.0" ?>
+<node name="/Channel" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2005-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2005-2009 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel">
+
+ <property name="ChannelType" type="s" tp:type="DBus_Interface"
+ access="read" tp:name-for-bindings="Channel_Type">
+ <tp:added version="0.17.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel's type. This cannot change once the channel has
+ been created.</p>
+
+ <p>For compatibility between older connection managers and newer
+ clients, if this is unavailable or is an empty string,
+ clients MUST use the result of calling
+ <tp:member-ref>GetChannelType</tp:member-ref>.</p>
+
+ <tp:rationale>
+ The GetAll method lets clients retrieve all properties in one
+ round-trip, which is desirable.
+ </tp:rationale>
+
+ <p>When requesting a channel, the request MUST specify a channel
+ type, and the request MUST fail if the specified channel type
+ cannot be supplied.</p>
+
+ <tp:rationale>
+ Common sense.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" tp:type="DBus_Interface[]" access="read">
+ <tp:added version="0.17.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Extra interfaces provided by this channel. This SHOULD NOT include
+ the channel type and the Channel interface itself, and cannot
+ change once the channel has been created.</p>
+
+ <p>For compatibility between older connection managers and newer
+ clients, if this is unavailable, or if this is an empty list and
+ <tp:member-ref>ChannelType</tp:member-ref> is an empty string,
+ clients MUST use the result of calling
+ <tp:member-ref>GetInterfaces</tp:member-ref> instead. If this is an
+ empty list but ChannelType is non-empty, clients SHOULD NOT call
+ GetInterfaces; this implies that connection managers that implement
+ the ChannelType property MUST also implement the Interfaces property
+ correctly.</p>
+
+ <tp:rationale>
+ The GetAll method lets clients retrieve all properties in one
+ round-trip, which is desirable.
+ </tp:rationale>
+
+ <p>When requesting a channel with a particular value for this
+ property, the request must fail without side-effects unless the
+ connection manager expects to be able to provide a channel whose
+ interfaces include at least the interfaces requested.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetHandle" type="u" access="read" tp:type="Handle"
+ tp:name-for-bindings="Target_Handle">
+ <tp:added version="0.17.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The handle (a representation for the identifier) of the contact,
+ chatroom, etc. with which this handle communicates. Its type
+ is given by the <tp:member-ref>TargetHandleType</tp:member-ref>
+ property.</p>
+
+ <p>This is fixed for the lifetime of the channel, so channels which
+ could potentially be used to communicate with multiple contacts,
+ and do not have an identity of their own (such as a Handle_Type_Room
+ handle), must have TargetHandleType set to Handle_Type_None and
+ TargetHandle set to 0.</p>
+
+ <p>Unlike in the telepathy-spec 0.16 API, there is no particular
+ uniqueness guarantee - there can be many channels with the same
+ (channel type, handle type, handle) tuple. This is necessary
+ to support conversation threads in XMPP and SIP, for example.</p>
+
+ <p>If this is present in a channel request, it must be nonzero,
+ <tp:member-ref>TargetHandleType</tp:member-ref>
+ MUST be present and not Handle_Type_None, and
+ <tp:member-ref>TargetID</tp:member-ref> MUST NOT be
+ present. Properties from
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface">Addressing.DRAFT</tp:dbus-ref>
+ MUST NOT be present.</p>
+
+ <p>The channel that satisfies the request MUST either:</p>
+
+ <ul>
+ <li>have the specified TargetHandle property; or</li>
+ <li>have <tp:member-ref>TargetHandleType</tp:member-ref> =
+ Handle_Type_None, TargetHandle = 0, and be configured such that
+ it could communicate with the specified handle in some other way
+ (e.g. have the requested contact handle in its Group
+ interface)</li>
+ </ul>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetID" tp:name-for-bindings="Target_ID"
+ type="s" access="read">
+ <tp:added version="0.17.9"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The string that would result from inspecting the
+ <tp:member-ref>TargetHandle</tp:member-ref>
+ property (i.e. the identifier in the IM protocol of the contact,
+ room, etc. with which this channel communicates), or the empty
+ string if the TargetHandle is 0.</p>
+
+ <tp:rationale>
+ <p>The presence of this property avoids the following race
+ condition:</p>
+
+ <ul>
+ <li>New channel C is signalled with target handle T</li>
+ <li>Client calls <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>(CONTACT,
+ [T])</li>
+ <li>Channel C closes, removing the last reference to handle T</li>
+ <li><tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>(CONTACT,
+ [T]) returns an error</li>
+ </ul>
+ </tp:rationale>
+
+ <p>If this is present in a channel request,
+ <tp:member-ref>TargetHandleType</tp:member-ref>
+ MUST be present and not Handle_Type_None, and
+ <tp:member-ref>TargetHandle</tp:member-ref> MUST NOT be
+ present. Properties from
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface">Addressing.DRAFT</tp:dbus-ref>
+ MUST NOT be present.The request MUST fail with error InvalidHandle,
+ without side-effects, if the requested TargetID would not be
+ accepted by
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection">RequestHandles</tp:dbus-ref>.</p>
+
+ <p>The returned channel must be related to the handle corresponding
+ to the given identifier, in the same way as if TargetHandle
+ had been part of the request instead.</p>
+
+ <tp:rationale>
+ <p>Requesting channels with a string identifier saves a round-trip
+ (the call to RequestHandles). It also allows the channel
+ dispatcher to accept a channel request for an account that is not
+ yet connected (and thus has no valid handles), bring the account
+ online, and pass on the same parameters to the new connection's
+ CreateChannel method.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetHandleType" type="u" access="read"
+ tp:type="Handle_Type" tp:name-for-bindings="Target_Handle_Type">
+ <tp:added version="0.17.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The type of <tp:member-ref>TargetHandle</tp:member-ref>.</p>
+
+ <p>If this is omitted from a channel request, connection managers
+ SHOULD treat this as equivalent to Handle_Type_None.</p>
+
+ <p>If this is omitted or is Handle_Type_None,
+ <tp:member-ref>TargetHandle</tp:member-ref> and
+ <tp:member-ref>TargetID</tp:member-ref> MUST be omitted from the
+ request.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="Close" tp:name-for-bindings="Close">
+ <tp:docstring>
+ Request that the channel be closed. This is not the case until
+ the <tp:member-ref>Closed</tp:member-ref> signal has been emitted, and
+ depending on the connection
+ manager this may simply remove you from the channel on the server,
+ rather than causing it to stop existing entirely. Some channels
+ such as contact list channels may not be closed.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ This channel may never be closed, e.g. a contact list
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This channel is not currently in a state where it can be closed,
+ e.g. a non-empty user-defined contact group
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="Closed" tp:name-for-bindings="Closed">
+ <tp:docstring>
+ Emitted when the channel has been closed. Method calls on the
+ channel are no longer valid after this signal has been emitted,
+ and the connection manager may then remove the object from the bus
+ at any point.
+ </tp:docstring>
+ </signal>
+
+ <method name="GetChannelType" tp:name-for-bindings="Get_Channel_Type">
+ <tp:deprecated version="0.17.7">Use the ChannelType
+ property if possible.</tp:deprecated>
+ <arg direction="out" type="s" tp:type="DBus_Interface"
+ name="Channel_Type">
+ <tp:docstring>The interface name</tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns the interface name for the type of this channel. Clients
+ SHOULD use the <tp:member-ref>ChannelType</tp:member-ref> property
+ instead, falling back to this method only if necessary.
+
+ <tp:rationale>
+ The GetAll method lets clients retrieve all properties in one
+ round-trip.
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <method name="GetHandle" tp:name-for-bindings="Get_Handle">
+ <tp:deprecated version="0.17.7">Use the TargetHandleType
+ and TargetHandle properties if possible.</tp:deprecated>
+ <arg direction="out" type="u" tp:type="Handle_Type"
+ name="Target_Handle_Type">
+ <tp:docstring>
+ The same as TargetHandleType.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="u" tp:type="Handle" name="Target_Handle">
+ <tp:docstring>
+ The same as TargetHandle.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns the handle type and number if this channel represents a
+ communication with a particular contact, room or server-stored list, or
+ zero if it is transient and defined only by its contents. Clients
+ SHOULD use the <tp:member-ref>TargetHandle</tp:member-ref> and
+ <tp:member-ref>TargetHandleType</tp:member-ref> properties instead,
+ falling back to this method only if necessary.
+
+ <tp:rationale>
+ The GetAll method lets clients retrieve all properties in one
+ round-trip.
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <method name="GetInterfaces" tp:name-for-bindings="Get_Interfaces">
+ <tp:deprecated version="0.17.7">Use the Interfaces
+ property if possible.</tp:deprecated>
+ <arg direction="out" type="as" tp:type="DBus_Interface[]"
+ name="Interfaces">
+ <tp:docstring>
+ An array of the D-Bus interface names
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get the optional interfaces implemented by the channel.
+ Clients SHOULD use the <tp:member-ref>Interfaces</tp:member-ref>
+ property instead, falling back to this method only if necessary.
+
+ <tp:rationale>
+ The GetAll method lets clients retrieve all properties in one
+ round-trip.
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <property name="Requested" tp:name-for-bindings="Requested"
+ type="b" access="read">
+ <tp:added version="0.17.13">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if this channel was created in response to a local request,
+ such as a call to
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.RequestChannel</tp:dbus-ref>
+ or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>.</p>
+
+ <tp:rationale>
+ <p>The idea of this property is to distinguish between "incoming"
+ and "outgoing" channels, in a way that doesn't break down when
+ considering special cases like contact lists that are automatically
+ created on connection to the server, or chatrooms that an
+ IRC proxy/bouncer like irssi-proxy or bip was already in.</p>
+
+ <p>The reason we want to make that distinction is that UIs for
+ things that the user explicitly requested should start up
+ automatically, whereas for incoming messages and VoIP calls we
+ should first ask the user whether they want to open the messaging
+ UI or accept the call.</p>
+ </tp:rationale>
+
+ <p>If the channel was not explicitly requested (even if it was
+ created as a side-effect of a call to one of those functions,
+ e.g. because joining a Tube in a MUC context on XMPP implies
+ joining that MUC), then this property is false.</p>
+
+ <p>For compatibility with older connection managers, clients SHOULD
+ assume that this property is true if they see a channel announced
+ by the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.NewChannel</tp:dbus-ref>
+ signal with the suppress_handler parameter set to true.</p>
+
+ <tp:rationale>
+ <p>In a correct connection manager, the only way to get such a
+ channel is to request it.</p>
+ </tp:rationale>
+
+ <p>Clients MAY additionally assume that this property is false
+ if they see a channel announced by the NewChannel signal with the
+ suppress_handler parameter set to false.</p>
+
+ <tp:rationale>
+ <p>This is more controversial, since it's possible to get that
+ parameter set to false by requesting a channel. However, there's
+ no good reason to do so, and we've deprecated this practice.</p>
+
+ <p>In the particular case of the channel dispatcher, the only
+ side-effect of wrongly thinking a channel is unrequested
+ is likely to be that the user has to confirm that they want to
+ use it, so it seems fairly harmless to assume in the channel
+ dispatcher that channels with suppress_handler false are
+ indeed unrequested.</p>
+ </tp:rationale>
+
+ <p>It does not make sense for this property to be in channel
+ requests—it will always be true for channels returned by
+ CreateChannel, and callers of EnsureChannel cannot control whether an
+ existing channel was originally requested locally—so it MUST NOT
+ be accepted.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InitiatorHandle" type="u" tp:type="Contact_Handle"
+ access="read" tp:name-for-bindings="Initiator_Handle">
+ <tp:added version="0.17.13">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The contact who initiated the channel; for instance, the contact
+ who invited the local user to a chatroom, or the contact who
+ initiated a call.</p>
+
+ <p>This does <em>not</em> necessarily represent the contact who
+ created the underlying protocol-level construct. For instance, if
+ Rob creates a chatroom, Will joins that chatroom, and Will invites Simon
+ to join it, then Simon will see Will as the InitiatorHandle of the
+ channel representing the chatroom.</p>
+
+ <tp:rationale>
+ <p>The room creator is generally a less useful piece of information
+ than the inviter, is less likely to be available at invitation
+ time (i.e. can't necessarily be an immutable property), and is
+ less likely to be available at all. The creator of a chatroom
+ is not currently available via Telepathy; if added in future, it
+ is likely to be made available as a property on the Chatroom
+ interface (<a
+ href="http://bugs.freedesktop.org/show_bug.cgi?id=23151">bug 23151</a>).</p>
+ </tp:rationale>
+
+ <p>For channels requested by the
+ local user, this MUST be the value of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.SelfHandle</tp:dbus-ref>
+ at the time the channel was created (i.e. not a channel-specific
+ handle).</p>
+
+ <tp:rationale>
+ <p>On some protocols, the SelfHandle may change (as signalled by
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.SelfHandleChanged</tp:dbus-ref>),
+ but this property is immutable. Hence, locally-requested channels'
+ InitiatorHandle and InitiatorID may not match the current
+ SelfHandle; <tp:member-ref>Requested</tp:member-ref> can be used to
+ determine whether the channel was created locally.</p>
+ </tp:rationale>
+
+ <p>For channels requested by a remote user, this MUST be their handle.
+ If unavailable or not applicable, this MUST be 0 (for instance,
+ contact lists are not really initiated by anyone in particular, and
+ it's easy to imagine a protocol where chatroom invitations can be
+ anonymous).</p>
+
+ <p>For channels with the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Group</tp:dbus-ref>
+ interface, this SHOULD be the same
+ contact who is signalled as the "Actor" causing the self-handle
+ to be placed in the local-pending set.</p>
+
+ <p>This SHOULD NOT be a channel-specific handle, if possible.</p>
+
+ <p>It does not make sense for this property to be in channel
+ requests - the initiator will always be the local user - so it
+ MUST NOT be accepted.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InitiatorID" type="s" access="read"
+ tp:name-for-bindings="Initiator_ID">
+ <tp:added version="0.17.13">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The string that would result from inspecting the
+ <tp:member-ref>InitiatorHandle</tp:member-ref>
+ property (i.e. the initiator's identifier in the IM protocol).</p>
+
+ <tp:rationale>
+ <p>The presence of this property avoids the following race
+ condition:</p>
+
+ <ul>
+ <li>New StreamedMedia channel C is signalled with initiator
+ handle I</li>
+ <li>Client calls <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>(CONTACT,
+ [I])</li>
+ <li>Channel C closes, removing the last reference to handle I</li>
+ <li><tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>(CONTACT,
+ [I]) returns an error</li>
+ <li>Client can indicate that a call was missed, but not who
+ called!</li>
+ </ul>
+ </tp:rationale>
+
+ <p>It does not make sense for this property to be in channel
+ requests - the initiator will always be the local user - so it
+ MUST NOT be accepted.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>All communication in the Telepathy framework is carried out via channel
+ objects which are created and managed by connections. This interface must
+ be implemented by all channel objects, along with one single channel type,
+ such as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Type.ContactList</tp:dbus-ref>
+ which represents a list of people (such as a buddy list) or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Type.Text</tp:dbus-ref> which
+ represents a channel over which textual messages are sent and received.</p>
+
+ <p>Each Channel's object path MUST start with the object path of
+ its associated <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>, followed
+ by '/'. There MAY be any number of additional object-path components,
+ which clients MUST NOT attempt to parse.</p>
+
+ <tp:rationale>
+ <p>This ensures that Channel object paths are unique, even between
+ Connections and CMs, because Connection object paths are
+ guaranteed-unique via their link to the well-known bus name.</p>
+
+ <p>If all connection managers in use are known to comply with at least
+ spec version 0.17.10, then the Connection's object path can
+ even be determined from the Channel's without any additional
+ information, by taking the first 7 components.</p>
+ </tp:rationale>
+
+ <p>Each channel has a number of immutable properties (which cannot vary
+ after the channel has been announced with <tp:dbus-ref
+ namespace='ofdT.Connection.Interface.Requests'>NewChannels</tp:dbus-ref>),
+ provided to clients in the
+ <tp:dbus-ref namespace='ofdT.Client.Observer'>ObserveChannels</tp:dbus-ref>,
+ <tp:dbus-ref namespace='ofdT.Client.Approver'>AddDispatchOperation</tp:dbus-ref> and
+ <tp:dbus-ref namespace='ofdT.Client.Handler'>HandleChannels</tp:dbus-ref>
+ methods to permit immediate identification of the channel. This interface
+ contains immutable properties common to all channels. In brief:</p>
+
+ <ul>
+ <li><tp:member-ref>ChannelType</tp:member-ref> specifies the kind of
+ communication carried out on this channel;</li>
+ <li><tp:member-ref>TargetHandleType</tp:member-ref>,
+ <tp:member-ref>TargetHandle</tp:member-ref> and
+ <tp:member-ref>TargetID</tp:member-ref> specify the entity with which
+ this channel communicates, such as the other party in a 1-1 call, or
+ the name of a multi-user chat room;</li>
+ <li><tp:member-ref>InitiatorHandle</tp:member-ref> and
+ <tp:member-ref>InitiatorID</tp:member-ref> specify who created this
+ channel;</li>
+ <li><tp:member-ref>Requested</tp:member-ref> indicates whether the local
+ user requested this channel, or whether it is an incoming call, a text
+ conversation started by a remote contact, a chatroom invitation,
+ etc.</li>
+ </ul>
+
+ <p>Other optional <tp:member-ref>Interfaces</tp:member-ref> can be
+ implemented to indicate other available
+ functionality, such as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Group</tp:dbus-ref>
+ if the channel contains a number of contacts, <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Password</tp:dbus-ref>
+ to indicate that a channel may have a password set to require entry, and
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.ChatState</tp:dbus-ref>
+ for typing notifications. The interfaces implemented may not vary after
+ the channel has been created. These other interfaces (along with the
+ interface named by <tp:member-ref>ChannelType</tp:member-ref>) may
+ themselves specify immutable properties to be announced up-front along
+ with the properties on this interface.</p>
+
+ <p>Some channels are “anonymous”, with
+ <tp:member-ref>TargetHandleType</tp:member-ref> set to <code>None</code>,
+ which indicates that the channel is defined by some other properties. For
+ instance, transient ad-hoc chat rooms may be defined only by their members (as visible
+ through the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Group</tp:dbus-ref>
+ interface), and <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>ContactSearch</tp:dbus-ref>
+ channels represent a single search attempt for a particular <tp:dbus-ref
+ namespace='ofdT.Channel.Type.ContactSearch'>Server</tp:dbus-ref>.</p>
+
+ <p>Specific connection manager implementations may implement channel types and
+ interfaces which are not contained within this specification in order to
+ support further functionality. To aid interoperability between client and
+ connection manager implementations, the interfaces specified here should be
+ used wherever applicable, and new interfaces made protocol-independent
+ wherever possible. Because of the potential for 3rd party interfaces adding
+ methods or signals with conflicting names, the D-Bus interface names should
+ always be used to invoke methods and bind signals.</p>
+ </tp:docstring>
+
+ <tp:changed version="0.17.7">Previously we guaranteed that, for
+ any handle type other than Handle_Type_None, and for any channel type
+ and any handle, there would be no more than one channel with that
+ combination of channel type, handle type and handle. This guarantee
+ has now been removed in order to accommodate features like message
+ threads.
+ </tp:changed>
+
+ <tp:changed version="0.17.10">Previously we did not explicitly
+ guarantee that Channels' object paths had the Connection's object path
+ as a prefix.
+ </tp:changed>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Bundle.xml b/spec/spec/Channel_Bundle.xml
new file mode 100644
index 000000000..d211525a4
--- /dev/null
+++ b/spec/spec/Channel_Bundle.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Bundle"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.ChannelBundle.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A group of related channels, which should all be dispatched to the
+ same handler if possible.</p>
+
+ <p>Bundles currently have no functionality of their own, so clients
+ SHOULD NOT examine this interface, but should instead treat the
+ bundle object-path as an opaque identifier. If more functionality is
+ added to bundles in future, this interface will be used for capability
+ discovery.</p>
+
+ <p>The lifetime of a bundle is defined by its component channels -
+ as long as one or more channels whose Bundle property is <em>B</em>
+ exist, the bundle <em>B</em> will also exist.</p>
+ </tp:docstring>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read" tp:type="DBus_Interface[]">
+ <tp:docstring>
+ A list of the extra interfaces provided by this channel bundle.
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Dispatch_Operation.xml b/spec/spec/Channel_Dispatch_Operation.xml
new file mode 100644
index 000000000..6ec69a67b
--- /dev/null
+++ b/spec/spec/Channel_Dispatch_Operation.xml
@@ -0,0 +1,483 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Dispatch_Operation"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.ChannelDispatchOperation">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel dispatch operation is an object in the ChannelDispatcher
+ representing a batch of unrequested channels being announced to
+ client
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref>
+ processes.</p>
+
+ <p>These objects can result from new incoming channels or channels
+ which are automatically created for some reason, but cannot result
+ from outgoing requests for channels.</p>
+
+ <p>More specifically, whenever the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.NewChannels</tp:dbus-ref>
+ signal contains channels whose
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
+ property is false, or whenever the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.NewChannel</tp:dbus-ref>
+ signal contains a channel with suppress_handler false,
+ one or more ChannelDispatchOperation objects are created for those
+ channels.</p>
+
+ <p>(If some channels in a NewChannels signal are in different bundles,
+ this is an error. The channel dispatcher SHOULD recover by treating
+ the NewChannels signal as if it had been several NewChannels signals
+ each containing one channel.)</p>
+
+ <p>First, the channel dispatcher SHOULD construct a list of all the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>s
+ that could handle all the channels (based on their <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ property), ordered by
+ priority in some implementation-dependent way. If there are handlers
+ which could handle all the channels, one channel dispatch operation
+ SHOULD be created for all the channels. If there are not, one channel
+ dispatch operation SHOULD be created for each channel, each with
+ a list of channel handlers that could handle that channel.</p>
+
+ <p>If no handler at all can handle a channel, the channel dispatcher
+ SHOULD terminate that channel instead of creating a channel dispatcher
+ for it. It is RECOMMENDED that the channel dispatcher closes
+ the channels using <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Destroyable.Destroy</tp:dbus-ref>
+ if supported, or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>
+ otherwise. As a special case, the channel dispatcher SHOULD NOT close
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">ContactList</tp:dbus-ref>
+ channels, and if Close fails, the channel dispatcher SHOULD ignore
+ that channel.</p>
+
+ <tp:rationale>
+ <p>ContactList channels are strange. We hope to replace them with
+ something better, such as an interface on the Connection, in a
+ future version of this specification.</p>
+ </tp:rationale>
+
+ <p>When listing channel handlers, priority SHOULD be given to
+ channel handlers that are already handling channels from the same
+ bundle.</p>
+
+ <p>If a handler with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">BypassApproval</tp:dbus-ref>
+ <code>= True</code> could handle all of the channels in the dispatch
+ operation, then the channel dispatcher SHOULD call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ on that handler, and (assuming the call succeeds) emit
+ <tp:member-ref>Finished</tp:member-ref> and stop processing those
+ channels without involving any approvers.</p>
+
+ <tp:rationale>
+ <p>Some channel types can be picked up "quietly" by an existing
+ channel handler. If a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ channel is added to an existing bundle containing a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ channel, there shouldn't be
+ any approvers, flashing icons or notification bubbles, if the
+ the UI for the StreamedMedia channel can just add a text box
+ and display the message.</p>
+ </tp:rationale>
+
+ <p>Otherwise, the channel dispatcher SHOULD send the channel dispatch
+ operation to all relevant approvers (in parallel) and wait for an
+ approver to claim the channels or request that they are handled.
+ See
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Approver">AddDispatchOperation</tp:dbus-ref>
+ for more details on this.</p>
+
+ <p>Finally, if the approver requested it, the channel dispatcher SHOULD
+ send the channels to a handler.</p>
+ </tp:docstring>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read" tp:type="DBus_Interface[]">
+ <tp:docstring>
+ A list of the extra interfaces provided by this channel dispatch
+ operation. This property cannot change.
+ </tp:docstring>
+ </property>
+
+ <property name="Connection" tp:name-for-bindings="Connection"
+ type="o" access="read">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ with which the <tp:member-ref>Channels</tp:member-ref> are
+ associated. The well-known bus name to use can be derived from
+ this object path by removing the leading '/' and replacing all
+ subsequent '/' by '.'. This property cannot change.
+ </tp:docstring>
+ </property>
+
+ <property name="Account" tp:name-for-bindings="Account"
+ type="o" access="read">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ with which the <tp:member-ref>Connection</tp:member-ref>
+ and <tp:member-ref>Channels</tp:member-ref> are
+ associated. This property cannot change.
+ </tp:docstring>
+ </property>
+
+ <property name="Channels" tp:name-for-bindings="Channels"
+ type="a(oa{sv})" access="read" tp:type="Channel_Details[]">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s
+ to be dispatched, and their properties. Change notification is via
+ the <tp:member-ref>ChannelLost</tp:member-ref> signal (channels
+ cannot be added to this property, only removed).
+ </tp:docstring>
+ </property>
+
+ <signal name="ChannelLost" tp:name-for-bindings="Channel_Lost">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel has closed before it could be claimed or handled. If
+ this is emitted for the last remaining channel in a channel
+ dispatch operation, it MUST immediately be followed by
+ <tp:member-ref>Finished</tp:member-ref>.</p>
+
+ <p>This signal MUST NOT be emitted until all Approvers that were
+ invoked have returned (successfully or with an error) from
+ their <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Approver">AddDispatchOperation</tp:dbus-ref>
+ method.</p>
+
+ <tp:rationale>
+ <p>This means that Approvers can connect to the ChannelLost signal
+ in a race-free way. Non-approver processes that discover
+ a channel dispatch operation in some way (such as observers)
+ will have to follow the usual "connect to signals then recover
+ state" model - first connect to ChannelLost and
+ <tp:member-ref>Finished</tp:member-ref>,
+ then download <tp:member-ref>Channels</tp:member-ref> (and
+ on error, perhaps assume that the operation has already
+ Finished).</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Channel" type="o">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>
+ that closed.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Error" type="s" tp:type="DBus_Error_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of a D-Bus error indicating why the channel closed. If
+ no better reason can be found,
+ <code>org.freedesktop.Telepathy.Error.NotAvailable</code> MAY
+ be used as a fallback; this means that this error SHOULD NOT be
+ given any more specific meaning.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Message" type="s">
+ <tp:docstring>
+ A string associated with the D-Bus error.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="PossibleHandlers" tp:name-for-bindings="Possible_Handlers"
+ type="as" access="read" tp:type="DBus_Well_Known_Name[]">
+ <tp:docstring>
+ <p>The well known bus names (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>) of the possible
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>s
+ for these channels. The channel dispatcher MUST place the most
+ preferred handlers first, according to some reasonable heuristic.
+ As a result, approvers SHOULD use the first handler by default.</p>
+
+ <p>The heuristic used to prioritize handlers SHOULD give a higher
+ priority to handlers that are already running.</p>
+
+ <tp:rationale>
+ <p>If, for instance, Empathy and Kopete have similar functionality,
+ and Empathy is running, we should prefer to send channels to it
+ rather than launching Kopete via service activation.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="HandleWith" tp:name-for-bindings="Handle_With">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by an approver to accept a channel bundle and request that
+ the given handler be used to handle it.</p>
+
+ <p>If successful, this method will cause the ChannelDispatchOperation
+ object to disappear, emitting
+ <tp:member-ref>Finished</tp:member-ref>.</p>
+
+ <p>However, this method may fail because the dispatch has already been
+ completed and the object has already gone. If this occurs, it
+ indicates that another approver has asked for the bundle to be
+ handled by a particular handler. The approver MUST NOT attempt
+ to interact with the channels further in this case, unless it is
+ separately invoked as the handler.</p>
+
+ <p>Approvers which are also channel handlers SHOULD use
+ <tp:member-ref>Claim</tp:member-ref> instead
+ of HandleWith to request that they can handle a channel bundle
+ themselves.</p>
+
+ <p>(FIXME: list some possible errors)</p>
+
+ <p>If the channel handler raises an error from <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>,
+ this method
+ MAY respond by raising that same error, even if it is not
+ specifically documented here.</p>
+ </tp:docstring>
+
+ <arg direction="in" type="s" tp:type="DBus_Bus_Name" name="Handler">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>) of the channel
+ handler that should handle the channel, or the empty string
+ if the client has no preferred channel handler.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The selected handler is non-empty, but is not a syntactically
+ correct <tp:type>DBus_Bus_Name</tp:type> or does not start with
+ "<code>org.freedesktop.Telepathy.Client.</code>".
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The selected handler is temporarily unable to handle these
+ channels.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The selected handler is syntactically correct, but will never
+ be able to handle these channels (for instance because the channels
+ do not match its HandlerChannelFilter, or because HandleChannels
+ raised NotImplemented).
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+ <tp:docstring>
+ At the time that HandleWith was called, this dispatch operation was
+ processing an earlier call to HandleWith. The earlier call has
+ now succeeded, so some Handler nominated by another approver is
+ now responsible for the channels. In this situation, the second
+ call to HandleWith MUST NOT return until the first one has
+ returned successfully or unsuccessfully, and if the first call
+ to HandleChannels fails, the channel dispatcher SHOULD try to obey
+ the choice of Handler made by the second call to HandleWith.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Claim" tp:name-for-bindings="Claim">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by an approver to claim channels for handling
+ internally. If this method is called successfully, the process
+ calling this method becomes the handler for the channel, but
+ <em>does not</em> have the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ method called on it.</p>
+
+ <p>Clients that call Claim on channels but do not immediately
+ close them SHOULD implement the Handler interface and its
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandledChannels</tp:dbus-ref>
+ property.</p>
+
+ <p>Approvers wishing to reject channels MUST call this method to
+ claim ownership of them, and MUST NOT call
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ on the channels unless/until this method returns successfully.</p>
+
+ <tp:rationale>
+ <p>The channel dispatcher can't know how best to close arbitrary
+ channel types, so it leaves it up to the approver to do so.
+ For instance, for Text channels it is necessary
+ to acknowledge any messages that have already been displayed to
+ the user first - ideally, the approver would display and then
+ acknowledge the messages - or to call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Destroyable.Destroy</tp:dbus-ref>
+ if the destructive behaviour of that method is desired.</p>
+
+ <p>Similarly, an Approver for StreamedMedia channels can close the
+ channel with a reason (e.g. "busy") if desired. The channel
+ dispatcher, which is designed to have no specific knowledge
+ of particular channel types, can't do that.</p>
+ </tp:rationale>
+
+ <p>If successful, this method will cause the ChannelDispatchOperation
+ object to disappear, emitting
+ <tp:member-ref>Finished</tp:member-ref>, in the same way as for
+ <tp:member-ref>HandleWith</tp:member-ref>.</p>
+
+ <p>This method may fail because the dispatch operation has already
+ been completed. Again, see HandleWith for more details. The approver
+ MUST NOT attempt to interact with the channels further in this
+ case.</p>
+
+ <p>(FIXME: list some other possible errors)</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+ <tp:docstring>
+ At the time that Claim was called, this dispatch operation was
+ processing a call to HandleWith which has now succeeded, so
+ some Handler nominated by another approver is now responsible for
+ the channel.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="HandleWithTime" tp:name-for-bindings="Handle_With_Time">
+ <tp:added version="0.19.6">
+ At the time of writing, no released implementation of the
+ Channel Dispatcher implements this method; clients should fall
+ back to calling <tp:member-ref>HandleWith</tp:member-ref>.
+ </tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A variant of <tp:member-ref>HandleWith</tp:member-ref> allowing the
+ approver to pass an user action time. This timestamp will be passed
+ to the Handler when <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ is called.</p>
+ </tp:docstring>
+
+ <arg direction="in" type="s" tp:type="DBus_Bus_Name" name="Handler">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>) of the channel
+ handler that should handle the channel, or the empty string
+ if the client has no preferred channel handler.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" type="x" tp:type="User_Action_Timestamp" name="UserActionTime">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The selected handler is non-empty, but is not a syntactically
+ correct <tp:type>DBus_Bus_Name</tp:type> or does not start with
+ "<code>org.freedesktop.Telepathy.Client.</code>".
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The selected handler is temporarily unable to handle these
+ channels.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The selected handler is syntactically correct, but will never
+ be able to handle these channels (for instance because the channels
+ do not match its HandlerChannelFilter, or because HandleChannels
+ raised NotImplemented).
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+ <tp:docstring>
+ At the time that HandleWith was called, this dispatch operation was
+ processing an earlier call to HandleWith. The earlier call has
+ now succeeded, so some Handler nominated by another approver is
+ now responsible for the channels. In this situation, the second
+ call to HandleWith MUST NOT return until the first one has
+ returned successfully or unsuccessfully, and if the first call
+ to HandleChannels fails, the channel dispatcher SHOULD try to obey
+ the choice of Handler made by the second call to HandleWith.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="Finished" tp:name-for-bindings="Finished">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when this dispatch operation finishes. The dispatch
+ operation is no longer present and further methods must not be
+ called on it.</p>
+
+ <p>Approvers that have a user interface SHOULD stop notifying the user
+ about the channels in response to this signal; they MAY assume that
+ on errors, they would have received
+ <tp:member-ref>ChannelLost</tp:member-ref> first.</p>
+
+ <p>Its object path SHOULD NOT be reused for a subsequent dispatch
+ operation; the ChannelDispatcher MUST choose object paths
+ in a way that avoids immediate re-use.</p>
+
+ <tp:rationale>
+ <p>Otherwise, clients might accidentally call
+ <tp:member-ref>HandleWith</tp:member-ref> or
+ <tp:member-ref>Claim</tp:member-ref> on a new dispatch operation
+ instead of the one they intended to handle.</p>
+ </tp:rationale>
+
+ <p>This signal MUST NOT be emitted until all Approvers that were
+ invoked have returned (successfully or with an error) from
+ their <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Approver">AddDispatchOperation</tp:dbus-ref>
+ method.</p>
+
+ <tp:rationale>
+ <p>This means that Approvers can connect to the ChannelLost signal
+ in a race-free way. Non-approver processes that discover
+ a channel dispatch operation in some way (such as observers)
+ will have to follow the usual "connect to signals then recover
+ state" model - first connect to
+ <tp:member-ref>ChannelLost</tp:member-ref> and
+ Finished, then download <tp:member-ref>Channels</tp:member-ref>
+ (and on error, perhaps assume that the operation has already
+ Finished).</p>
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Dispatcher.xml b/spec/spec/Channel_Dispatcher.xml
new file mode 100644
index 000000000..771d06089
--- /dev/null
+++ b/spec/spec/Channel_Dispatcher.xml
@@ -0,0 +1,774 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Dispatcher"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.ChannelDispatcher">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel dispatcher is responsible for responding to new
+ channels and launching client processes to handle them. It also
+ provides functionality for client processes to request that new
+ channels are created.</p>
+
+ <p>If a channel dispatcher is running, it is responsible for dispatching
+ new channels on all
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>s
+ created by the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">AccountManager</tp:dbus-ref>.
+ Connections not created by the AccountManager are outside the scope
+ of the channel dispatcher.</p>
+
+ <tp:rationale>
+ <p>Connections created by standalone Telepathy clients
+ that do not intend to interact with the channel dispatcher
+ should be ignored - otherwise, the channel dispatcher would try
+ to launch handlers for channels that the standalone client
+ was already handling internally.</p>
+ </tp:rationale>
+
+ <p>The current channel dispatcher is defined to be the process that
+ owns the well-known bus name
+ <code>org.freedesktop.Telepathy.ChannelDispatcher</code> on
+ the session bus. This process MUST export an object with this
+ interface at the object path
+ <code>/org/freedesktop/Telepathy/ChannelDispatcher</code>.</p>
+
+ <p>Until a mechanism exists for making a reasonable automatic choice
+ of ChannelDispatcher implementation, implementations SHOULD NOT
+ register as an activatable service for the ChannelDispatcher's
+ well-known bus name. Instead, it is RECOMMENDED that some component
+ of the user's session will select and activate a particular
+ implementation, and that other Telepathy-enabled programs
+ can detect whether channel request/dispatch functionality is available
+ by checking whether the ChannelDispatcher's well-known name is in use
+ at runtime.</p>
+
+ <p>There are three categories of client process defined by this
+ specification:</p>
+
+ <dl>
+ <dt><tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Observer</tp:dbus-ref></dt>
+ <dd><p>Observers monitor the creation of new channels. This
+ functionality can be used for things like message logging.
+ All observers are notified simultaneously.</p></dd>
+
+ <dt><tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref></dt>
+ <dd>
+ <p>Approvers notify the user that new channels have been created,
+ and also select which channel handler will be used for the channel,
+ either by asking the user or by choosing the most appropriate
+ channel handler.</p>
+ </dd>
+
+ <dt><tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref></dt>
+ <dd>
+ <p>Each new channel or set of channels is passed to exactly one
+ handler as its final destination. A typical channel handler is a
+ user interface process handling channels of a particular type.</p>
+ </dd>
+ </dl>
+ </tp:docstring>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read" tp:type="DBus_Interface[]">
+ <tp:docstring>
+ A list of the extra interfaces provided by this channel dispatcher.
+ </tp:docstring>
+ </property>
+
+ <method name="CreateChannel" tp:name-for-bindings="Create_Channel">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Equivalent to calling
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref> with an empty
+ <var>Hints</var> parameter.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Account" type="o">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ for which the new channel is to be created.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Requested_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Preferred_Handler" type="s"
+ tp:type="DBus_Well_Known_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred handler for this
+ channel, or an empty string to indicate that any handler would be
+ acceptable.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ <tp:changed version="0.19.0">
+ Previously, the spec didn't say that this should disregard the
+ handler's filter. This has been implemented since
+ telepathy-mission-control 5.3.2.
+ </tp:changed>
+ </arg>
+
+ <arg direction="out" name="Request" type="o">
+ <tp:docstring>
+ A
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The <var>Preferred_Handler</var> is syntactically invalid or does
+ not start with <code>org.freedesktop.Telepathy.Client.</code>,
+ the <var>Account</var> does not exist, or one of the
+ <var>Requested_Properties</var> is invalid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+
+ </method>
+
+ <method name="EnsureChannel" tp:name-for-bindings="Ensure_Channel">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Equivalent to calling
+ <tp:member-ref>EnsureChannelWithHints</tp:member-ref> with an empty
+ <var>Hints</var> parameter.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Account" type="o">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ for which the new channel is to be created.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Requested_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Preferred_Handler" type="s"
+ tp:type="DBus_Well_Known_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred handler for this
+ channel, or an empty string to indicate that any handler would be
+ acceptable. The behaviour and rationale are the same as for the
+ corresponding parameter to
+ <tp:member-ref>EnsureChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Request" type="o">
+ <tp:docstring>
+ A
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The <var>Preferred_Handler</var> is syntactically invalid or does
+ not start with <code>org.freedesktop.Telepathy.Client.</code>,
+ the <var>Account</var> does not exist, or one of the
+ <var>Requested_Properties</var> is invalid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+
+ </method>
+
+ <method name="CreateChannelWithHints"
+ tp:name-for-bindings="Create_Channel_With_Hints">
+ <tp:added version="0.21.5">
+ Support for this method is indicated by the
+ <tp:member-ref>SupportsRequestHints</tp:member-ref> property.
+ Clients MUST recover from this method being unsupported by falling back
+ to <tp:dbus-ref
+ namespace="ofdT.ChannelDispatcher">CreateChannel</tp:dbus-ref>.
+ </tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Start a request to create a channel. This initially just creates a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object, which can be used to continue the request and track its
+ success or failure.</p>
+
+ <tp:rationale>
+ <p>The request can take a long time - in the worst case, the
+ channel dispatcher has to ask the account manager to put the
+ account online, the account manager has to ask the operating
+ system to obtain an Internet connection, and the operating
+ system has to ask the user whether to activate an Internet
+ connection using an on-demand mechanism like dialup.</p>
+
+ <p>This means that using a single D-Bus method call and response
+ to represent the whole request will tend to lead to that call
+ timing out, which is not the behaviour we want.</p>
+ </tp:rationale>
+
+ <p>If this method is called for an Account that is disabled, invalid
+ or otherwise unusable, no error is signalled until
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest.Proceed</tp:dbus-ref>
+ is called, at which point
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest.Failed</tp:dbus-ref>
+ is emitted with an appropriate error.</p>
+
+ <tp:rationale>
+ <p>This means there's only one code path for errors, apart from
+ InvalidArgument for "that request makes no sense".</p>
+
+ <p>It also means that the request will proceed if the account is
+ enabled after calling CreateChannel, but before calling
+ Proceed.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Account" type="o">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ for which the new channel is to be created.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Requested_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties. This has the same
+ semantics as the corresponding parameter to
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>.
+ </p>
+
+ <p>Certain properties will not necessarily make sense in this
+ dictionary: for instance,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ can only be given if the requester is able to interact with a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ to the desired account.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelRequest">UserActionTime</tp:dbus-ref>
+ property will be set to this value, and it will eventually be
+ passed as the <code>User_Action_Time</code> parameter of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Preferred_Handler" type="s"
+ tp:type="DBus_Well_Known_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred handler for this
+ channel, or an empty string to indicate that any handler would be
+ acceptable. The channel dispatcher SHOULD dispatch as many as
+ possible of the resulting channels (ideally, all of them)
+ to that handler—irrespective of whether that handler's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ matches the channel—and SHOULD remember the preferred handler
+ so it can try to dispatch subsequent channels in the same bundle
+ to the same handler.</p>
+
+ <tp:rationale>
+ <p>This must be the well-known bus name, not the unique name,
+ to ensure that all handlers do indeed have the Client API,
+ and the Client object on the handler can be located easily.</p>
+
+ <p>This is partly so the channel dispatcher can call
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ on it, and partly so the channel dispatcher
+ can recover state if it crashes and is restarted.</p>
+
+ <p>The filter should be disregarded for ease of use of this
+ interface: clients will usually use this argument to request
+ channels be sent to themself, and this should trump the filter
+ not matching. This also allows a client to become the handler
+ for a channel produced by one of its own requests, while not
+ being a candidate to handle other channels of that type.</p>
+ </tp:rationale>
+
+ <p>If this is a well-known bus name and the handler has the
+ Requests interface, the channel dispatcher SHOULD
+ call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Interface.Requests">AddRequest</tp:dbus-ref>
+ on that Handler after this method has returned.</p>
+
+ <tp:rationale>
+ <p>This ordering allows a Handler which calls CreateChannel with
+ itself as the preferred handler to associate the call to
+ AddRequest with that call.</p>
+ </tp:rationale>
+
+ <p>This is copied to the ChannelRequest that is returned,
+ as the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelRequest">PreferredHandler</tp:dbus-ref>
+ property.</p>
+ </tp:docstring>
+
+ <tp:changed version="0.19.0">
+ Previously, the spec didn't say that this should disregard the
+ handler's filter. This has been implemented since
+ telepathy-mission-control 5.3.2.
+ </tp:changed>
+ </arg>
+
+ <arg direction="in" name="Hints" type="a{sv}">
+ <tp:docstring>
+ <p>Additional information about the channel request, which will be
+ used as the value for the resulting request's <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">Hints</tp:dbus-ref>
+ property.</p>
+
+ <tp:rationale>
+ <p>See the Hints property's documentation for rationale.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Request" type="o">
+ <tp:docstring>
+ A
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The <var>Preferred_Handler</var> is syntactically invalid or does
+ not start with <code>org.freedesktop.Telepathy.Client.</code>,
+ the <var>Account</var> does not exist, or one of the
+ <var>Requested_Properties</var> is invalid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+
+ </method>
+
+ <method name="EnsureChannelWithHints"
+ tp:name-for-bindings="Ensure_Channel_With_Hints">
+ <tp:added version="0.21.5">
+ Support for this method is indicated by the
+ <tp:member-ref>SupportsRequestHints</tp:member-ref> property.
+ Clients MUST recover from this method being unsupported by falling back
+ to <tp:dbus-ref
+ namespace="ofdT.ChannelDispatcher">EnsureChannel</tp:dbus-ref>.
+ </tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Start a request to ensure that a channel exists, creating it if
+ necessary. This initially just creates a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object, which can be used to continue the request and track its
+ success or failure.</p>
+
+ <p>If this method is called for an Account that is disabled, invalid
+ or otherwise unusable, no error is signalled until
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest.Proceed</tp:dbus-ref>
+ is called, at which point
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest.Failed</tp:dbus-ref>
+ is emitted with an appropriate error.</p>
+
+ <tp:rationale>
+ <p>The rationale is as for <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy.ChannelDispatcher'>CreateChannelWithHints</tp:dbus-ref>.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Account" type="o">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ for which the new channel is to be created.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Requested_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties. This has the same
+ semantics as the corresponding parameter to
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.EnsureChannel</tp:dbus-ref>.
+ </p>
+
+ <p>Certain properties will not necessarily make sense in this
+ dictionary: for instance,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ can only be given if the requester is able to interact with a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ to the desired account.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Preferred_Handler" type="s"
+ tp:type="DBus_Well_Known_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred handler for this
+ channel, or an empty string to indicate that any handler would be
+ acceptable. The behaviour and rationale are the same as for the
+ corresponding parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>, except
+ as noted here.</p>
+
+ <p>If any new channels are created in response to this
+ request, the channel dispatcher SHOULD dispatch as many as
+ possible of the resulting channels (ideally, all of them)
+ to that handler, and SHOULD remember the preferred handler
+ so it can try to dispatch subsequent channels in the same bundle
+ to the same handler. If the requested channel already exists (that
+ is, <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.EnsureChannel</tp:dbus-ref>
+ returns <code>Yours=False</code>) then the channel dispatcher
+ SHOULD re-dispatch the channel to its existing handler, and MUST
+ NOT dispatch it to this client (unless it is the existing handler);
+ the request is still deemed to have succeeded in this case.</p>
+
+ <tp:rationale>
+ <p>An address book application, for example, might call <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy.ChannelDispatcher'>EnsureChannel</tp:dbus-ref>
+ to ensure that a text channel with a particular contact is
+ displayed to the user; it does not care whether a new channel was
+ made. An IM client might call <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy.ChannelDispatcher'>EnsureChannel</tp:dbus-ref>
+ in response to the user double-clicking an entry in the contact
+ list, with itself as the <code>Preferred_Handler</code>; if the
+ user already has a conversation with that contact in another
+ application, they would expect the existing window to be
+ presented, rather than their double-click leading to an error
+ message. So the request should succeed, even if its
+ <code>Preferred_Handler</code> is not used.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Hints" type="a{sv}">
+ <tp:docstring>
+ Additional information about the channel request, which will be used
+ as the value for the resulting request's <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">Hints</tp:dbus-ref>
+ property.</tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Request" type="o">
+ <tp:docstring>
+ A
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The <var>Preferred_Handler</var> is syntactically invalid or does
+ not start with <code>org.freedesktop.Telepathy.Client.</code>,
+ the <var>Account</var> does not exist, or one of the
+ <var>Requested_Properties</var> is invalid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+
+ </method>
+
+ <method name="DelegateChannels"
+ tp:name-for-bindings="Delegate_Channels">
+ <tp:added version="0.23.1">
+ Implemented since telepathy-mission-control 5.7.12.
+ </tp:added>
+ <tp:changed version="0.23.2">This method now returns
+ <var>Delegated</var> and <var>Not_Delegated</var> instead of nothing.
+ <tp:dbus-ref namespace="ofdT.Client.Handler">HandleChannels</tp:dbus-ref>
+ is now called once per <var>Channel</var> in <var>Channels</var>.
+ </tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ to redispatch a bunch of channels it is currently handling.</p>
+
+ <p>For each <var>Channel</var> in <var>Channels</var>, if another
+ <tp:dbus-ref namespace="ofdT.Client">Handler</tp:dbus-ref>
+ can be found,
+ <tp:dbus-ref namespace="ofdT.Client.Handler">HandleChannels</tp:dbus-ref>
+ will be called on it until a
+ <tp:dbus-ref namespace="ofdT.Client">Handler</tp:dbus-ref>
+ accepts it.</p>
+
+ <p>This method returns once all the <var>Channels</var> have either
+ been accepted or rejected by Handlers.</p>
+
+ <p>If this method fails, the original
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ is still handling the channels.</p>
+
+ </tp:docstring>
+
+ <arg direction="in" name="Channels" type="ao">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of channels to redispatch. The caller has to be the current
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ of all of these channels
+ </p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channels
+ delegation is for some reason not involving user action.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Preferred_Handler" type="s"
+ tp:type="DBus_Well_Known_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred new handler for these
+ channels, or an empty string to indicate that any handler would be
+ acceptable. The behaviour and rationale are the same as for the
+ corresponding parameter to
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref>.</p>
+
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Delegated" type="ao">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of channels which have been delegated; the caller is no
+ longer handling these channels.</p>
+
+ <p>The client should remove these channels from its
+ <tp:dbus-ref namespace="ofdT.Client.Handler">HandledChannels</tp:dbus-ref>
+ property.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Not_Delegated" type="a{o(ss)}"
+ tp:type="Not_Delegated_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of channels which have NOT been delegated; the caller is still
+ handling these channels.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The Preferred_Handler is syntactically invalid or does
+ not start with <code>org.freedesktop.Telepathy.Client.</code>.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYours">
+ <tp:docstring>
+ At least one <var>Channel</var> in <var>Channels</var> is not
+ currently handled by the caller. No <var>Channel</var> has been
+ delegated.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+
+ </method>
+
+ <tp:mapping name="Not_Delegated_Map">
+ <tp:docstring>
+ A mapping associating not delegated channel with an error.
+ </tp:docstring>
+
+ <tp:member type="o" name="Channel">
+ <tp:docstring>
+ The path of the channel
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="(ss)" name="Error" tp:type="Not_Delegated_Error">
+ <tp:docstring>
+ An error describing why the channel has not be delegated
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:struct name="Not_Delegated_Error">
+ <tp:member type="s" name="Error_Name" tp:type="DBus_Error_Name">
+ <tp:docstring>
+ the name of a D-Bus error describing what went wrong.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Error_Message">
+ <tp:docstring>
+ a human-readable informative error message.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="PresentChannel"
+ tp:name-for-bindings="Present_Channel">
+ <tp:added version="0.23.1">
+ Implemented since telepathy-mission-control 5.7.12.
+ </tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Equivalent of calling
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.ChannelDispatcher">EnsureChannel</tp:dbus-ref>
+ with a <var>Requested_Properties</var> which would result in ensuring
+ <var>Channel</var>.</p>
+
+ <p>If <var>Channel</var> is handled, its handler will be asked to present it the user
+ (e.g. bring it into the foreground).</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Channel" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel to present.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="User_Action_Time" type="x"
+ tp:type="User_Action_Timestamp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.</p>
+
+ <p>This parameter is used in the same way as the corresponding
+ parameter to
+ <tp:member-ref>EnsureChannelWithHints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The Account does not exist, the Channel does not exist or it
+ does not belong to the Account.
+ </tp:docstring>
+ </tp:error>
+
+ </tp:possible-errors>
+ </method>
+
+ <property name="SupportsRequestHints"
+ tp:name-for-bindings="Supports_Request_Hints"
+ type="b" access="read">
+ <tp:added version="0.21.5"/>
+ <tp:docstring>
+ If <code>True</code>, the channel dispatcher is new enough to support
+ <tp:member-ref>CreateChannelWithHints</tp:member-ref> and
+ <tp:member-ref>EnsureChannelWithHints</tp:member-ref>, in addition
+ to the older <tp:dbus-ref
+ namespace="ofdT.ChannelDispatcher">CreateChannel</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="ofdT.ChannelDispatcher">EnsureChannel</tp:dbus-ref>
+ methods, and also new enough to emit <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">SucceededWithChannel</tp:dbus-ref>
+ before the older <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">Succeeded</tp:dbus-ref> signal.
+ If <code>False</code> or missing, only the metadata-less
+ variants are supported.
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Dispatcher_Interface_Operation_List.xml b/spec/spec/Channel_Dispatcher_Interface_Operation_List.xml
new file mode 100644
index 000000000..be06f5caa
--- /dev/null
+++ b/spec/spec/Channel_Dispatcher_Interface_Operation_List.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Dispatcher_Interface_Operation_List"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.ChannelDispatcher.Interface.OperationList">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.ChannelDispatcher"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface allows users of the ChannelDispatcher to enumerate
+ all the pending dispatch operations, with change notification.</p>
+
+ <tp:rationale>
+ <p>The existence of the
+ <tp:member-ref>DispatchOperations</tp:member-ref> property allows a
+ newly started approver to pick up existing dispatch operations.</p>
+
+ <p>This is on a separate interface so clients that aren't interested
+ in doing this aren't woken up by its signals.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:struct name="Dispatch_Operation_Details"
+ array-name="Dispatch_Operation_Details_List">
+
+ <tp:docstring>
+ Details of a channel dispatch operation.
+ </tp:docstring>
+
+ <tp:member name="Channel_Dispatch_Operation" type="o">
+ <tp:docstring>
+ The object path of the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation</tp:dbus-ref>.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Properties of the channel dispatch operation.</p>
+
+ <p>Connection managers MUST NOT include properties in this mapping
+ if their values can change. Clients MUST ignore properties
+ that appear in this mapping if their values can change.</p>
+
+ <tp:rationale>
+ <p>The rationale is the same as for
+ <tp:type>Channel_Details</tp:type>.</p>
+ </tp:rationale>
+
+ <p>Each dictionary MUST contain at least the following keys:</p>
+ <ul>
+ <li><tp:dbus-ref>org.freedesktop.Telepathy.ChannelDispatchOperation.Interfaces</tp:dbus-ref></li>
+ <li><tp:dbus-ref>org.freedesktop.Telepathy.ChannelDispatchOperation.Connection</tp:dbus-ref></li>
+ <li><tp:dbus-ref>org.freedesktop.Telepathy.ChannelDispatchOperation.Account</tp:dbus-ref></li>
+ <li><tp:dbus-ref>org.freedesktop.Telepathy.ChannelDispatchOperation.PossibleHandlers</tp:dbus-ref></li>
+ </ul>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property
+ name="DispatchOperations" tp:name-for-bindings="Dispatch_Operations"
+ type="a(oa{sv})" tp:type="Dispatch_Operation_Details[]" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of ChannelDispatchOperation objects currently being
+ processed. Change notification is via the
+ <tp:member-ref>NewDispatchOperation</tp:member-ref> and
+ <tp:member-ref>DispatchOperationFinished</tp:member-ref> signals.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="NewDispatchOperation"
+ tp:name-for-bindings="New_Dispatch_Operation">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a dispatch operation is added to
+ <tp:member-ref>DispatchOperations</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Dispatch_Operation" type="o">
+ <tp:docstring>
+ The dispatch operation that was created.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Properties"
+ type="a{sv}" tp:type="Qualified_Property_Value_Map">
+ <tp:docstring>
+ The same properties that would appear in the Properties member of
+ <tp:type>Dispatch_Operation_Details</tp:type>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="DispatchOperationFinished"
+ tp:name-for-bindings="Dispatch_Operation_Finished">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Emitted when a dispatch operation finishes (i.e. exactly once per
+ emission of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation.Finished</tp:dbus-ref>).
+
+ <tp:rationale>
+ Strictly speaking this is redundant with
+ ChannelDispatchOperation.Finished, but it provides full
+ change-notification for the
+ <tp:member-ref>DispatchOperations</tp:member-ref> property.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Dispatch_Operation" type="o">
+ <tp:docstring>
+ The dispatch operation that was closed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Future.xml b/spec/spec/Channel_Future.xml
new file mode 100644
index 000000000..5bbca17b1
--- /dev/null
+++ b/spec/spec/Channel_Future.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Future"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.FUTURE"
+ tp:causes-havoc="a staging area for future Channel functionality">
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface contains functionality which we intend to incorporate
+ into the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref> interface
+ in future. It should be considered to
+ be conceptually part of the core Channel interface, but without
+ API or ABI guarantees.</p>
+
+ <tp:rationale>
+ <p>If we add new functionality to the Channel interface, libraries
+ that use generated code (notably telepathy-glib) will have it as
+ part of their ABI forever, meaning we can't make incompatible
+ changes. By using this interface as a staging area for future
+ Channel functionality, we can try out new properties, signals
+ and methods as application-specific extensions, then merge them
+ into the core Channel interface when we have enough implementation
+ experience to declare them to be stable.</p>
+
+ <p>The name is by analogy to Python's <code>__future__</code>
+ pseudo-module.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <property name="Bundle" tp:name-for-bindings="Bundle"
+ type="o" access="read">
+ <tp:added version="0.17.9">(in Channel.FUTURE
+ pseudo-interface)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelBundle.DRAFT</tp:dbus-ref>
+ to which this channel belongs.</p>
+
+ <p>A channel's Bundle property can never change.</p>
+
+ <p>Older connection managers might not have this property. Clients
+ (particularly the channel dispatcher) SHOULD recover by considering
+ each channel to be in a bundle containing only that channel,
+ distinct from all other bundles, which has no additional
+ interfaces.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Handler.xml b/spec/spec/Channel_Handler.xml
new file mode 100644
index 000000000..edf975e4d
--- /dev/null
+++ b/spec/spec/Channel_Handler.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Handler" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2007-2008 Collabora Limited</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.ChannelHandler">
+ <tp:deprecated version="0.17.23">
+ Clients should implement <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Client.Handler</tp:dbus-ref>
+ instead.
+ </tp:deprecated>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface exported by Mission Control 4 client applications which
+ are able to handle incoming channels.</p>
+ </tp:docstring>
+ <tp:added version="0.17.0"/>
+
+ <method name="HandleChannel" tp:name-for-bindings="Handle_Channel">
+ <tp:docstring>
+ Called when a channel handler should handle a new channel.
+ </tp:docstring>
+ <tp:added version="0.17.0"/>
+
+ <arg direction="in" type="s" name="Bus_Name" tp:type="DBus_Bus_Name">
+ <tp:docstring>
+ The bus name of the connection and channel
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" type="o" name="Connection">
+ <tp:docstring>
+ The object-path of the connection that owns the channel
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" type="s" tp:type="DBus_Interface" name="Channel_Type">
+ <tp:docstring>
+ The channel type
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" type="o" name="Channel">
+ <tp:docstring>
+ The object-path of the channel
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" type="u" tp:type="Handle_Type" name="Handle_Type">
+ <tp:docstring>The type of the handle that the channel communicates
+ with, or 0 if there is no associated handle</tp:docstring>
+ </arg>
+
+ <arg direction="in" type="u" tp:type="Handle" name="Handle">
+ <tp:docstring>The handle that the channel communicates with,
+ or 0 if there is no associated handle</tp:docstring>
+ </arg>
+
+ <!-- FIXME: possible errors? -->
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
+
diff --git a/spec/spec/Channel_Interface_Addressing.xml b/spec/spec/Channel_Interface_Addressing.xml
new file mode 100644
index 000000000..494fd7bf0
--- /dev/null
+++ b/spec/spec/Channel_Interface_Addressing.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Addressing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Limited</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Addressing.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.12">(as draft)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface provides properties that can be used for
+ requesting channels through different contact addressing
+ schemes like vCard addresses or URIs.
+ </p>
+ </tp:docstring>
+
+ <property name="TargetVCardField" type="s" access="read"
+ tp:name-for-bindings="Target_VCard_Field">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The vCard field, normalized to lower case,
+ <tp:member-ref>TargetVCardAddress</tp:member-ref> refers to.</p>
+
+ <p>The <code>url</code> vCard field MUST NOT appear here; see
+ <tp:member-ref>TargetURI</tp:member-ref> instead.</p>
+
+ <tp:rationale>
+ <p>In practice, protocols have a limited set of URI
+ schemes that make sense to resolve as a contact.</p>
+ </tp:rationale>
+
+ <p>If this is omitted from a request,
+ <tp:member-ref>TargetVCardAddress</tp:member-ref> MUST be
+ omitted as well.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetURIScheme" type="s" access="read"
+ tp:name-for-bindings="Target_URI_Scheme">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The URI scheme used in <tp:member-ref>TargetURI</tp:member-ref></p>
+
+ <tp:rationale>
+ <p>While this seems redundant, since the scheme is included in
+ <tp:member-ref>TargetURI</tp:member-ref>, it exists for constructing
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">RequestableChannelClasses</tp:dbus-ref>
+ that support a limited set of URI schemes.</p>
+ </tp:rationale>
+
+ <p>If this is omitted from a request,
+ <tp:member-ref>TargetURI</tp:member-ref> MUST be
+ omitted as well.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetVCardAddress" type="s" access="read"
+ tp:name-for-bindings="Target_VCard_Address">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The vCard address of the Channel's target.</p>
+
+ <p>If this is present in a channel request,
+ <tp:member-ref>TargetVCardField</tp:member-ref>
+ MUST be present, and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>,
+ and <tp:member-ref>TargetURI</tp:member-ref> MUST NOT be present.
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ must either not be present or set to Handle_Type_Contact.
+ The request MUST fail with error InvalidHandle, without
+ side-effects, if the requested vCard address cannot be found.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="TargetURI" type="s" access="read"
+ tp:name-for-bindings="Target_URI">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The URI of the Channel's target. The URI's scheme (i.e. the
+ part before the first colon) MUST be identical to
+ <tp:member-ref>TargetURIScheme</tp:member-ref>.</p>
+
+ <p>If this is present in a channel request,
+ <tp:member-ref>TargetVCardField</tp:member-ref>
+ MUST be present, and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>,
+ and <tp:member-ref>TargetVCardAddress</tp:member-ref> MUST NOT be
+ present.
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ must either not be present or set to Handle_Type_Contact.
+ The request MUST fail with error InvalidHandle, without
+ side-effects, if the requested vCard address cannot be found.</p>
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Anonymity.xml b/spec/spec/Channel_Interface_Anonymity.xml
new file mode 100644
index 000000000..ef3a3b85d
--- /dev/null
+++ b/spec/spec/Channel_Interface_Anonymity.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Anonymity"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Anonymity">
+ <tp:added version="0.19.7">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for requesting the anonymity modes of a channel
+ (as defined in <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Anonymity</tp:dbus-ref>).</p>
+ </tp:docstring>
+
+ <property name="AnonymityModes" type="u" tp:type="Anonymity_Mode_Flags"
+ access="read" tp:name-for-bindings="Anonymity_Modes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The list of initially requested anonymity modes on the channel. This
+ MUST NOT change, and is Requestable.
+ </tp:docstring>
+ </property>
+
+ <property name="AnonymityMandatory" type="b" access="read"
+ tp:name-for-bindings="Anonymity_Mandatory">
+ <tp:docstring>
+ Whether or not the anonymity settings are required for this channel.
+ This MUST NOT change, and is Requestable.
+ </tp:docstring>
+ </property>
+
+ <property name="AnonymousID" type="s" access="read"
+ tp:name-for-bindings="Anonymous_ID">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This is the ID that the remote user of the channel MAY see
+ (assuming there's a single ID). For example, for SIP connections
+ where the From address has been scrambled by the CM, the scrambled
+ address would be available here for the client to see. This is
+ completely optional, and MAY be an empty string ("") in
+ cases where anonymity modes are not set, or the CM doesn't know
+ what the remote contact will see, or any other case where this
+ doesn't make sense.</p>
+
+ <p>This MAY change over the lifetime of the channel, and SHOULD NOT
+ be used with the Request interface.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Call_State.xml b/spec/spec/Channel_Interface_Call_State.xml
new file mode 100644
index 000000000..b0aea5915
--- /dev/null
+++ b/spec/spec/Channel_Interface_Call_State.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Call_State" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2008 Nokia Corporation </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.CallState">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for streamed media channels that can indicate call
+ progress or call states. The presence of this interface is no guarantee
+ that call states will actually be signalled (for instance, SIP
+ implementations are not guaranteed to generate status 180 Ringing, so a
+ call can be accepted without the Ringing flag ever having been set;
+ similarly, Jingle implementations are not guaranteed to send
+ <code>&lt;ringing/&gt;</code>).</p>
+
+ <p>To notify the other participant in the call that they are on hold,
+ see <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Hold</tp:dbus-ref>.</p>
+ </tp:docstring>
+ <tp:added version="0.17.2"/>
+
+ <method name="GetCallStates" tp:name-for-bindings="Get_Call_States">
+ <tp:docstring>
+ Get the current call states for all contacts involved in this call.
+ </tp:docstring>
+
+ <arg tp:type="Channel_Call_State_Map" name="States" direction="out"
+ type="a{uu}">
+ <tp:docstring>
+ The current call states. Participants where the call state flags
+ would be 0 (all unset) may be omitted from this mapping.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="CallStateChanged" tp:name-for-bindings="Call_State_Changed">
+ <tp:docstring>
+ Emitted when the state of a member of the channel has changed.
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for the contact.
+ </tp:docstring>
+ </arg>
+
+ <arg name="State" type="u" tp:type="Channel_Call_State_Flags">
+ <tp:docstring>
+ The new state for this contact.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:mapping name="Channel_Call_State_Map">
+ <tp:docstring>
+ A map from contacts to call states.
+ </tp:docstring>
+
+ <tp:member name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>A contact involved in this call.</tp:docstring>
+ </tp:member>
+
+ <tp:member name="State" type="u" tp:type="Channel_Call_State_Flags">
+ <tp:docstring>State flags for the given contact.</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:flags name="Channel_Call_State_Flags" value-prefix="Channel_Call_State" type="u">
+ <tp:docstring>
+ A set of flags representing call states.
+ </tp:docstring>
+
+ <tp:flag suffix="Ringing" value="1">
+ <tp:docstring>
+ The contact has been alerted about the call but has not responded
+ (e.g. 180 Ringing in SIP).
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Queued" value="2">
+ <tp:docstring>
+ The contact is temporarily unavailable, and the call has been placed
+ in a queue (e.g. 182 Queued in SIP, or call-waiting in telephony).
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Held" value="4">
+ <tp:docstring>
+ The contact has placed the call on hold, and will not receive
+ media from the local user or any other participants until they
+ unhold the call again.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Forwarded" value="8">
+ <tp:docstring>
+ The initiator of the call originally called a contact other than the
+ current recipient of the call, but the call was then forwarded or
+ diverted.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="In_Progress" value="16">
+ <tp:docstring>
+ Progress has been made in placing the outgoing call, but the
+ destination contact may not have been made aware of the call yet
+ (so the Ringing state is not appropriate). This corresponds to SIP's
+ status code 183 Session Progress, and could be used when the
+ outgoing call has reached a gateway, for instance.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Conference_Host" value="32">
+ <tp:added version='0.19.11'/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ This contact has merged this call into a conference. Note that GSM
+ provides a notification when the remote party merges a call into a
+ conference, but not when it is split out again; thus, this flag can
+ only indicate that the call has been part of a conference at some
+ point. If a GSM connection manager receives a notification that a
+ call has been merged into a conference a second time, it SHOULD
+ represent this by clearing and immediately re-setting this flag on
+ the remote contact.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Chat_State.xml b/spec/spec/Channel_Interface_Chat_State.xml
new file mode 100644
index 000000000..27515d2e8
--- /dev/null
+++ b/spec/spec/Channel_Interface_Chat_State.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Chat_State" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2007 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.ChatState">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
+
+ <tp:mapping name="Chat_State_Map">
+ <tp:added version="0.19.7"/>
+ <tp:docstring>A map from contacts to their chat states.</tp:docstring>
+ <tp:member name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>A contact</tp:docstring>
+ </tp:member>
+ <tp:member name="State" type="u" tp:type="Channel_Chat_State">
+ <tp:docstring>The contact's chat state</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="ChatStates" tp:name-for-bindings="Chat_States"
+ access="read" type="a{uu}" tp:type="Chat_State_Map">
+ <tp:added version="0.19.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map containing the chat states of all contacts in this
+ channel whose chat state is not Inactive.</p>
+
+ <p>Contacts in this channel, but who are not listed in this map,
+ may be assumed to be in the Inactive state.</p>
+
+ <p>In implementations that do not have this property, its value may be
+ assumed to be empty until a
+ <tp:member-ref>ChatStateChanged</tp:member-ref> signal indicates
+ otherwise.</p>
+
+ <tp:rationale>
+ <p>This property was not present in older versions of telepathy-spec,
+ because chat states in XMPP are not state-recoverable (if you
+ miss the change notification signal, there's no way to know the
+ state). However, this property still allows clients to recover
+ state changes that were seen by the CM before the client started
+ to deal with the channel.</p>
+
+ <p>In CMs that follow older spec versions, assuming Inactive will
+ mean that initial chat states will always be assumed to be
+ Inactive, which is the best we can do. XEP 0085 specifies
+ Inactive as the "neutral" state to be assumed unless told
+ otherwise.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="SetChatState" tp:name-for-bindings="Set_Chat_State">
+ <arg direction="in" name="State" type="u" tp:type="Channel_Chat_State">
+ <tp:docstring>
+ The new state.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Set the local state and notify other members of the channel that it
+ has changed.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+ <signal name="ChatStateChanged" tp:name-for-bindings="Chat_State_Changed">
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for the contact.
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Channel_Chat_State">
+ <tp:docstring>
+ The new state of this contact.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the state of a member of the channel has changed.
+ This includes local state.
+ </tp:docstring>
+ </signal>
+ <tp:enum name="Channel_Chat_State" type="u">
+ <tp:enumvalue suffix="Gone" value="0">
+ <tp:docstring>
+ The contact has effectively ceased participating in the chat.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Inactive" value="1">
+ <tp:docstring>
+ The contact has not been active for some time.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Active" value="2">
+ <tp:docstring>
+ The contact is actively participating in the chat.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Paused" value="3">
+ <tp:docstring>
+ The contact has paused composing a message.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Composing" value="4">
+ <tp:docstring>
+ The contact is composing a message to be sent to the chat.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for channels for receiving notifications of remote contacts'
+ state, and for notifying remote contacts of the local state.</p>
+
+ <p>Clients should assume that a contact's state is Channel_Chat_State_Inactive
+ unless they receive a notification otherwise.</p>
+
+ <p>The Channel_Chat_State_Gone state is treated differently to other states:</p>
+ <ul>
+ <li>It may not be used for multi-user chats</li>
+ <li>It may not be explicitly sent</li>
+ <li>It should be automatically sent when the channel is closed</li>
+ <li>It must not be sent to the peer if a channel is closed without being used</li>
+ <li>Receiving it must not cause a new channel to be opened</li>
+ </ul>
+
+ <p>The different states are defined by XEP-0085, but may be applied to any suitable protocol.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Conference.xml b/spec/spec/Channel_Interface_Conference.xml
new file mode 100644
index 000000000..abda59eef
--- /dev/null
+++ b/spec/spec/Channel_Interface_Conference.xml
@@ -0,0 +1,628 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Conference"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.Conference">
+ <tp:added version="0.19.13">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires
+ interface="org.freedesktop.Telepathy.Channel.Interface.Group"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for multi-user conference channels that can "continue
+ from" one or more individual channels. This could be used to invite
+ other contacts to an existing 1-1 text conversation, combine two phone
+ calls into one conference call, and so on, with roughly the same API in
+ each case.</p>
+
+ <tp:rationale>
+ <p>This interface addresses freedesktop.org <a
+ href="http://bugs.freedesktop.org/show_bug.cgi?id=24906">bug
+ #24906</a> (GSM-compatible conference calls) and <a
+ href="http://bugs.freedesktop.org/show_bug.cgi?id=24939">bug
+ #24939</a> (upgrading calls and chats to multi-user).
+ See those bugs for more rationale and use cases.</p>
+ </tp:rationale>
+
+ <p>Existing channels are upgraded by requesting a new channel of the same
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>,
+ listing the channels to be merged into the new conference in the
+ <tp:member-ref>InitialChannels</tp:member-ref> property of the request.
+ If <tp:member-ref>InitialInviteeHandles</tp:member-ref> and
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref> are
+ <var>Allowed_Properties</var> in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">RequestableChannelClasses</tp:dbus-ref>,
+ ad-hoc conferences to a set of contacts may be created by requesting a
+ channel, specifying
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> and/or
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref> to be the contacts in
+ question. A request may specify these alongside
+ <tp:member-ref>InitialChannels</tp:member-ref>, to simultaneously
+ upgrade a channel to a conference and invite others to join it.</p>
+
+ <p>Channels with this interface MAY also implement <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>MergeableConference.DRAFT</tp:dbus-ref>
+ to support merging more 1-1 channels into an ongoing conference.
+ Similarly, 1-1 channels MAY implement <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Splittable.DRAFT</tp:dbus-ref> to
+ support being broken out of a Conference channel.</p>
+
+ <p>The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Group</tp:dbus-ref> interface on Conference channels MAY use
+ channel-specific handles for participants; clients SHOULD support
+ both Conferences that have channel-specific handles, and those that
+ do not.</p>
+
+ <tp:rationale>
+ <p>In the GSM case, the Conference's Group interface MAY have
+ channel-specific handles, to represent the fact that the same
+ phone number may be in a conference twice (for instance, it could be
+ the number of a corporate switchboard).</p>
+
+ <p>In the XMPP case, the Conference's Group interface SHOULD have
+ channel-specific handles, to reflect the fact that the participants
+ have MUC-specific identities, and the user might also be able to see
+ their global identities, or not.</p>
+
+ <p>In most other cases, including MSN and link-local XMPP, the
+ Conference's Group interface SHOULD NOT have channel-specific
+ handles, since users' identities are always visible.</p>
+ </tp:rationale>
+
+ <p>Connection managers implementing channels with this interface
+ MUST NOT allow the object paths of channels that could be merged
+ into a Conference to be re-used, unless the channel re-using the
+ object path is equivalent to the channel that previously used it.</p>
+
+ <tp:rationale>
+ <p>If you upgrade some channels into a conference, and then close
+ the original channels, <tp:member-ref>InitialChannels</tp:member-ref>
+ (which is immutable) will contain paths to channels which no longer
+ exist. This implies that you should not re-use channel object paths,
+ unless future incarnations of the path are equivalent.</p>
+
+ <p>For instance, on protocols where you can only have
+ zero or one 1-1 text channels with Emily at one time, it would
+ be OK to re-use the same object path for every 1-1 text channel
+ with Emily; but on protocols where this is not true, it would
+ be misleading.</p>
+ </tp:rationale>
+
+ <h4>Examples of usage</h4>
+
+ <p>A pair of 1-1 GSM calls <var>C1</var> and <var>C2</var> can be merged
+ into a single conference call by calling:</p>
+
+ <blockquote>
+ <code><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>({
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>: ...Call,
+ ...<tp:member-ref>InitialChannels</tp:member-ref>: [C1, C2]
+ })</code>
+ </blockquote>
+
+ <p>which returns a new channel <var>Cn</var> implementing the conference
+ interface. (As a quirk of GSM, both 1-1 will cease to function normally
+ until they are <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.Splittable.DRAFT">Split</tp:dbus-ref>
+ from the conference, or the conference ends.)</p>
+
+ <p>An XMPP 1-1 conversation <var>C3</var> (with
+ <tt>chris@example.com</tt>, say) can be continued in a newly created
+ multi-user chatroom by calling:</p>
+
+ <blockquote>
+ <code>CreateChannel({
+ ...ChannelType: ...Text,
+ ...<tp:member-ref>InitialChannels</tp:member-ref>: [C3]
+ })</code>
+ </blockquote>
+
+ <p>Or, to invite <tt>emily@example.net</tt> to join the newly-created MUC
+ at the same time:</p>
+
+ <blockquote>
+ <code>CreateChannel({
+ ...ChannelType: ...Text,
+ ...<tp:member-ref>InitialChannels</tp:member-ref>: [C3],
+ ...<tp:member-ref>InitialInviteeIDs</tp:member-ref>: ['emily@example.net']
+ })</code>
+ </blockquote>
+
+ <p>To continue <var>C3</var> in a particular multi-user
+ chatroom (rather than the implementation inventing a unique name for
+ the room), call:</p>
+
+ <blockquote>
+ <code><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">EnsureChannel</tp:dbus-ref>({
+ ...ChannelType: ...Text,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>: ...Room,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>: 'telepathy@conf.example.com',
+ ...<tp:member-ref>InitialChannels</tp:member-ref>: [C3]
+ })</code>
+ </blockquote>
+
+ <p>Note the use of EnsureChannel — if a channel for
+ <tt>telepathy@conf.example.com</tt> is already open, this SHOULD be
+ equivalent to inviting <tt>chris@example.com</tt> to the existing
+ channel.</p>
+
+ <p>In the above cases, the text channel <var>C3</var> SHOULD remain open
+ and fully functional (until explicitly closed by a client); new
+ incoming 1-1 messages from <tt>chris@example.com</tt> SHOULD appear in
+ <var>C3</var>, and messages sent using <var>C3</var> MUST be relayed
+ only to <tt>chris@example.com</tt>.</p>
+
+ <tp:rationale>
+ <p>If there is an open 1-1 text channel with a contact, in every
+ other situation new messages will appear in that channel. Given
+ that the old channel remains open — which is the least surprising
+ behaviour, and eases us towards a beautiful world where channels
+ never close themselves — it stands to reason that it should be
+ where new messages from Chris should appear. On MSN, creating a
+ conference from <var>C3</var> should migrate the underlying
+ switchboard from <var>C3</var> to the new channel; this is an
+ implementation detail, and should not affect the representation on
+ D-Bus. With a suitable change of terminology, Skype has the same
+ behaviour.</p>
+
+ <p>If the current handler of that channel doesn't want this to happen
+ (maybe it transformed the existing tab into the group chat window,
+ and so there'd be no UI element still around to show new messages),
+ then it should just <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref> the
+ old 1-1 channel; it'll respawn if necessary.</p>
+ </tp:rationale>
+
+ <p>Either of the XMPP cases could work for Call channels, to
+ upgrade from 1-1 Jingle to multi-user Jingle. Any of the XMPP cases
+ could in principle work for link-local XMPP (XEP-0174).</p>
+
+ <p>XMPP and MSN do not natively have a concept of merging two or more
+ channels C1, C2... into one channel, Cn. However, the GSM-style
+ merging API can be supported on XMPP and MSN, as an API short-cut
+ for upgrading C1 into a conference Cn (which invites the
+ TargetHandle of C1 into Cn), then immediately inviting the
+ TargetHandle of C2, the TargetHandle of C3, etc. into Cn as well.</p>
+
+ <h4>Sample <tp:dbus-ref namespace='ofdT.Connection.Interface.Requests'
+ >RequestableChannelClasses</tp:dbus-ref></h4>
+
+ <p>A GSM connection might advertise the following channel class for
+ conference calls:</p>
+
+ <blockquote>
+ <code>
+( Fixed = {<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>StreamedMedia</tp:dbus-ref><br/>
+  },<br/>
+  Allowed = [ <tp:member-ref>InitialChannels</tp:member-ref>,
+ <tp:dbus-ref namespace='ofdT.Channel.Type.StreamedMedia'
+ >InitialAudio</tp:dbus-ref>
+ ]<br/>
+)
+ </code>
+ </blockquote>
+
+ <p>This indicates support for starting audio-only conference calls by
+ merging two or more existing channels (since
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> and
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref> are not allowed).</p>
+
+ <p>An XMPP connection might advertise the following classes for ad-hoc
+ multi-user text chats:</p>
+
+ <blockquote>
+ <code>
+( Fixed = {<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>Text</tp:dbus-ref><br/>
+  },<br/>
+  Allowed = [ <tp:member-ref>InitialChannels</tp:member-ref>,
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref>,
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref>,
+ <tp:member-ref>InvitationMessage</tp:member-ref>
+ ]<br/>
+),<br/>
+( Fixed = {<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>,<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>:
+ Room<br/>
+  },<br/>
+  Allowed = [ <tp:dbus-ref namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref namespace='ofdT.Channel'>TargetID</tp:dbus-ref>,<br/>
+              <tp:member-ref>InitialChannels</tp:member-ref>,
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref>,
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref>,
+ <tp:member-ref>InvitationMessage</tp:member-ref>
+ ]<br/>
+)
+ </code>
+ </blockquote>
+
+ <p>The first class indicates support for starting ad-hoc (nameless) chat
+ rooms, upgraded from existing 1-1 channels and/or inviting new
+ contacts, along with a message to be sent along with the invitations.
+ The second indicates support for upgrading to a particular named chat
+ room.</p>
+ </tp:docstring>
+
+ <property name="Channels" tp:name-for-bindings="Channels"
+ access="read" type="ao">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The individual <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s that
+ are continued by this conference, which have the same <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref> as this one, but with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref> = CONTACT.</p>
+
+ <p>This property MUST NOT be requestable; instead, the
+ <tp:member-ref>InitialChannels</tp:member-ref> property may be
+ specified when requesting a channel.</p>
+
+ <tp:rationale>
+ <p>This is consistent with requesting
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> and
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref>, rather than
+ requesting <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Group.Members</tp:dbus-ref>
+ and some hypothetical ID version of that property.</p>
+ </tp:rationale>
+
+ <p>Change notification is via the
+ <tp:member-ref>ChannelMerged</tp:member-ref> and
+ <tp:member-ref>ChannelRemoved</tp:member-ref> signals.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="ChannelMerged" tp:name-for-bindings="Channel_Merged">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a new channel is added to the value of
+ <tp:member-ref>Channels</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Channel" type="o">
+ <tp:docstring>The channel that was added to
+ <tp:member-ref>Channels</tp:member-ref>.</tp:docstring>
+ </arg>
+
+ <arg name="Channel_Specific_Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>A new channel-specific handle for the <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandle</tp:dbus-ref> of
+ <var>Channel</var>, as will appear in
+ <tp:member-ref>OriginalChannels</tp:member-ref>, or <tt>0</tt> if a
+ global handle is used for
+ <var>Channel</var>'s TargetHandle on the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Group</tp:dbus-ref> interface
+ of this channel.</tp:docstring>
+ </arg>
+
+ <arg name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring><var>Channel</var>'s immutable properties.</tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="ChannelRemoved" tp:name-for-bindings="Channel_Removed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a channel is removed from the value of
+ <tp:member-ref>Channels</tp:member-ref>, either because it closed
+ or because it was split using the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Splittable.DRAFT.Split</tp:dbus-ref> method.</p>
+
+ <p>If a channel is removed because it was closed, <tp:dbus-ref
+ namespace='ofdT.Channel'>Closed</tp:dbus-ref> should be emitted
+ before this signal.</p>
+ </tp:docstring>
+
+ <arg name="Channel" type="o">
+ <tp:docstring>The channel that was removed from
+ <tp:member-ref>Channels</tp:member-ref>.</tp:docstring>
+ </arg>
+
+ <arg name="Details" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Additional information about the removal, which may include
+ the same well-known keys as the Details argument of
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Group"
+ >MembersChangedDetailed</tp:dbus-ref>, with the same semantics.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="InitialChannels" tp:name-for-bindings="Initial_Channels"
+ access="read" type="ao" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The initial value of <tp:member-ref>Channels</tp:member-ref>.</p>
+
+ <p>This property SHOULD be requestable. Omitting it from a request is
+ equivalent to providing it with an empty list as value. Requests
+ where its value has at least two channel paths SHOULD be expected to
+ succeed on any implementation of this interface. If
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> and
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref> are
+ <var>Allowed_Properties</var> in <tp:dbus-ref
+ namespace='ofdT.Connection.Interface.Requests'
+ >RequestableChannelClasses</tp:dbus-ref>, then requests with zero
+ or one channel paths SHOULD also succeed; otherwise, clients SHOULD
+ NOT make requests with zero or one paths for this property.</p>
+
+ <tp:rationale>
+ <p>In GSM, a pair of calls can be merged into a conference, but you
+ can't start a conference call from zero or one existing calls. In
+ XMPP and MSN, you can create a new chatroom, or upgrade one 1-1
+ channel into a chatroom; however, on these protocols, it is also
+ possible to fake GSM-style merging by upgrading the first channel,
+ then inviting the targets of all the other channels into it.</p>
+ </tp:rationale>
+
+ <p>If possible, the <tp:member-ref>Channels</tp:member-ref>' states SHOULD
+ NOT be altered by merging them into a conference. However, depending on
+ the protocol, the Channels MAY be placed in a "frozen" state by placing
+ them in this property's value or by calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >MergeableConference.DRAFT.Merge</tp:dbus-ref> on them.</p>
+
+ <tp:rationale>
+ <p>In Jingle, nothing special will happen to merged calls. UIs MAY
+ automatically place calls on hold before merging them, if that is
+ the desired behaviour; this SHOULD always work. Not doing
+ an implicit hold/unhold seems to preserve least-astonishment.</p>
+
+ <p>In GSM, the calls that are merged go into a state similar to
+ Hold, but they cannot be unheld, only split from the conference
+ call using <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Channel.Interface.Splittable.DRAFT.Split</tp:dbus-ref>.</p>
+ </tp:rationale>
+
+ <p>Depending on the protocol, it might be signalled to remote users
+ that this channel is a continuation of all the requested channels,
+ or that it is only a continuation of the first channel in the
+ list.</p>
+
+ <tp:rationale>
+ <p>In MSN, the conference steals the underlying switchboard (protocol
+ construct) from one of its component channels, so the conference
+ appears to remote users to be a continuation of that channel and no
+ other. The connection manager has to make some arbitrary choice, so
+ we arbitrarily mandate that it SHOULD choose the first channel in
+ the list as the one to continue.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialInviteeHandles"
+ tp:name-for-bindings="Initial_Invitee_Handles"
+ access="read" type="au" tp:type="Contact_Handle[]" tp:immutable="yes"
+ tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of additional contacts invited to this conference when it
+ was created.</p>
+
+ <p>If it is possible to invite new contacts when creating a conference
+ (as opposed to merging several channels into one new conference
+ channel), this property SHOULD be requestable, and appear in the allowed
+ properties in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+ >RequestableChannelClasses</tp:dbus-ref>. Otherwise, this property
+ SHOULD NOT be requestable, and its value SHOULD always be the empty
+ list.</p>
+
+ <tp:rationale>
+ <p>On GSM you have to place a 1-1 call before you can merge it into a
+ conference; on the other hand, you can invite new contacts to XMPP
+ Muji calls and XMPP/MSN/Skype ad-hoc chat rooms without starting a
+ 1-1 channel with them first.</p>
+ </tp:rationale>
+
+ <p>If included in a request, the given contacts are automatically
+ invited into the new channel, as if they had been added with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Group.AddMembers</tp:dbus-ref>(InitialInviteeHandles,
+ <tp:member-ref>InvitationMessage</tp:member-ref>) immediately after
+ the channel was created.</p>
+
+ <tp:rationale>
+ <p>This is a simple convenience API for the common case that a UI
+ upgrades a 1-1 chat to a multi-user chat solely in order to invite
+ someone else to participate.</p>
+ </tp:rationale>
+
+ <p>If the local user was not the initiator of this channel, the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Group.SelfHandle</tp:dbus-ref> SHOULD appear in the value of this
+ property, together with any other contacts invited at the same time
+ (if that information is known).</p>
+
+ <p>InitialInviteeHandles, InitialInviteeIDs and InitialChannels MAY be
+ combined in a single request.</p>
+
+ <tp:rationale>
+ <p>For example, if you have a 1-1 channel C1 with Rob, and you want
+ to invite Sjoerd to join the discussion, you can do so by
+ requesting a channel with InitialChannels=[C1] and
+ InitialInviteeHandles=[sjoerd],
+ or InitialChannels=[C1] and
+ InitialInviteeIDs=["sjoerd@example.com"].</p>
+ </tp:rationale>
+
+ <p>If a request includes some combination of InitialInviteeHandles,
+ InitialInviteeIDs and InitialChannels, then the value of
+ InitialInviteeHandles on the resulting channel SHOULD be the union of
+ the handles from InitialInviteeHandles, the handles corresponding
+ to the InitialInviteeIDs, and the target handles of the
+ InitialChannels, with any duplicate handles removed. Because this
+ property is immutable, its value SHOULD be computed before the
+ channel is announced via the NewChannels signal.</p>
+
+ <tp:rationale>
+ <p>This simplifies identification of new channels in clients - they
+ only have to look at one of the properties, not both. For example,
+ after either of the requests mentioned above, the NewChannels
+ signal would announce the channel with InitialChannels=[C1],
+ InitialInviteeHandles=[rob, sjoerd], and
+ InitialInviteeIDs=["rob@example.net", "sjoerd.example.com"].</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialInviteeIDs"
+ tp:name-for-bindings="Initial_Invitee_IDs"
+ access="read" type="as" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of additional contacts invited to this conference when it
+ was created.</p>
+
+ <p>This property SHOULD be requestable if and only if
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> is requestable.
+ Its semantics are the same, except that it takes a list of the
+ string representations of contact handles; invitations are sent to
+ any contact present in either or both of these properties.</p>
+
+ <p>When a channel is created, the values of InitialInviteeHandles and
+ InitialInviteeIDs MUST correspond to each other. In particular, this
+ means that the value of InitialInviteeIDs will include the TargetID
+ of each channel in InitialChannels, and the ID corresponding to each
+ handle in InitialInviteeHandles.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InvitationMessage" tp:name-for-bindings="Invitation_Message"
+ access="read" type="s" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The message that was sent to the
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> when they were
+ invited.</p>
+
+ <p>This property SHOULD be requestable, and appear in the allowed
+ properties in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+ >RequestableChannelClasses</tp:dbus-ref>, in protocols where
+ invitations can have an accompanying text message.</p>
+
+ <tp:rationale>
+ <p>This allows invitations with a message to be sent when using
+ <tp:member-ref>InitialInviteeHandles</tp:member-ref> or
+ <tp:member-ref>InitialInviteeIDs</tp:member-ref>.</p>
+ </tp:rationale>
+
+ <p>If the local user was not the initiator of this channel, the
+ message with which they were invited (if any) SHOULD appear in the
+ value of this property.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="OriginalChannels" tp:name-for-bindings="Original_Channels"
+ type="a{uo}" tp:type="Channel_Originator_Map"
+ access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>On GSM conference calls, it is possible to have the same phone
+ number in a conference twice; for instance, it could be the number of
+ a corporate switchboard. This is represented using channel-specific
+ handles; whether or not a channel uses channel-specific handles is
+ reported in <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Group.GroupFlags</tp:dbus-ref>.
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Group.HandleOwners</tp:dbus-ref>
+ property specifies the mapping from opaque channel-specific handles
+ to actual numbers; this property specifies the original 1-1 channel
+ corresponding to each channel-specific handle in the conference.</p>
+
+ <p>In protocols where this situation cannot arise, such as XMPP,
+ this property MAY remain empty.</p>
+
+ <p>For example, consider this situation:</p>
+
+ <ol>
+ <li>Place a call (with path <tt>/call/to/simon</tt>) to the contact
+ <tt>+441234567890</tt> (which is assigned the handle <var>h</var>,
+ say), and ask to be put through to Simon McVittie;</li>
+ <li>Put that call on hold;</li>
+ <li>Place another call (with path <tt>/call/to/jonny</tt>) to
+ <tt>+441234567890</tt>, and ask to be put
+ through to Jonny Lamb;</li>
+ <li>Request a new channel with
+ <tp:member-ref>InitialChannels</tp:member-ref>:
+ <tt>['/call/to/simon', '/call/to/jonny']</tt>.</li>
+ </ol>
+
+ <p>The new channel will have the following properties, for some handles
+ <var>s</var> and <var>j</var>:</p>
+
+ <blockquote>
+ <code>{<br/>
+ ...<tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Group.GroupFlags</tp:dbus-ref>:
+ Channel_Specific_Handles | (other flags),<br/>
+ ...<tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Group.Members</tp:dbus-ref>:
+ [self_handle, s, j],<br/>
+ ...<tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Group.HandleOwners</tp:dbus-ref>:
+ { s: h, j: h },<br/>
+ ...<tp:member-ref>InitialChannels</tp:member-ref>:
+ ['/call/to/simon', '/call/to/jonny'],<br/>
+ ...<tp:member-ref>Channels</tp:member-ref>:
+ ['/call/to/simon', '/call/to/jonny'],<br/>
+ ...<tp:member-ref>OriginalChannels</tp:member-ref>:
+ { s: '/call/to/simon', j: '/call/to/jonny' },<br/>
+ # ...standard properties like ChannelType: Group elided...<br/>
+ }</code>
+ </blockquote>
+
+ <p>Change notification is via the
+ <tp:member-ref>ChannelMerged</tp:member-ref> and
+ <tp:member-ref>ChannelRemoved</tp:member-ref> signals: if
+ <var>Channel_Specific_Handle</var> in the former is non-zero, this
+ property SHOULD be updated to map that handle to the merged channel's
+ path.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="Channel_Originator_Map">
+ <tp:member name="Channel_Specific_Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A channel-specific handle for a participant in this conference.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Original_Channel" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The object path of <tp:member-ref>Channels</tp:member-ref>
+ representing the original 1-1 channel with
+ <var>Channel_Specific_Handle</var>.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A mapping from members of a conference to the original 1-1 channel with
+ that contact, if any. See
+ <tp:member-ref>OriginalChannels</tp:member-ref> for details.
+ </tp:docstring>
+ </tp:mapping>
+ </interface>
+</node>
diff --git a/spec/spec/Channel_Interface_Credentials_Storage.xml b/spec/spec/Channel_Interface_Credentials_Storage.xml
new file mode 100644
index 000000000..e44b13e32
--- /dev/null
+++ b/spec/spec/Channel_Interface_Credentials_Storage.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Credentials_Storage"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2011 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.CredentialsStorage.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.10">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.SASLAuthentication"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel interface for SASL authentication channels that can save the
+ credentials in the connection manager.</p>
+
+ <p>This interface is unlikely to be present for any SASL channels that are
+ more complex than a simple password prompt (e.g.
+ <code>X-TELEPATHY-PASSWORD</code> or <code>PLAIN</code>).</p>
+
+ <p>In practice, this interface should only be implemented by connection
+ managers that implement the <tp:dbus-ref
+ namespace="ofdT">ConnectionManager.Interface.AccountStorage.DRAFT</tp:dbus-ref>
+ interface. To clear a password that has been saved in this manner, a
+ client should call <tp:dbus-ref
+ namespace="ofdT.ConnectionManager.Interface">AccountStorage.DRAFT.ForgetCredentials</tp:dbus-ref>
+ on the Account.</p>
+ </tp:docstring>
+
+ <method name="StoreCredentials" tp:name-for-bindings="Store_Credentials">
+ <arg direction="in" name="Store" type="b">
+ <tp:docstring>
+ Whether to store the authentication credentials.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This method tells the connection manager whether to store the
+ authentication response in order to allow the connection manager to
+ sign-on automatically in the future.</p>
+ <p>If credentials have been stored in this way, the client SHOULD NOT
+ attempt to store the credentials locally in a keyring.</p>
+ <p>This method MUST be called before <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.SASLAuthentication">AcceptSASL</tp:dbus-ref>
+ is called or it will have no effect.</p>
+ </tp:docstring>
+ </method>
+ </interface>
+</node>
diff --git a/spec/spec/Channel_Interface_DTMF.xml b/spec/spec/Channel_Interface_DTMF.xml
new file mode 100644
index 000000000..bb579a113
--- /dev/null
+++ b/spec/spec/Channel_Interface_DTMF.xml
@@ -0,0 +1,342 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_DTMF" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2005-2010 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2005-2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.DTMF">
+ <tp:xor-requires>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Call1"/>
+ </tp:xor-requires>
+ <tp:changed version="0.19.6">The <tp:type>Stream_ID</tp:type>s in this
+ interface should now be ignored by CMs. This is primarily to allow this
+ interface to be used with <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Call1</tp:dbus-ref>
+ channels.</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An interface that gives a Channel the ability to send DTMF events over
+ audio streams which have been established using the StreamedMedia channel
+ type. The event codes used are in common with those defined in <a
+ href="http://www.rfc-editor.org/rfc/rfc4733.txt">RFC4733</a>, and are
+ listed in the <tp:type>DTMF_Event</tp:type> enumeration.
+ </tp:docstring>
+
+ <method name="StartTone" tp:name-for-bindings="Start_Tone">
+ <tp:changed version="0.19.6">The <var>Stream_ID</var> parameter became
+ vestigial.</tp:changed>
+ <arg direction="in" name="Stream_ID" type="u" tp:type="Stream_ID">
+ <tp:docstring>A stream ID as defined in the StreamedMedia channel
+ type. This argument is included for backwards compatibility and MUST
+ be ignored by the implementations - the tone SHOULD be sent to all
+ eligible streams in the channel.</tp:docstring>
+ </arg>
+ <arg direction="in" name="Event" type="y" tp:type="DTMF_Event">
+ <tp:docstring>A numeric event code from the DTMF_Event enum.</tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ <p>Start sending a DTMF tone to all eligible streams in the channel.
+ Where possible, the tone will continue until
+ <tp:member-ref>StopTone</tp:member-ref> is called. On certain protocols,
+ it may only be possible to send events with a predetermined length. In
+ this case, the implementation MAY emit a fixed-length tone, and the
+ StopTone method call SHOULD return NotAvailable.</p>
+ <tp:rationale>
+ The client may wish to control the exact duration and timing of the
+ tones sent as a result of user's interaction with the dialpad, thus
+ starting and stopping the tone sending explicitly.
+ </tp:rationale>
+
+ <p>Tone overlaping or queueing is not supported, so this method can only
+ be called if no DTMF tones are already being played.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError" />
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The given stream ID was invalid. Deprecated, since stream IDs
+ are ignored.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ There are no eligible audio streams.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy">
+ <tp:docstring>
+ DTMF tones are already being played.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="StopTone" tp:name-for-bindings="Stop_Tone">
+ <tp:changed version="0.19.6">The <var>Stream_ID</var> parameter became
+ vestigial.</tp:changed>
+ <arg direction="in" name="Stream_ID" type="u" tp:type="Stream_ID">
+ <tp:docstring>A stream ID as defined in the StreamedMedia channel
+ type. This argument is included for backwards compatibility and MUST
+ be ignored by the implementations - the sending SHOULD be stoped in
+ all eligible streams in the channel.</tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Stop sending any DTMF tones which have been started using the
+ <tp:member-ref>StartTone</tp:member-ref> or
+ <tp:member-ref>MultipleTones</tp:member-ref> methods.
+ If there is no current tone, this method will do nothing.
+ If MultipleTones was used, the client should not assume the
+ sending has stopped immediately; instead, the client should wait
+ for the StoppedTones signal.
+ <tp:rationale>
+ On some protocols it might be impossible to cancel queued tones
+ immediately.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError" />
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The given stream ID was invalid. Deprecated, since stream IDs
+ are ignored.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ Continuous tones are not supported by this stream. Deprecated,
+ since stream IDs are ignored.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="MultipleTones" tp:name-for-bindings="Multiple_Tones">
+ <tp:added version="0.19.6" />
+ <tp:changed version="0.21.3">The characters [pPxXwW,] must
+ also be supported.</tp:changed>
+ <arg direction="in" name="Tones" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A string representation of one or more DTMF
+ events. Implementations of this method MUST support all of the
+ following characters in this string:</p>
+
+ <ul>
+ <li>the digits 0-9, letters A-D and a-d, and symbols '*' and '#'
+ correspond to the members of <tp:type>DTMF_Event</tp:type></li>
+
+ <li>any of 'p', 'P', 'x', 'X' or ',' (comma) results in an
+ implementation-defined pause, typically for 3 seconds</li>
+
+ <li>'w' or 'W' waits for the user to continue, by stopping
+ interpretation of the string, and if there is more to be played,
+ emitting the <tp:member-ref>TonesDeferred</tp:member-ref> signal
+ with the rest of the string as its argument: see that signal
+ for details</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ <p>Send multiple DTMF events to all eligible streams in the channel.
+ Each tone will be played for an implementation-defined number of
+ milliseconds (typically 250ms), followed by a gap before the next tone
+ is played (typically 100ms). The
+ duration and gap are defined by the protocol or connection manager.</p>
+
+ <tp:rationale>
+ <p>In cases where the client knows in advance the tone sequence it
+ wants to send, it's easier to use this method than manually start
+ and stop each tone in the sequence.</p>
+
+ <p>The tone and gap lengths may need to vary for interoperability,
+ according to the protocol and other implementations' ability to
+ recognise tones. At the time of writing, GStreamer uses a
+ minimum of 250ms tones and 100ms gaps when playing in-band DTMF
+ in the normal audio stream, or 70ms tones and 50ms gaps when
+ encoding DTMF as <code>audio/telephone-event</code>.</p>
+ </tp:rationale>
+
+ <p>Tone overlaping or queueing is not supported, so this method can only
+ be called if no DTMF tones are already being played.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError" />
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The supplied Tones string was invalid.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ There are no eligible audio streams.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy">
+ <tp:docstring>
+ DTMF tones are already being played.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <property name="CurrentlySendingTones"
+ tp:name-for-bindings="Currently_Sending_Tones" type="b" access="read">
+ <tp:added version="0.19.6" />
+ <tp:docstring>
+ Indicates whether there are DTMF tones currently being sent in the
+ channel. If so, the client should wait for
+ <tp:member-ref>StoppedTones</tp:member-ref> signal before trying to
+ send more tones.
+ </tp:docstring>
+ </property>
+
+ <property name="InitialTones" tp:name-for-bindings="Initial_Tones"
+ type="s" access="read">
+ <tp:added version="0.19.6" />
+ <tp:docstring>
+ <p>If non-empty in a channel request that will create a new channel,
+ the connection manager should send the tones immediately after
+ at least one eligible audio stream has been created in the
+ channel.</p>
+
+ <p>This property is immutable (cannot change).</p>
+ </tp:docstring>
+ </property>
+
+ <property name="DeferredTones" tp:name-for-bindings="Deferred_Tones"
+ type="s" access="read">
+ <tp:added version="0.21.3" />
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The tones waiting for the user to continue, if any.</p>
+
+ <p>When this property is set to a non-empty value,
+ <tp:member-ref>TonesDeferred</tp:member-ref> is emitted.
+ When any tones are played (i.e. whenever
+ <tp:member-ref>SendingTones</tp:member-ref> is emitted),
+ this property is reset to the empty string.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="TonesDeferred" tp:name-for-bindings="Tones_Deferred">
+ <tp:added version="0.21.3" />
+ <arg name="Tones" type="s">
+ <tp:docstring>The new non-empty value of
+ <tp:member-ref>DeferredTones</tp:member-ref>.</tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when 'w' or 'W', indicating "wait for the user to continue",
+ is encountered while playing a DTMF string queued by
+ <tp:member-ref>MultipleTones</tp:member-ref> or
+ <tp:member-ref>InitialTones</tp:member-ref>. Any queued DTMF events
+ after the 'w', which have not yet been played, are placed in the
+ <tp:member-ref>DeferredTones</tp:member-ref> property and copied
+ into this signal's argument.</p>
+
+ <p>When the channel handler is ready to continue, it MAY pass the
+ value of <tp:member-ref>DeferredTones</tp:member-ref> to
+ <tp:member-ref>MultipleTones</tp:member-ref>, to resume sending.
+ Alternatively, it MAY ignore the deferred tones, or even play
+ different tones instead. Any deferred tones are discarded the next
+ time a tone is played.</p>
+
+ <p>This signal SHOULD NOT be emitted if there is nothing left to play,
+ i.e. if the 'w' was the last character in the DTMF string.</p>
+ </tp:docstring>
+ </signal>
+
+ <signal name="SendingTones" tp:name-for-bindings="Sending_Tones">
+ <tp:added version="0.19.6" />
+ <arg name="Tones" type="s">
+ <tp:docstring>DTMF string (one or more events) that is to be played.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>DTMF tone(s)are being sent to all eligible streams in the channel.
+ The signal is provided to indicating the fact that the streams are
+ currently being used to send one or more DTMF tones, so any other
+ media input is not getting through to the audio stream. It also
+ serves as a cue for the
+ <tp:member-ref>StopTone</tp:member-ref> method.</p>
+ </tp:docstring>
+ </signal>
+
+ <signal name="StoppedTones" tp:name-for-bindings="Stopped_Tones">
+ <tp:added version="0.19.6" />
+ <arg name="Cancelled" type="b">
+ <tp:docstring>True if the DTMF tones were actively cancelled via
+ <tp:member-ref>StopTone</tp:member-ref>.</tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>DTMF tones have finished playing on streams in this channel.</p>
+ </tp:docstring>
+ </signal>
+
+ <tp:enum name="DTMF_Event" type="y">
+ <tp:enumvalue suffix="Digit_0" value="0">
+ <tp:docstring>0</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_1" value="1">
+ <tp:docstring>1</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_2" value="2">
+ <tp:docstring>2</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_3" value="3">
+ <tp:docstring>3</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_4" value="4">
+ <tp:docstring>4</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_5" value="5">
+ <tp:docstring>5</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_6" value="6">
+ <tp:docstring>6</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_7" value="7">
+ <tp:docstring>7</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_8" value="8">
+ <tp:docstring>8</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Digit_9" value="9">
+ <tp:docstring>9</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Asterisk" value="10">
+ <tp:docstring>*</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Hash" value="11">
+ <tp:docstring>#</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Letter_A" value="12">
+ <tp:docstring>A</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Letter_B" value="13">
+ <tp:docstring>B</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Letter_C" value="14">
+ <tp:docstring>C</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Letter_D" value="15">
+ <tp:docstring>D</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Destroyable.xml b/spec/spec/Channel_Interface_Destroyable.xml
new file mode 100644
index 000000000..ce5592327
--- /dev/null
+++ b/spec/spec/Channel_Interface_Destroyable.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Destroyable"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.Destroyable">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.17.14">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface exists to support channels where
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>
+ is insufficiently destructive. At the moment this means
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Type.Text</tp:dbus-ref>,
+ but the existence of this interface means that unsupported channels
+ can be terminated in a non-channel-type-specific way.</p>
+ </tp:docstring>
+
+ <method name="Destroy" tp:name-for-bindings="Destroy">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Close the channel abruptly, possibly with loss of data. The
+ connection manager MUST NOT re-create the channel unless/until
+ more events occur.</p>
+
+ <tp:rationale>
+ <p>The main motivating situation for this method is that when a Text
+ channel with pending messages is closed with Close, it comes back
+ as an incoming channel (to avoid a race between Close and an
+ incoming message). If Destroy is called on a Text channel, the CM
+ should delete all pending messages and close the channel, and
+ the channel shouldn't be re-created until/unless another message
+ arrives.</p>
+ </tp:rationale>
+
+ <p>Most clients SHOULD call
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>
+ instead. However, if a client explicitly intends to destroy the
+ channel with possible loss of data, it SHOULD call this method
+ if this interface is supported (according to the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interfaces</tp:dbus-ref>
+ property), falling back to Close if not.</p>
+
+ <p>In particular, channel dispatchers SHOULD use this method if
+ available when terminating channels that cannot be handled
+ correctly (for instance, if no handler has been installed for
+ a channel type, or if the handler crashes repeatedly).</p>
+
+ <p>Connection managers do not need to implement this interface on
+ channels where Close and Destroy would be equivalent.</p>
+
+ <tp:rationale>
+ <p>Callers need to be able to fall back to Close in any case.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_File_Transfer_Metadata.xml b/spec/spec/Channel_Interface_File_Transfer_Metadata.xml
new file mode 100644
index 000000000..4d2d728d9
--- /dev/null
+++ b/spec/spec/Channel_Interface_File_Transfer_Metadata.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_File_Transfer_Metadata"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2011 Collabora Ltd.</tp:copyright>
+
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.FileTransfer.Metadata">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.FileTransfer"/>
+ <tp:added version="0.25.0"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface exists to provide a mechanism to include
+ arbitrary additional information in file transfers. For
+ example, one might want to send a document and include the
+ number of times the character P appeared in the file, so would
+ add <tt>NumberOfPs=42</tt> to the
+ <tp:member-ref>Metadata</tp:member-ref> property.</p>
+
+ <p><tp:member-ref>ServiceName</tp:member-ref> living in its own
+ property makes it easier for specific applications to send
+ files to each other, bypassing the standard handler. For
+ example, the Banshee Telepathy plugin handler could match on
+ <tp:member-ref>ServiceName</tp:member-ref> so the Empathy file
+ transfer is not used instead.</p>
+ </tp:docstring>
+
+ <property name="ServiceName" tp:name-for-bindings="Service_Name"
+ type="s" access="readwrite" tp:immutable="sì"
+ tp:requestable="naturalmente">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A string representing the service name that will be used
+ over the file transfer channel. This property is equivalent
+ to the <tp:dbus-ref
+ namespace="ofdT">Channel.Type.DBusTube.ServiceName</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="ofdT">Channel.Type.StreamTube.Service</tp:dbus-ref>
+ properties. If no service name is given then this property
+ will be the empty string.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Metadata" tp:name-for-bindings="Metadata"
+ type="a{sas}" tp:type="Metadata" access="readwrite"
+ tp:immutable="sì" tp:requestable="naturalmente">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about the file transfer set by the
+ channel initiator. If no additional information is given then
+ this property will be empty.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="Metadata" type="a{sas}">
+ <tp:docstring>
+ A mapping from string key to a list of strings, used in the
+ <tp:member-ref>Metadata</tp:member-ref> property. To emulate a
+ simple string → string hash table one should have exactly one
+ member in the value string list.
+
+ <tp:rationale>
+ This property is an a{sas} primarily because this maps
+ easily to <a
+ href="http://xmpp.org/extensions/xep-0004.html">XEP-0004
+ Data Forms</a>, and allows more structured metadata than
+ a{ss} would. (For instance, a list of RDF triples could be
+ expressed as one long array of strings, or as three-element
+ values for a series of dummy key names, rather than as one
+ big string blob.)
+
+ While it might be convenient for applications to allow keys
+ of arbitrary types, the added convenience would be
+ outweighed by having to define the XMPP representation
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:member name="Key" type="s"/>
+ <tp:member name="Values" type="as"/>
+ </tp:mapping>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Group.xml b/spec/spec/Channel_Interface_Group.xml
new file mode 100644
index 000000000..890e84ebe
--- /dev/null
+++ b/spec/spec/Channel_Interface_Group.xml
@@ -0,0 +1,1252 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Group" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2005-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2005-2009 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Group">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:struct name="Local_Pending_Info" array-name="Local_Pending_Info_List">
+ <tp:docstring>A structure representing a contact whose attempt to
+ join a group is to be confirmed by the local user using
+ <tp:member-ref>AddMembers</tp:member-ref>.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="To_Be_Added">
+ <tp:docstring>
+ The contact to be added to the group
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Contact_Handle" name="Actor">
+ <tp:docstring>
+ The contact requesting or causing the change
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Channel_Group_Change_Reason" name="Reason">
+ <tp:docstring>
+ The reason for the change
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Message">
+ <tp:docstring>
+ A human-readable message from the Actor, or an empty string
+ if there is no message
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="AddMembers" tp:name-for-bindings="Add_Members">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of contact handles to invite to the channel
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Message" type="s">
+ <tp:docstring>
+ A string message, which can be blank if desired
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Invite all the given contacts into the channel, or accept requests for
+ channel membership for contacts on the pending local list.</p>
+
+ <p>A message may be provided along with the request, which will be sent
+ to the server if supported. See the CHANNEL_GROUP_FLAG_MESSAGE_ADD and
+ CHANNEL_GROUP_FLAG_MESSAGE_ACCEPT
+ <tp:member-ref>GroupFlags</tp:member-ref> to see in which cases this
+ message should be provided.</p>
+
+ <p>Attempting to add contacts who are already members is allowed;
+ connection managers must silently accept this, without error.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Full"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.InviteOnly"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Banned"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetAllMembers" tp:name-for-bindings="Get_All_Members">
+ <tp:deprecated version="0.17.6">Use GetAll on the D-Bus
+ Properties D-Bus interface to get properties including Members,
+ RemotePendingMembers and LocalPendingMembers instead, falling back to
+ this method and GetLocalPendingMembersWithInfo if necessary.
+ </tp:deprecated>
+
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Members">
+ <tp:docstring>
+ array of handles of current members
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Local_Pending">
+ <tp:docstring>
+ array of handles of local pending members
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Remote_Pending">
+ <tp:docstring>
+ array of handles of remote pending members
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns arrays of all current, local and remote pending channel
+ members.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:flags name="Channel_Group_Flags" value-prefix="Channel_Group_Flag" type="u">
+ <tp:flag suffix="Can_Add" value="1">
+ <tp:docstring>
+ The <tp:member-ref>AddMembers</tp:member-ref> method can be used to
+ add or invite members who are
+ not already in the local pending list (which is always valid).
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Can_Remove" value="2">
+ <tp:docstring>
+ The <tp:member-ref>RemoveMembers</tp:member-ref> method can be used
+ to remove channel members
+ (removing those on the pending local list is always valid).
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Can_Rescind" value="4">
+ <tp:docstring>
+ The <tp:member-ref>RemoveMembers</tp:member-ref> method can be used
+ on people on the remote
+ pending list.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Add" value="8">
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>AddMembers</tp:member-ref> on
+ contacts who are not currently pending members.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Remove" value="16">
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>RemoveMembers</tp:member-ref> on
+ contacts who are currently channel members.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Accept" value="32">
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>AddMembers</tp:member-ref> on
+ contacts who are locally pending.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Reject" value="64">
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>RemoveMembers</tp:member-ref> on
+ contacts who are locally pending.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Rescind" value="128">
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>RemoveMembers</tp:member-ref> on
+ contacts who are remote pending.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Channel_Specific_Handles" value="256">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The members of this group have handles which are specific to
+ this channel, and are not valid as general-purpose handles on
+ the connection. Depending on the channel, it may be possible to
+ check the <tp:member-ref>HandleOwners</tp:member-ref> property or
+ call <tp:member-ref>GetHandleOwners</tp:member-ref> to find the
+ owners of these handles, which should be done if you wish to (e.g.)
+ subscribe to the contact's presence.
+ </p>
+
+ <p>
+ Connection managers must ensure that any given handle is not
+ simultaneously a general-purpose handle and a channel-specific
+ handle.
+ </p>
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Only_One_Group" value="512">
+ <tp:docstring>
+ Placing a contact in multiple groups of this type is not allowed
+ and will raise NotAvailable (on services where contacts may only
+ be in one user-defined group, user-defined groups will have
+ this flag).
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Handle_Owners_Not_Available" value="1024">
+ <tp:docstring>
+ In rooms with channel specific handles (ie Channel_Specific_Handles
+ flag is set), this flag indicates that no handle owners are
+ available, apart from the owner of the
+ <tp:member-ref>SelfHandle</tp:member-ref>.
+
+ <tp:rationale>
+ This used to be an important optimization to avoid repeated
+ GetHandleOwners calls, before we introduced the
+ <tp:member-ref>HandleOwners</tp:member-ref> property and
+ <tp:member-ref>HandleOwnersChanged</tp:member-ref> signal.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Properties" value="2048">
+ <tp:docstring>
+ This flag indicates that all the properties introduced in
+ specification 0.17.6 are fully supported.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Members_Changed_Detailed" value="4096">
+ <tp:docstring>
+ Indicates that <tp:member-ref>MembersChangedDetailed</tp:member-ref>
+ will be emitted for changes to this group's members in addition to
+ <tp:member-ref>MembersChanged</tp:member-ref>.
+ Clients can then connect to the former and ignore emission of the
+ latter. This flag's state MUST NOT change over the lifetime of a
+ channel.
+
+ <tp:rationale>
+ If it were allowed to change, client bindings would have to always
+ connect to MembersChanged just in case the flag ever went away (and
+ generally be unnecessarily complicated), which would mostly negate
+ the point of having this flag in the first place.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Message_Depart" value="8192">
+ <tp:added version="0.17.21"/>
+ <tp:docstring>
+ A message may be sent to the server when calling
+ <tp:member-ref>RemoveMembers</tp:member-ref> on
+ the <tp:member-ref>SelfHandle</tp:member-ref>.
+
+ <tp:rationale>
+ This would be set for XMPP Multi-User Chat or IRC channels,
+ but not for a typical implementation of streamed media calls.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <property name="GroupFlags" type="u" tp:type="Channel_Group_Flags"
+ access="read" tp:name-for-bindings="Group_Flags">
+ <tp:docstring>
+ An integer representing the bitwise-OR of flags on this
+ channel. The user interface can use this to present information about
+ which operations are currently valid. Change notification is via
+ the <tp:member-ref>GroupFlagsChanged</tp:member-ref> signal.
+ </tp:docstring>
+ <tp:added version="0.17.6">For backwards compatibility,
+ clients should fall back to calling GetGroupFlags if
+ Channel_Group_Flag_Properties is not present.</tp:added>
+ </property>
+
+ <method name="GetGroupFlags" tp:name-for-bindings="Get_Group_Flags">
+ <arg direction="out" type="u" tp:type="Channel_Group_Flags"
+ name="Group_Flags">
+ <tp:docstring>
+ The value of the GroupFlags property
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns the value of the <tp:member-ref>GroupFlags</tp:member-ref> property.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Use GetAll on the D-Bus
+ Properties D-Bus interface to get properties including GroupFlags
+ instead, falling back to this method if necessary.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:mapping name="Handle_Owner_Map">
+ <tp:docstring>
+ A map from channel-specific handles to their owners.
+ </tp:docstring>
+ <tp:added version="0.17.6">For backwards compatibility,
+ clients should fall back to calling GetHandleOwners if
+ Channel_Group_Flag_Properties is not present.</tp:added>
+
+ <tp:member type="u" name="Channel_Specific_Handle"
+ tp:type="Contact_Handle">
+ <tp:docstring>
+ A nonzero channel-specific handle
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Global_Handle" tp:type="Contact_Handle">
+ <tp:docstring>
+ The global handle that owns the corresponding channel-specific
+ handle, or 0 if this could not be determined
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="HandleOwners" type="a{uu}" tp:type="Handle_Owner_Map"
+ access="read" tp:name-for-bindings="Handle_Owners">
+ <tp:docstring>
+ A map from channel-specific handles to their owners, including
+ at least all of the channel-specific handles in this channel's members,
+ local-pending or remote-pending sets as keys. Any handle not in
+ the keys of this mapping is not channel-specific in this channel.
+ Handles which are channel-specific, but for which the owner is
+ unknown, MUST appear in this mapping with 0 as owner. Change
+ notification is via the
+ <tp:member-ref>HandleOwnersChanged</tp:member-ref> signal.
+ </tp:docstring>
+ <tp:added version="0.17.6"/>
+ </property>
+
+ <signal name="HandleOwnersChanged"
+ tp:name-for-bindings="Handle_Owners_Changed">
+ <tp:docstring>
+ Emitted whenever the <tp:member-ref>HandleOwners</tp:member-ref>
+ property changes.
+ </tp:docstring>
+ <tp:added version="0.17.6">This signal should not be relied on
+ unless Channel_Group_Flag_Properties is present.</tp:added>
+ <tp:deprecated version="0.23.4">Clients should listen to
+ <tp:member-ref>HandleOwnersChangedDetailed</tp:member-ref> instead to
+ get the new identifiers as well.
+ </tp:deprecated>
+
+ <arg name="Added" type="a{uu}" tp:type="Handle_Owner_Map">
+ <tp:docstring>
+ A map from channel-specific handles to their owners, in which the
+ keys include all the handles that were added to the keys of the
+ HandleOwners property, and all the handles in that property whose
+ owner has changed
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The channel-specific handles that were removed from the keys of the
+ HandleOwners property, as a result of the contact leaving this group
+ in a previous <tp:member-ref>MembersChanged</tp:member-ref> signal
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="HandleOwnersChangedDetailed"
+ tp:name-for-bindings="Handle_Owners_Changed_Detailed">
+ <tp:docstring>
+ <p>Emitted whenever the <tp:member-ref>HandleOwners</tp:member-ref>
+ property changes.</p>
+
+ <p>Clients can assume this signal is emitted by the Connection Manager
+ if the <tp:member-ref>MemberIdentifiers</tp:member-ref> property exists
+ </p>
+ </tp:docstring>
+ <tp:added version="0.23.4"/>
+
+ <arg name="Added" type="a{uu}" tp:type="Handle_Owner_Map">
+ <tp:docstring>
+ A map from channel-specific handles to their owners, in which the
+ keys include all the handles that were added to the keys of the
+ HandleOwners property, and all the handles in that property whose
+ owner has changed
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The channel-specific handles that were removed from the keys of the
+ HandleOwners property, as a result of the contact leaving this group
+ in a previous <tp:member-ref>MembersChanged</tp:member-ref> signal
+ </tp:docstring>
+ </arg>
+ <arg name="Identifiers" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring>
+ The string identifiers for handles mentioned in this signal, to
+ give clients the minimal information necessary to create contacts
+ without waiting for round-trips. Connection managers MUST include at
+ least the identifiers for all handles in the Added map, and MAY
+ include those from Removed array.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="GetHandleOwners" tp:name-for-bindings="Get_Handle_Owners">
+ <arg direction="in" name="Handles" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of integer handles representing members of the channel
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="au" tp:type="Contact_Handle[]" name="Owners">
+ <tp:docstring>
+ An array of integer handles representing the owner handles of
+ the given room members, in the same order, or 0 if the
+ owner is not available
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ If the CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES flag is set on
+ the channel, then the handles of the group members are specific
+ to this channel, and are not meaningful in a connection-wide
+ context such as contact lists. This method allows you to find
+ the owner of the handle if it can be discovered in this channel,
+ or 0 if the owner is not available.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Clients should use the
+ HandleOwners property and HandleOwnersChanged signal if
+ Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This channel doesn't have the CHANNEL_SPECIFIC_HANDLES flag,
+ so handles in this channel are globally meaningful and calling
+ this method is not necessary
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ One of the given handles is not a member
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetLocalPendingMembers"
+ tp:name-for-bindings="Get_Local_Pending_Members">
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Handles"/>
+ <tp:docstring>
+ Returns the To_Be_Added handle (only) for each structure in the
+ <tp:member-ref>LocalPendingMembers</tp:member-ref> property.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Use the LocalPendingMembers
+ property, if Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetLocalPendingMembersWithInfo"
+ tp:name-for-bindings="Get_Local_Pending_Members_With_Info">
+ <tp:added version="0.15.0" />
+ <tp:docstring>
+ Returns the <tp:member-ref>LocalPendingMembers</tp:member-ref> property.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Use the LocalPendingMembers
+ property, if Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <arg direction="out" type="a(uuus)" tp:type="Local_Pending_Info[]"
+ name="Info">
+ <tp:docstring>
+ An array of structs containing:
+ <ul>
+ <li>
+ A handle representing the contact requesting channel membership
+ </li>
+ <li>
+ A handle representing the contact making the request, or 0 if
+ unknown
+ </li>
+ <li>
+ The reason for the request: one of the values of
+ <tp:type>Channel_Group_Change_Reason</tp:type>
+ </li>
+ <li>
+ A string message containing the reason for the request if any (or
+ blank if none)
+ </li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="LocalPendingMembers" access="read"
+ type="a(uuus)" tp:type="Local_Pending_Info[]"
+ tp:name-for-bindings="Local_Pending_Members">
+ <tp:docstring>
+ An array of structs containing handles representing contacts
+ requesting channel membership and awaiting local approval with
+ <tp:member-ref>AddMembers</tp:member-ref>.
+ </tp:docstring>
+ <tp:added version="0.17.6">If Channel_Group_Flag_Properties is
+ not present, clients should fall back to using the
+ deprecated GetLocalPendingMembersWithInfo method, or fall back
+ from that to the deprecated GetAllMembers method.</tp:added>
+ </property>
+
+ <property name="Members" tp:name-for-bindings="Members"
+ access="read" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The members of this channel.
+ </tp:docstring>
+ <tp:added version="0.17.6">If Channel_Group_Flag_Properties
+ is not set, fall back to calling GetAllMembers.</tp:added>
+ </property>
+
+ <method name="GetMembers" tp:name-for-bindings="Get_Members">
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Handles"/>
+ <tp:docstring>
+ Returns the <tp:member-ref>Members</tp:member-ref> property.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Use the Members
+ property, if Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="RemotePendingMembers" access="read" type="au"
+ tp:type="Contact_Handle[]" tp:name-for-bindings="Remote_Pending_Members">
+ <tp:docstring>
+ An array of handles representing contacts who have been
+ invited to the channel and are awaiting remote approval.
+ </tp:docstring>
+ <tp:added version="0.17.6">If Channel_Group_Flag_Properties
+ is not set, fall back to calling GetAllMembers.</tp:added>
+ </property>
+
+ <method name="GetRemotePendingMembers"
+ tp:name-for-bindings="Get_Remote_Pending_Members">
+ <arg direction="out" type="au" tp:type="Contact_Handle[]"
+ name="Handles"/>
+ <tp:docstring>
+ Returns an array of handles representing contacts who have been
+ invited to the channel and are awaiting remote approval.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Use the
+ <tp:member-ref>RemotePendingMembers</tp:member-ref>
+ property, if Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="SelfHandleChanged" tp:name-for-bindings="Self_Handle_Changed">
+ <tp:docstring>
+ Emitted whenever the <tp:member-ref>SelfHandle</tp:member-ref> property
+ changes.
+ </tp:docstring>
+ <tp:added version="0.17.6">This signal should not be relied on
+ unless Channel_Group_Flag_Properties is present.</tp:added>
+ <tp:deprecated version="0.23.4">Clients should listen to
+ <tp:member-ref>SelfContactChanged</tp:member-ref> instead to get the new
+ identifier as well.
+ </tp:deprecated>
+
+ <arg type="u" tp:type="Contact_Handle" name="Self_Handle">
+ <tp:docstring>
+ The new value of the SelfHandle property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="SelfContactChanged" tp:name-for-bindings="Self_Contact_Changed">
+ <tp:docstring>
+ <p>Emitted whenever the <tp:member-ref>SelfHandle</tp:member-ref> property
+ changes.</p>
+
+ <p>Clients can assume this signal is emitted by the Connection Manager
+ if the <tp:member-ref>MemberIdentifiers</tp:member-ref> property exists.
+ </p>
+ </tp:docstring>
+ <tp:added version="0.23.4"/>
+
+ <arg type="u" tp:type="Contact_Handle" name="Self_Handle">
+ <tp:docstring>
+ The new value of the SelfHandle property.
+ </tp:docstring>
+ </arg>
+ <arg type="s" name="Self_ID">
+ <tp:docstring>
+ The new value of the SelfHandle property's identifier.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="SelfHandle" type="u" tp:type="Contact_Handle"
+ access="read" tp:name-for-bindings="Self_Handle">
+ <tp:docstring>
+ The handle for the user on this channel (which can also be a
+ local or remote pending member), or 0 if the user is not a member at
+ all (which is likely to be the case, for instance, on <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">ContactList</tp:dbus-ref>
+ channels). Note that this is different from the result of
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.GetSelfHandle</tp:dbus-ref>
+ on some protocols, so the value of this handle should
+ always be used with the methods of this interface.
+ </tp:docstring>
+ <tp:added version="0.17.6">For backwards compatibility,
+ clients should fall back to calling GetSelfHandle if
+ Channel_Group_Flag_Properties is not present.</tp:added>
+ </property>
+
+ <property name="MemberIdentifiers" type="a{us}" tp:type="Handle_Identifier_Map"
+ access="read" tp:name-for-bindings="Member_Identifiers">
+ <tp:docstring>
+ The string identifiers for handles mentioned in this channel, to
+ give clients the minimal information necessary to create contacts
+ without waiting for round-trips. Connection managers MUST include at
+ least the identifiers for
+ <tp:member-ref>SelfHandle</tp:member-ref>,
+ <tp:member-ref>Members</tp:member-ref>,
+ <tp:member-ref>LocalPendingMembers</tp:member-ref> (and their actors if
+ any),
+ <tp:member-ref>RemotePendingMembers</tp:member-ref> and
+ <tp:member-ref>HandleOwners</tp:member-ref>.
+ </tp:docstring>
+ <tp:added version="0.23.4"/>
+ </property>
+
+ <method name="GetSelfHandle" tp:name-for-bindings="Get_Self_Handle">
+ <arg direction="out" type="u" tp:type="Contact_Handle"
+ name="Self_Handle"/>
+ <tp:docstring>
+ Returns the value of the <tp:member-ref>SelfHandle</tp:member-ref>
+ property.
+ </tp:docstring>
+ <tp:deprecated version="0.17.6">Clients should retrieve the
+ SelfHandle property using GetAll instead,
+ if Channel_Group_Flag_Properties is present.</tp:deprecated>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="GroupFlagsChanged" tp:name-for-bindings="Group_Flags_Changed">
+ <arg name="Added" type="u" tp:type="Channel_Group_Flags">
+ <tp:docstring>
+ A bitwise OR of the flags which have been set
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="u" tp:type="Channel_Group_Flags">
+ <tp:docstring>
+ A bitwise OR of the flags which have been cleared
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the flags as returned by
+ <tp:member-ref>GetGroupFlags</tp:member-ref> are changed.
+ The user interface should be updated as appropriate.
+ </tp:docstring>
+ </signal>
+
+ <tp:enum name="Channel_Group_Change_Reason" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The reason for a set of handles to move to one of
+ <tp:member-ref>Members</tp:member-ref>,
+ <tp:member-ref>LocalPendingMembers</tp:member-ref> or
+ <tp:member-ref>RemotePendingMembers</tp:member-ref>, or to be removed
+ from the group. A client may supply a reason when attempting to
+ remove members from a group with
+ <tp:member-ref>RemoveMembersWithReason</tp:member-ref>, and reasons
+ are supplied by the CM when emitting
+ <tp:member-ref>MembersChanged</tp:member-ref> and
+ <tp:member-ref>MembersChangedDetailed</tp:member-ref>. Some reason
+ codes have different meanings depending on the <var>Actor</var> in a
+ MembersChanged signal.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>No reason was provided for this change.</p>
+
+ <p>In particular, this reason SHOULD be used when representing
+ users joining a named chatroom in the usual way, users leaving
+ a chatroom by their own request, and normal termination of a
+ StreamedMedia call by the remote user.</p>
+
+ <p>If the <tp:member-ref>SelfHandle</tp:member-ref> is removed from
+ a group for this reason and the actor is not the SelfHandle, the
+ equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Terminated</code>.</p>
+
+ <p>If the SelfHandle is removed from a group for this reason and
+ the actor is also the SelfHandle, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cancelled</code>.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Offline" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is due to a user going offline. Also used when
+ user is already offline, but this wasn't known previously.</p>
+
+ <p>If a one-to-one <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ call fails because the contact being called is offline, the
+ connection manager SHOULD indicate this by removing both the
+ <tp:member-ref>SelfHandle</tp:member-ref> and the other contact's
+ handle from the Group interface with reason Offline.</p>
+
+ <tp:rationale>
+ For 1-1 calls, the call terminates as a result of removing the
+ remote contact, so the SelfHandle should be removed at the same
+ time as the remote contact and for the same reason.
+ </tp:rationale>
+
+ <p>If a handle is removed from a group for this reason, the
+ equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Offline</code>.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Kicked" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is due to a kick operation.</p>
+
+ <p>If the <tp:member-ref>SelfHandle</tp:member-ref> is removed
+ from a group for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Channel.Kicked</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Busy" value="3">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is due to a busy indication.</p>
+
+ <p>If a one-to-one <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ call fails because the contact being called is busy, the
+ connection manager SHOULD indicate this by removing both the
+ <tp:member-ref>SelfHandle</tp:member-ref> and the other contact's
+ handle from the Group interface with reason Busy.</p>
+
+ <tp:rationale>
+ For 1-1 calls, the call terminates as a result of removing the
+ remote contact, so the SelfHandle should be removed at the same
+ time as the remote contact and for the same reason.
+ </tp:rationale>
+
+ <p>If the <tp:member-ref>SelfHandle</tp:member-ref> is removed
+ from a group for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Busy</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Invited" value="4">
+ <tp:docstring>
+ The change is due to an invitation. This reason SHOULD only be used
+ when contacts are added to the remote-pending set (to indicate that
+ the contact has been invited) or to the members (to indicate that
+ the contact has accepted the invitation).
+
+ <tp:rationale>
+ Otherwise, what would it mean?
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Banned" value="5">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is due to a kick+ban operation.</p>
+
+ <p>If the <tp:member-ref>SelfHandle</tp:member-ref> is removed
+ from a group for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Channel.Banned</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Error" value="6">
+ <tp:docstring>
+ The change is due to an error occurring.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Invalid_Contact" value="7">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is because the requested contact does not exist.</p>
+
+ <p>For instance, if the user invites a nonexistent contact to a
+ chatroom or attempts to call a nonexistent contact, this could
+ be indicated by the CM adding that contact's handle to
+ remote-pending for reason None or Invited, then removing it for
+ reason Invalid_Contact. In the case of a 1-1 StreamedMedia
+ call, the CM SHOULD remove the self handle from the Group
+ in the same signal.</p>
+
+ <tp:rationale>
+ For 1-1 calls, the call terminates as a result of removing the
+ remote contact, so the SelfHandle should be removed at the same
+ time as the remote contact and for the same reason.
+ </tp:rationale>
+
+ <p>If a contact is removed from a group for this reason, the
+ equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.DoesNotExist</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="No_Answer" value="8">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is because the requested contact did not respond.</p>
+
+ <p>If a one-to-one <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ call fails because the contact being called did not respond, or the
+ local user did not respond to an incoming call, the
+ connection manager SHOULD indicate this by removing both the
+ <tp:member-ref>SelfHandle</tp:member-ref> and the other contact's
+ handle from the Group interface with reason No_Answer.</p>
+
+ <tp:rationale>
+ Documenting existing practice.
+ </tp:rationale>
+
+ <p>If a contact is removed from a group for this reason, the
+ equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.NoAnswer</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Renamed" value="9">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is because a contact's unique identifier changed.
+ There must be exactly one handle in the removed set and exactly
+ one handle in one of the added sets. The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Renaming">Renamed</tp:dbus-ref>
+ signal on the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Renaming</tp:dbus-ref>
+ interface will have been emitted for the same handles,
+ shortly before this <tp:member-ref>MembersChanged</tp:member-ref> signal is emitted.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Permission_Denied" value="10">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is because there was no permission to contact the
+ requested handle.</p>
+
+ <p>If a contact is removed from a group for this reason, the
+ equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.PermissionDenied</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Separated" value="11">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If members are removed with this reason code, the change is
+ because the group has split into unconnected parts which can only
+ communicate within themselves (e.g. netsplits on IRC use this
+ reason code).
+ </p>
+ <p>
+ If members are added with this reason code, the change is because
+ unconnected parts of the group have rejoined. If this channel
+ carries messages (e.g. <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Tubes</tp:dbus-ref>
+ channels) applications must
+ assume that the contacts being added are likely to have missed some
+ messages as a result of the separation, and that the contacts
+ in the group are likely to have missed some messages from the
+ contacts being added.
+ </p>
+ <p>Note that from the added contacts' perspective, they have been
+ in the group all along, and the contacts we indicate to be in
+ the group (including the local user) have just rejoined
+ the group with reason Separated. Application protocols in Tubes
+ should be prepared to cope with this situation.
+ </p>
+
+ <p>The <tp:member-ref>SelfHandle</tp:member-ref> SHOULD NOT be
+ removed from channels with this reason.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <signal name="MembersChanged" tp:name-for-bindings="Members_Changed">
+ <arg name="Message" type="s">
+ <tp:docstring>
+ A string message from the server, or blank if not
+ </tp:docstring>
+ </arg>
+ <arg name="Added" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members added to the channel
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members removed from the channel
+ </tp:docstring>
+ </arg>
+ <arg name="Local_Pending" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members who are pending local approval
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Pending" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members who are pending remote approval
+ </tp:docstring>
+ </arg>
+ <arg name="Actor" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact handle of the person who made the change, or 0
+ if not known
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="u" tp:type="Channel_Group_Change_Reason">
+ <tp:docstring>
+ A reason for the change
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when contacts join any of the three lists (members, local
+ pending or remote pending) or when they leave any of the three lists.
+ There may also be a message from the server regarding this change,
+ which may be displayed to the user if desired.</p>
+
+ <p>All channel-specific handles that are mentioned in this signal
+ MUST be represented in the value of the
+ <tp:member-ref>HandleOwners</tp:member-ref> property.
+ In practice, this will mean that
+ <tp:member-ref>HandleOwnersChanged</tp:member-ref> is
+ emitted <em>before</em> emitting a MembersChanged signal in which
+ channel-specific handles are added, but that it is emitted
+ <em>after</em> emitting a MembersChanged signal in which
+ channel-specific handles are removed.</p>
+
+ <p>See <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ for an overview of how group state changes are used to indicate the
+ progress of a call.</p>
+ </tp:docstring>
+ </signal>
+
+ <tp:mapping name="Handle_Identifier_Map">
+ <tp:docstring>
+ A map from handles to the corresponding normalized string identifier.
+ </tp:docstring>
+ <tp:added version="0.17.17"/>
+
+ <tp:member type="u" name="Handle" tp:type="Contact_Handle">
+ <tp:docstring>
+ A nonzero handle
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Identifier">
+ <tp:docstring>
+ The same string that would be returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>
+ for this handle.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <signal name="MembersChangedDetailed"
+ tp:name-for-bindings="Members_Changed_Detailed">
+ <arg name="Added" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members added to the channel
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members removed from the channel
+ </tp:docstring>
+ </arg>
+ <arg name="Local_Pending" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members who are pending local approval
+ </tp:docstring>
+ </arg>
+ <arg name="Remote_Pending" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members who are pending remote approval
+ </tp:docstring>
+ </arg>
+ <arg name="Details" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Information about the change, which may include the following
+ well-known keys:</p>
+
+ <dl>
+ <dt>actor (u — <tp:type>Contact_Handle</tp:type>)</dt>
+ <dd>The contact handle of the person who made the change; 0 or
+ omitted if unknown or not applicable.</dd>
+
+ <dt>change-reason (u — <tp:type>Channel_Group_Change_Reason</tp:type>)</dt>
+ <dd>A reason for the change.</dd>
+
+ <dt>contact-ids (a{us} — <tp:type>Handle_Identifier_Map</tp:type>)</dt>
+ <dd>
+ <p>The string identifiers for handles mentioned in this signal, to
+ give clients the minimal information necessary to react to the
+ event without waiting for round-trips. Connection managers
+ SHOULD include the identifiers for members added to the group and
+ for the actor (if any); they MAY omit the identifiers for handles
+ which have been removed from the group.</p>
+
+ <tp:rationale>
+ <p>On IRC, an event such as a netsplit could cause the vast
+ majority of a channel to leave. Given that clients should
+ already know the identifiers of a channel's members, including
+ potentially hundreds of strings in the netsplit signal is
+ unnecessary.</p>
+ </tp:rationale>
+
+ <p>Clients MUST NOT assume that the presence or absence of a
+ handle in this mapping is meaningful. This mapping is merely
+ an optimization for round-trip reduction, and connection
+ managers MAY add additional handles, omit some handles, or
+ omit the mapping completely.</p>
+ </dd>
+
+ <dt>message (s)</dt>
+ <dd>A string message from the server regarding the change</dd>
+
+ <dt>error (s — <tp:type>DBus_Error_Name</tp:type>)</dt>
+ <dd>A (possibly implementation-specific) DBus error describing the
+ change, providing more specific information than the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum allows. This
+ MUST only be present if it is strictly more informative than
+ 'change-reason'; if present, 'change-reason' MUST be set to the
+ closest available reason.
+
+ <tp:rationale>
+ A SIP connection manager might want to signal "402 Payment
+ required" as something more specific than Error or
+ Permission_Denied so that a SIP-aware UI could handle it
+ specially; including a namespaced error permits this to be done
+ without <tp:type>Channel_Group_Change_Reason</tp:type> being
+ extended to encompass every error any CM ever wants to report.
+ </tp:rationale>
+ </dd>
+
+ <dt>debug-message (s)</dt>
+ <dd>Debugging information on the change. SHOULD NOT be shown to
+ users in normal circumstances.</dd>
+ </dl>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when contacts join any of the three lists (members, local
+ pending or remote pending) or when they leave any of the three
+ lists. This signal provides a superset of the information provided by
+ <tp:member-ref>MembersChanged</tp:member-ref>;
+ if the channel's <tp:member-ref>GroupFlags</tp:member-ref>
+ contains Members_Changed_Detailed, then clients may listen exclusively
+ to this signal in preference to that signal.</p>
+
+ <p>All channel-specific handles that are mentioned in this signal
+ MUST be represented in the value of the
+ <tp:member-ref>HandleOwners</tp:member-ref> property. In practice,
+ this will mean that
+ <tp:member-ref>HandleOwnersChanged</tp:member-ref> is emitted
+ <em>before</em> emitting a MembersChangedDetailed signal in which
+ channel-specific handles are added, but that it is emitted
+ <em>after</em> emitting a MembersChangedDetailed signal in which
+ channel-specific handles are removed.</p>
+
+ <p>See <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ for an overview of how group state changes are used to indicate the
+ progress of a call.</p>
+ </tp:docstring>
+ <tp:added version="0.17.16"/>
+ </signal>
+
+ <method name="RemoveMembers" tp:name-for-bindings="Remove_Members">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of contact handles to remove from the channel
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Message" type="s">
+ <tp:docstring>
+ A string message, which can be blank if desired
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Requests the removal of contacts from a channel, reject their
+ request for channel membership on the pending local list, or
+ rescind their invitation on the pending remote list.</p>
+
+ <p>If the <tp:member-ref>SelfHandle</tp:member-ref> is in a Group,
+ it can be removed via this method, in order to leave the group
+ gracefully. This is the recommended way to leave a chatroom, close
+ or reject a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ call, and so on.</p>
+
+ <p>Accordingly, connection managers SHOULD support
+ doing this, regardless of the value of
+ <tp:member-ref>GroupFlags</tp:member-ref>.
+ If doing so fails with PermissionDenied, this is considered to a bug
+ in the connection manager, but clients MUST recover by falling back
+ to closing the channel with the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ method.</p>
+
+ <p>Removing any contact from the local pending list is always
+ allowed. Removing contacts other than the
+ <tp:member-ref>SelfHandle</tp:member-ref> from the channel's members
+ is allowed if and only if Channel_Group_Flag_Can_Remove is in the
+ <tp:member-ref>GroupFlags</tp:member-ref>,
+ while removing contacts other than the
+ <tp:member-ref>SelfHandle</tp:member-ref> from the remote pending list
+ is allowed if and only if Channel_Group_Flag_Can_Rescind is in the
+ <tp:member-ref>GroupFlags</tp:member-ref>.</p>
+
+ <p>A message may be provided along with the request, which will be
+ sent to the server if supported. See the
+ Channel_Group_Flag_Message_Remove,
+ Channel_Group_Flag_Message_Depart,
+ Channel_Group_Flag_Message_Reject and
+ Channel_Group_Flag_Message_Rescind
+ <tp:member-ref>GroupFlags</tp:member-ref> to see in which cases this
+ message should be provided.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RemoveMembersWithReason"
+ tp:name-for-bindings="Remove_Members_With_Reason">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of contact handles to remove from the channel
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Message" type="s">
+ <tp:docstring>
+ A string message, which can be blank if desired
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Reason" type="u"
+ tp:type="Channel_Group_Change_Reason">
+ <tp:docstring>
+ A reason for the change
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ As <tp:member-ref>RemoveMembers</tp:member-ref>, but a reason code may
+ be provided where
+ appropriate. The reason code may be ignored if the underlying
+ protocol is unable to represent the given reason.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The provided reason code was invalid.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for channels which have multiple members, and where the members
+ of the channel can change during its lifetime. Your presence in the channel
+ cannot be presumed by the channel's existence (for example, a channel you
+ may request membership of but your request may not be granted).</p>
+
+ <p>This interface implements three lists: a list of current members
+ (<tp:member-ref>Members</tp:member-ref>), and two lists of local pending
+ and remote pending members
+ (<tp:member-ref>LocalPendingMembers</tp:member-ref> and
+ <tp:member-ref>RemotePendingMembers</tp:member-ref>, respectively).
+ Contacts on the remote
+ pending list have been invited to the channel, but the remote user has not
+ accepted the invitation. Contacts on the local pending list have requested
+ membership of the channel, but the local user of the framework must accept
+ their request before they may join. A single contact should never appear on
+ more than one of the three lists. The lists are empty when the channel is
+ created, and the <tp:member-ref>MembersChanged</tp:member-ref> signal
+ (and, if the channel's <tp:member-ref>GroupFlags</tp:member-ref> contains
+ Members_Changed_Detailed, the
+ <tp:member-ref>MembersChangedDetailed</tp:member-ref> signal)
+ should be emitted when information
+ is retrieved from the server, or changes occur.</p>
+
+ <p>If the <tp:member-ref>MembersChanged</tp:member-ref> or
+ <tp:member-ref>MembersChangedDetailed</tp:member-ref> signal indicates
+ that the <tp:member-ref>SelfHandle</tp:member-ref> has been removed from
+ the channel, and the channel subsequently emits <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Closed</tp:dbus-ref>,
+ clients SHOULD consider the details given in the MembersChanged or
+ MembersChangedDetailed signal to be the reason why the channel closed.</p>
+
+ <p>Addition of members to the channel may be requested by using
+ <tp:member-ref>AddMembers</tp:member-ref>. If
+ remote acknowledgement is required, use of the AddMembers method will cause
+ users to appear on the remote pending list. If no acknowledgement is
+ required, AddMembers will add contacts to the member list directly. If a
+ contact is awaiting authorisation on the local pending list, AddMembers
+ will grant their membership request.</p>
+
+ <p>Removal of contacts from the channel may be requested by using
+ <tp:member-ref>RemoveMembers</tp:member-ref>. If a contact is awaiting
+ authorisation on the local pending
+ list, RemoveMembers will refuse their membership request. If a contact is
+ on the remote pending list but has not yet accepted the invitation,
+ RemoveMembers will rescind the request if possible.</p>
+
+ <p>It should not be presumed that the requester of a channel implementing this
+ interface is immediately granted membership, or indeed that they are a
+ member at all, unless they appear in the list. They may, for instance,
+ be placed into the remote pending list until a connection has been
+ established or the request acknowledged remotely.</p>
+
+ <p>If the local user joins a Group channel whose members or other state
+ cannot be discovered until the user joins (e.g. many chat room
+ implementations), the connection manager should ensure that the channel
+ is, as far as possible, in a consistent state before adding the local
+ contact to the members set; until this happens, the local contact should
+ be in the remote-pending set. For instance, if the connection manager
+ queries the server to find out the initial members list for the
+ channel, it should leave the local contact in the remote-pending set
+ until it has finished receiving the initial members list.
+ </p>
+
+ <p>If the protocol provides no reliable way to tell whether the complete
+ initial members list has been received yet, the connection manager
+ should make a best-effort attempt to wait for the full list
+ (in the worst case, waiting for a suitable arbitrary timeout)
+ rather than requiring user interfaces to do so on its behalf.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_HTML.xml b/spec/spec/Channel_Interface_HTML.xml
new file mode 100644
index 000000000..ad86867ca
--- /dev/null
+++ b/spec/spec/Channel_Interface_HTML.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_HTML"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.HTML.DRAFT"
+ tp:causes-havoc="unfinished">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
+ <tp:requires
+ interface="org.freedesktop.Telepathy.Channel.Interface.Messages"/>
+ <tp:added version="0.17.5">(draft version, not API-stable)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface extends the Messages interface to support
+ capability discovery, so clients can decide what subset of HTML
+ is supported.</p>
+
+ <p>(However, the capability discovery mechanism has not been written
+ yet, so this interface MUST NOT be used. It exists only to
+ indicate what direction we intend to go in.)</p>
+
+ <tp:rationale>
+ <p>XMPP supports all of XHTML-IM, and SIP (at least theoretically)
+ supports all of XHTML. However, many protocols are more limited -
+ for instance, in MSN you can only set font properties for a
+ whole message at a time. We should not mislead users into thinking
+ they can send MSN messages where individual words are emphasized.</p>
+ </tp:rationale>
+
+ <p>If this interface is present, clients MAY send XHTML formatted text
+ in message parts with type "text/html", and SHOULD interpret
+ "text/html" message parts received in reply.</p>
+
+ <p>Client authors SHOULD pay careful attention to the security
+ considerations in XEP-0071, "XHTML-IM", to avoid exposing client users
+ to security risks. Clients MUST NOT assume that connection managers
+ will filter messages to remove unsafe HTML.</p>
+
+ <tp:rationale>
+ <p>Connection managers are the components in Telepathy that are most
+ likely to be exploitable by a remote attacker to run malicious code
+ (since they are network-facing), so any filtering that the CM does
+ might be subverted.</p>
+ </tp:rationale>
+
+ <p>To avoid misleading users, clients SHOULD only present UI for the
+ subset of HTML that is indicated to be supported by this
+ interface. It follows that clients SHOULD NOT send unsupported
+ markup to the connection manager. However, even if the connection
+ manager cannot send arbitrary XHTML, it MUST cope gracefully
+ with being given arbitrary XHTML by a client.</p>
+
+ <tp:rationale>
+ <p>Connection managers should be lenient in what they receive.</p>
+ </tp:rationale>
+
+ <p>Clients MUST NOT send HTML that is not well-formed XML, but
+ connection managers MAY signal HTML that is malformed or invalid.
+ Clients SHOULD attempt to parse messages as XHTML, but fall back
+ to using a permissive "tag-soup" HTML parser if that fails.
+ (FIXME: or should the presence of this interface imply that the
+ CM fixes up "text/html" to be XHTML? In practice that would result
+ in all the CMs having to link against libxml2 or something... the
+ rationale above no longer applies here, since dropping a malformed
+ message is "safe")</p>
+ </tp:docstring>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Hold.xml b/spec/spec/Channel_Interface_Hold.xml
new file mode 100644
index 000000000..69d295d97
--- /dev/null
+++ b/spec/spec/Channel_Interface_Hold.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Hold" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005-2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005-2008 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Hold">
+ <tp:xor-requires>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Call1"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Call1.Content"/>
+ </tp:xor-requires>
+ <tp:changed version="0.17.4">first API-stable version</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for channels where you may put the channel on hold.
+ This only makes sense for channels where
+ you are streaming media to or from the members. (To see whether the
+ other participant has put you on hold, see <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >CallState</tp:dbus-ref>.)</p>
+
+ <p>If you place a channel on hold, this indicates that you do not wish
+ to be sent media streams by any of its members and will be ignoring
+ any media streams you continue to receive. It also requests that the
+ connection manager free up any resources that are only needed for
+ an actively used channel (e.g. in a GSM or PBX call, it will be
+ necessary to place an active call on hold before you can start
+ another call).</p>
+
+ <p>This can also be used for putting a single Content on hold, if the
+ protocol supports it (This interface is in the Channel namespace for
+ historical reasons).</p>
+ </tp:docstring>
+
+ <method name="GetHoldState" tp:name-for-bindings="Get_Hold_State">
+ <tp:docstring>
+ Return whether the local user has placed the channel on hold.
+ </tp:docstring>
+
+ <arg name="HoldState" direction="out" type="u"
+ tp:type="Local_Hold_State">
+ <tp:docstring>
+ The state of the channel
+ </tp:docstring>
+ </arg>
+
+ <arg name="Reason" direction="out" type="u"
+ tp:type="Local_Hold_State_Reason">
+ <tp:docstring>
+ The reason why the channel is in that state
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="HoldStateChanged" tp:name-for-bindings="Hold_State_Changed">
+ <tp:docstring>
+ Emitted to indicate that the hold state has changed for this channel.
+ This may occur as a consequence of you requesting a change with
+ <tp:member-ref>RequestHold</tp:member-ref>, or the state changing as a
+ result of a request from
+ another process.
+ </tp:docstring>
+
+ <arg name="HoldState" type="u" tp:type="Local_Hold_State">
+ <tp:docstring>
+ The state of the channel
+ </tp:docstring>
+ </arg>
+
+ <arg name="Reason" type="u" tp:type="Local_Hold_State_Reason">
+ <tp:docstring>
+ The reason for the state change
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="Local_Hold_State" type="u">
+ <tp:docstring>
+ The hold state of a channel.
+ </tp:docstring>
+
+ <tp:enumvalue value="0" suffix="Unheld">
+ <tp:docstring>
+ All streams are unheld (the call is active). New channels SHOULD
+ have this hold state.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="1" suffix="Held">
+ <tp:docstring>
+ All streams are held (the call is on hold)
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="2" suffix="Pending_Hold">
+ <tp:docstring>
+ The connection manager is attempting to move to state Held, but
+ has not yet completed that operation. It is unspecified whether
+ any, all or none of the streams making up the channel are on hold.
+ Examining the Hold state of Call Contents (if applicable) may
+ provide more useful information.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="3" suffix="Pending_Unhold">
+ <tp:docstring>
+ The connection manager is attempting to move to state Unheld, but
+ has not yet completed that operation. It is unspecified whether
+ any, all or none of the streams making up the channel are on hold.
+ Examining the Hold state of Call Contents (if applicable) may
+ provide more useful information.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Local_Hold_State_Reason" type="u">
+ <tp:docstring>
+ The reason for a change to the Local_Hold_State. Clients MUST
+ treat unknown values as equivalent to Local_Hold_State_Reason_None.
+ </tp:docstring>
+
+ <tp:enumvalue value="0" suffix="None">
+ <tp:docstring>
+ The reason cannot be described by any of the predefined values
+ (connection managers SHOULD avoid this reason, but clients MUST
+ handle it gracefully)
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="1" suffix="Requested">
+ <tp:docstring>
+ The change is in response to a user request
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="2" suffix="Resource_Not_Available">
+ <tp:docstring>
+ The change is because some resource was not available
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <method name="RequestHold" tp:name-for-bindings="Request_Hold">
+ <arg direction="in" name="Hold" type="b">
+ <tp:docstring>
+ A boolean indicating whether or not the channel should be on hold
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the channel be put on hold (be instructed not to send
+ any media streams to you) or be taken off hold.</p>
+
+ <p>If the connection manager can immediately tell that the requested
+ state change could not possibly succeed, this method SHOULD
+ return the NotAvailable error. If the requested state is the
+ same as the current state, this method SHOULD return successfully
+ without doing anything.</p>
+
+ <p>Otherwise, this method SHOULD immediately set the hold state to
+ Local_Hold_State_Pending_Hold or Local_Hold_State_Pending_Unhold
+ (as appropriate), emitting
+ <tp:member-ref>HoldStateChanged</tp:member-ref> if this is a change,
+ and return successfully.</p>
+
+ <p>The eventual success or failure of the request is indicated by a
+ subsequent HoldStateChanged signal, changing the hold state to
+ Local_Hold_State_Held or Local_Hold_State_Unheld.</p>
+
+ <p>If the channel has multiple streams, and the connection manager
+ succeeds in changing the hold state of one stream but fails to
+ change the hold state of another, it SHOULD attempt to revert
+ all streams to their previous hold states.</p>
+
+ <p>The following state transitions SHOULD be used, where
+ appropriate:</p>
+
+ <ul>
+ <li>Successful hold:
+ (Unheld, any reason) → (Pending_Hold, Requested) →
+ (Held, Requested)
+ </li>
+ <li>Successful unhold:
+ (Held, any reason) → (Pending_Unhold, Requested) →
+ (Unheld, Requested)
+ </li>
+ <li>Attempting to unhold fails at the first attempt to acquire a
+ resource:
+ (Held, any reason) → (Pending_Unhold, Requested) →
+ (Held, Resource_Not_Available)
+ </li>
+ <li>Attempting to unhold acquires one resource, but fails to acquire
+ a second, and takes time to release the first:
+ (Held, any reason) → (Pending_Unhold, Requested) →
+ (Pending_Hold, Resource_Not_Available) →
+ (Held, Resource_Not_Available)
+ </li>
+ </ul>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The requested hold state cannot be achieved; for example,
+ if only a limited number of channels can be in the "not on hold"
+ state, attempts to exceed this number will raise NotAvailable.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Media_Signalling.xml b/spec/spec/Channel_Interface_Media_Signalling.xml
new file mode 100644
index 000000000..58a222c19
--- /dev/null
+++ b/spec/spec/Channel_Interface_Media_Signalling.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Media_Signalling" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2009 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.MediaSignalling">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"/>
+ <tp:changed version="0.24.0">The old-style Telepathy properties,
+ deprecated since March 2009, have been removed.</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for signalling a channel containing synchronised media
+ sessions which can contain an arbitrary number of streams. The
+ presence of this interface on a Channel indicates that the connection
+ manager will not carry out the actual streaming for this channel,
+ and that the client handling the channel is responsible for doing
+ so; in most cases we recommend doing this by using the
+ telepathy-farsight library.</p>
+
+ <tp:rationale>
+ <p>Streaming audio and (particularly) video requires a high level of
+ integration with the UI, and having the connection manager act as
+ a proxy would be likely to introduce unacceptable latency. As a
+ result, audio/video streaming is offloaded into the client
+ where possible, as an exception to the general design of
+ Telepathy.</p>
+ </tp:rationale>
+
+ <p>The negotiation interface is based on the API of the
+ <a href="http://farsight.freedesktop.org/">Farsight</a> library.
+ This, in turn, is based upon the IETF MMusic ICE drafts, where
+ connections are established by signalling potential connection
+ candidates to the peer until a usable connection is found, and
+ codecs are negotiated with an SDP-style offer and answer. However,
+ the principles should be applicable to other media streaming methods
+ and the API re-used without difficulty.</p>
+
+ <p>Note that the naming conventions used in the MediaStreamHandler
+ and MediaSessionHandler interfaces are rather confusing; methods
+ have signal-like names and signals have method-like names, due to
+ the API being based rather too closely on that of Farsight. This
+ is for historical reasons and will be fixed in a future release
+ of the Telepathy specification.</p>
+ </tp:docstring>
+
+ <tp:simple-type name="Media_Session_Type" type="s">
+ <tp:docstring>The type of a media session. Currently, the only supported
+ value is "rtp".</tp:docstring>
+ </tp:simple-type>
+
+ <tp:struct name="Media_Session_Handler_Info"
+ array-name="Media_Session_Handler_Info_List">
+ <tp:docstring>A struct representing a active session handler.</tp:docstring>
+ <tp:member type="o" name="Session_Handler">
+ <tp:docstring>The object path of the session handler, which is on the
+ same bus name as the channel.</tp:docstring>
+ </tp:member>
+ <tp:member type="s" tp:type="Media_Session_Type" name="Media_Session_Type">
+ <tp:docstring>The media session's type</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="GetSessionHandlers"
+ tp:name-for-bindings="Get_Session_Handlers">
+ <arg direction="out" type="a(os)" tp:type="Media_Session_Handler_Info[]"
+ name="Session_Handlers"/>
+ <tp:docstring>
+ Returns all currently active session handlers on this channel
+ as a list of (session_handler_path, type).
+ </tp:docstring>
+ </method>
+
+ <signal name="NewSessionHandler" tp:name-for-bindings="New_Session_Handler">
+ <arg name="Session_Handler" type="o">
+ <tp:docstring>
+ Object path of the new <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Media.SessionHandler</tp:dbus-ref>
+ object
+ </tp:docstring>
+ </arg>
+ <arg name="Session_Type" tp:type="Media_Session_Type" type="s">
+ <tp:docstring>
+ String indicating type of session, eg &quot;rtp&quot;
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal that a session handler object has been created. The client
+ should create a session object and create streams for the streams
+ within.
+ </tp:docstring>
+ </signal>
+
+ <tp:hct name="gtalk-p2p">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media.StreamHandler">NATTraversal</tp:dbus-ref>
+ property is <code>gtalk-p2p</code>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="ice-udp">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media.StreamHandler">NATTraversal</tp:dbus-ref>
+ property is <code>ice-udp</code>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="wlm-8.5">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media.StreamHandler">NATTraversal</tp:dbus-ref>
+ property is <code>wlm-8.5</code>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="wlm-2009">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media.StreamHandler">NATTraversal</tp:dbus-ref>
+ property is <code>wlm-2009</code>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="video/h264" is-family="yes">
+ <tp:docstring>
+ <p>The client supports media streaming with H264 (etc.).</p>
+
+ <p>This handler capability token is a one of a family
+ of similar tokens: for any other audio or video codec whose MIME
+ type is audio/<em>subtype</em> or video/<em>subtype</em>, a handler
+ capability token of this form may exist (the subtype MUST appear
+ in lower case in this context). Clients MAY support more
+ codecs than they explicitly advertise support for; clients SHOULD
+ explicitly advertise support for their preferred codec(s), and
+ for codecs like H264 that are, in practice, significant in codec
+ negotiation.</p>
+
+ <tp:rationale>
+ <p>For instance, the XMPP capability used by the Google Video
+ Chat web client to determine whether a client is compatible
+ with it requires support for H264 video, so an XMPP
+ connection manager that supports this version of Jingle should
+ not advertise the Google Video Chat capability unless there
+ is at least one installed client that declares that it supports
+ <code>video/h264</code> on StreamedMedia channels.</p>
+ </tp:rationale>
+
+ <p>For example, a client could advertise support for
+ Speex, Theora and H264 by having three
+ handler capability tokens,
+ <code>org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/audio/speex</code>,
+ <code>org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/theora</code> and
+ <code>org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/h264</code>,
+ in its <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">Capabilities</tp:dbus-ref>
+ property.</p>
+
+ <p>Clients MAY have media signalling abilities without explicitly
+ supporting any particular codec, and connection managers SHOULD
+ support this usage.</p>
+
+ <tp:rationale>
+ <p>This is necessary to support gatewaying between two Telepathy
+ connections, in which case the available codecs might not be
+ known to the gatewaying process.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:hct>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Mergeable_Conference.xml b/spec/spec/Channel_Interface_Mergeable_Conference.xml
new file mode 100644
index 000000000..cd606c1b7
--- /dev/null
+++ b/spec/spec/Channel_Interface_Mergeable_Conference.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Mergeable_Conference"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.MergeableConference.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.Conference"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for multi-user conference channels that can have
+ additional individual channels merged into them after they are
+ created.</p>
+
+ <tp:rationale>
+ <p>This interface addresses part of freedesktop.org <a
+ href="http://bugs.freedesktop.org/show_bug.cgi?id=24906">bug
+ #24906</a> (GSM-compatible conference calls). GSM is currently
+ the only protocol known to implement this; PBXs might implement
+ it too.</p>
+
+ <p>It might be made into a mandatory-to-implement part of Conference,
+ or kept as a separate interface, when stabilized.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <method name="Merge"
+ tp:name-for-bindings="Merge">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the given channel be incorporated into this
+ channel.</p>
+
+ <p>The given channel SHOULD be added to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Conference.Channels</tp:dbus-ref> if and only if the
+ underlying protocol signals the merge in some way. It MUST NOT be
+ added to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Conference.InitialChannels</tp:dbus-ref> (to preserve
+ immutability).</p>
+
+ <tp:rationale>
+ <p>In GSM it is possible to merge additional calls into an ongoing
+ conference.</p>
+
+ <p>In XMPP this method could be implemented to merge a 1-1 Text
+ channel into a MUC Text channel by inviting the peer from the Text
+ channel into the MUC, or to merge a 1-1 Jingle call into a Muji
+ call by inviting the peer from the Jingle call into the Muji call.
+ (MUC and Muji channels are both implemented by XMPP MUCs, with
+ Handle_Type_Room.)</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Channel" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel with the same <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref>
+ as this one, but with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref> = CONTACT.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The given channel isn't suitable for merging into this one: for
+ instance, it might have the wrong channel type or handle type.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It will never be possible to merge channels into this particular
+ conference.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The given channel is theoretically suitable for merging into this
+ one, but that's not currently possible for some reason (for
+ instance, this SHOULD be raised if a limit on the number of
+ channels in a conference is exceeded).
+ <strong>[FIXME: PermissionDenied?]</strong>
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
diff --git a/spec/spec/Channel_Interface_Messages.xml b/spec/spec/Channel_Interface_Messages.xml
new file mode 100644
index 000000000..a88576dc8
--- /dev/null
+++ b/spec/spec/Channel_Interface_Messages.xml
@@ -0,0 +1,1484 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Messages"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008–2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008–2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.Messages">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
+ <tp:added version="0.17.16">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface extends the <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy.Channel.Type'>Text</tp:dbus-ref>
+ interface to support more general messages, including:</p>
+
+ <ul>
+ <li>messages with attachments (like MIME multipart/mixed)</li>
+ <li>groups of alternatives (like MIME multipart/alternative)</li>
+ <li>delivery reports (which replace <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text.SendError</tp:dbus-ref>),
+ addding support for protocols where the message content is not echoed
+ back to the sender on failure and for receiving positive
+ acknowledgements, as well as ensuring that incoming delivery reports
+ are not lost if no client is handling the channel yet;</li>
+ <li>any extra types of message we need in future</li>
+ </ul>
+
+ <p>Incoming messages, outgoing messages, and delivery reports are all
+ represented as lists of <tp:type>Message_Part</tp:type> structures,
+ with a format reminiscent of e-mail. Messages are sent by calling
+ <tp:member-ref>SendMessage</tp:member-ref>; outgoing messages are
+ announced to other clients which may be interested in the channel by
+ the <tp:member-ref>MessageSent</tp:member-ref> signal. Incoming
+ messages and delivery reports are signalled by
+ <tp:member-ref>MessageReceived</tp:member-ref>, and are stored in the
+ the <tp:member-ref>PendingMessages</tp:member-ref> property until
+ acknowledged by calling <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.
+ Only the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ for a channel should acknowledge messages; <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Observer</tp:dbus-ref>s
+ (such as loggers) and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref>s
+ for the channel may listen for incoming messages, and send messages of their own, but SHOULD NOT acknowledge messages.</p>
+
+ <tp:rationale>
+ <p>If observers were allowed to acknowledge messages, then messages
+ might have been acknowledged before the handler even got to see the
+ channel, and hence could not be shown to the user.</p>
+ </tp:rationale>
+
+ <p>If this interface is present, clients that support it SHOULD
+ listen for the <tp:member-ref>MessageSent</tp:member-ref> and
+ <tp:member-ref>MessageReceived</tp:member-ref> signals, and
+ ignore the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
+ signals on the Text interface (which are guaranteed to duplicate
+ signals from this interface).</p>
+
+ <p>Although this specification supports formatted (rich-text)
+ messages with unformatted alternatives, implementations SHOULD NOT
+ attempt to send formatted messages until the Telepathy specification
+ has also been extended to cover capability discovery for message
+ formatting.</p>
+
+ <tp:rationale>
+ We intend to expose all rich-text messages as XHTML-IM, but on some
+ protocols, formatting is an extremely limited subset of that format
+ (e.g. there are protocols where foreground/background colours, font
+ and size can be set, but only for entire messages).
+ Until we can tell UIs what controls to offer to the user, it's
+ unfriendly to offer the user controls that may have no effect.
+ </tp:rationale>
+ </tp:docstring>
+
+ <property name="SupportedContentTypes" type="as" access="read"
+ tp:name-for-bindings="Supported_Content_Types"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of MIME types supported by this channel, with more preferred
+ MIME types appearing earlier in the list. The list MAY include "*/*"
+ to indicate that attachments with arbitrary MIME types can be sent.
+ This list MUST NOT be empty, since all Messages implementations
+ MUST accept messages containing a single "text/plain" part.</p>
+
+ <p>Items in this list MUST be normalized to lower-case.</p>
+
+ <p>Some examples of how this property interacts with the
+ <tp:member-ref>MessagePartSupportFlags</tp:member-ref>:</p>
+
+ <dl>
+ <dt>A simple IM implementation: only plain text messages are
+ allowed</dt>
+ <dd>SupportedContentTypes = ['text/plain'],
+ MessagePartSupportFlags = 0</dd>
+
+ <dt>Formatted text with a plain text alternative is allowed (see the
+ HTML interface draft)</dt>
+ <dd>SupportedContentTypes = ['text/html', 'text/plain'],
+ MessagePartSupportFlags = 0</dd>
+
+ <dt>JPEG or PNG images may be sent, but without any attached
+ text</dt>
+ <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
+ 'image/png'], MessagePartSupportFlags = 0</dd>
+
+ <dt>Unformatted text to which an optional JPEG or PNG image may be
+ attached</dt>
+ <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
+ 'image/png'], MessagePartSupportFlags = One_Attachment</dd>
+
+ <dt>Formatted text to which arbitrarily many images may be
+ attached</dt>
+ <dd>SupportedContentTypes = ['text/html', 'text/plain', 'image/jpeg',
+ 'image/png', 'image/x-ms-bmp'], MessagePartSupportFlags =
+ One_Attachment | Multiple_Attachments</dd>
+
+ <dt>A full SIP implementation: arbitrary MIME messages are
+ allowed</dt>
+ <dd>SupportedContentTypes = ['*/*'], MessagePartSupportFlags =
+ One_Attachment | Multiple_Attachments</dd>
+ </dl>
+ </tp:docstring>
+ </property>
+
+ <property name="MessageTypes" type="au"
+ tp:type="Channel_Text_Message_Type[]" access="read"
+ tp:name-for-bindings="Message_Types"
+ tp:immutable="yes">
+ <tp:added version="0.21.5">
+ This supersedes <tp:dbus-ref namespace="ofdT.Channel.Type.Text"
+ >GetMessageTypes</tp:dbus-ref>; fall back to that method for
+ compatibility with older connection managers.
+ </tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of message types which may be sent on this channel.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="MessagePartSupportFlags" type="u"
+ tp:type="Message_Part_Support_Flags" access="read"
+ tp:name-for-bindings="Message_Part_Support_Flags"
+ tp:immutable="yes">
+ <tp:docstring>
+ Flags indicating the level of support for message parts on this
+ channel.
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Message_Part_Support_Flags"
+ value-prefix="Message_Part_Support_Flag" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Flags indicating the level of support for message parts on this
+ channel. They are designed such that setting more flags always
+ implies that the channel has more capabilities.</p>
+
+ <p>If no flags are set, this indicates that messages may contain
+ a single message part whose content-type is any of the types
+ from SupportedContentTypes, possibly with some alternatives.</p>
+
+ <p>There is no flag indicating support for alternatives. This is
+ because the SendMessage implementation can always accept messages
+ containing alternatives, even if the underlying protocol does not,
+ by deleting all alternatives except the first (most preferred)
+ that is supported.</p>
+
+ <tp:rationale>
+ Each of the flags so far implies the previous flag, so we could
+ have used a simple enumeration here; however, we've defined
+ the message-part support indicator as a flag set for future
+ expansion.
+ </tp:rationale>
+
+ <p>See <tp:member-ref>SupportedContentTypes</tp:member-ref> for some
+ examples.</p>
+ </tp:docstring>
+
+ <tp:flag suffix="One_Attachment" value="1">
+ <tp:docstring>
+ <tp:member-ref>SendMessage</tp:member-ref> will accept messages
+ containing a textual message body,
+ plus a single attachment of any type listed in the
+ SupportedContentTypes property. It does not make sense for this
+ flag to be set if Message_Part_Support_Flag_Data_Only is not also set
+ (because the connection manager can trivially provide an empty text
+ part if necessary).
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Multiple_Attachments" value="2">
+ <tp:docstring>
+ SendMessage will accept messages containing a textual message body,
+ plus an arbitrary number of attachments of any type listed in the
+ SupportedContentTypes property. It does not make sense for this
+ flag to be set if Message_Part_Support_Flag_One_Attachment is not
+ also set.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:mapping name="Message_Part" array-name="Message_Part_List"
+ array-depth="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Part of a message's content. In practice, this mapping never
+ appears in isolation: incoming messages are represented by a list of
+ <tp:type>Message_Part</tp:type> mappings in the
+ <tp:member-ref>MessageReceived</tp:member-ref> signal, and outgoing
+ messages are passed to <tp:member-ref>SendMessage</tp:member-ref> as
+ a list of these mappings.</p>
+
+ <p>The first part of the message contains "headers", which refer
+ to the entire message. The second and subsequent parts contain the
+ message's content, including plain text, formatted text and/or
+ attached files. Well-known keys for the header and body parts are
+ defined by the <tp:type>Message_Header_Key</tp:type> and
+ <tp:type>Message_Body_Key</tp:type> types, respectively. It is an
+ error for a connection manager to put keys referring to the message
+ as a whole in the second or subsequent Message_Part, or keys intended
+ for body parts in the first Message_Part; clients MUST recover from
+ this error by ignoring these mis-placed keys.</p>
+
+ <tp:rationale>
+ <p>Instead of representing messages as aa{sv} where the first
+ dictionary is special (a dictionary of headers), we could have
+ used a signature like (a{sv}aa{sv}) to separate out the headers
+ and the body parts.</p>
+
+ <p>However, this would make access to the messages more awkward.
+ In Python, the syntax for access to a header field would remain
+ <code>message[0]['message-type']</code>, but access to a body
+ field in the second body part would change from
+ <code>message[2]['content'] to message[1][1]['content']</code>. In
+ GLib, the message would change from being a
+ <code>GPtrArray(GHashTable)</code> to being a
+ <code>GValueArray(GHashTable, GPtrArray(GHashTable))</code> which
+ is rather inconvenient to dereference.</p>
+ </tp:rationale>
+
+ <p>In any group of parts with the same non-empty value for the
+ <tt>alternative</tt> key (which represent alternative versions of the
+ same content), more faithful versions of the intended message MUST
+ come before less faithful versions (note that this order is the
+ opposite of MIME <tt>multipart/alternative</tt> parts). Clients
+ SHOULD display the first alternative that they understand.</p>
+
+ <tp:rationale>
+ <p>Specifying the preference order means that if the underlying
+ protocol doesn't support alternatives, the CM can safely delete
+ everything apart from the first supported alternative when
+ sending messages.</p>
+
+ <p>The order is the reverse of MIME because MIME's rationale for
+ placing the "plainest" part first (legibility in pre-MIME UAs)
+ does not apply to us, and placing the most preferred part
+ first simplifies display (a client can iterate the message
+ in order, display the first alternative that it understands,
+ and skip displaying all subsequent parts with the same
+ "alternative" key).</p>
+ </tp:rationale>
+
+ <p>Clients SHOULD present all parts that are not redundant
+ alternatives in the order they appear in this array, possibly
+ excluding parts that are referenced by another displayed part.
+ It is implementation-specific how the parts are presented to the
+ user.</p>
+
+ <tp:rationale>
+ <p>This allows CMs to assume that all parts are actually shown to
+ the user, even if they are not explicitly referenced - we do
+ not yet recommend formatted text, and there is no way for
+ plain text to reference an attachment since it has no concept of
+ markup or references. This also forces clients to do something
+ sensible with messages that consist entirely of "attachments",
+ with no "body" at all.</p>
+
+ <p>For instance, when displaying the above example, a client that
+ understands the HTML part should display the JPEG image once,
+ between the two lines "Here is a photo of my cat:" and
+ "Isn't it cute?"; it may additionally present the image in some
+ way for a second time, after "Isn't it cute?", or may choose
+ not to.</p>
+
+ <p>A client that does not understand HTML, displaying the same
+ message, should display the plain-text part, followed by the JPEG
+ image.</p>
+ </tp:rationale>
+
+ <p>Connection managers, clients and extensions to this specification
+ SHOULD NOT include <tp:type>Handle</tp:type>s as values in a
+ Message_Part, except for <code>message-sender</code> in the
+ header.</p>
+
+ <tp:rationale>
+ <p>Reference-counting handles in clients becomes problematic if
+ the channel proxy cannot know whether particular map values
+ are handles or not.</p>
+ </tp:rationale>
+
+ <h4>Example messages</h4>
+
+ <p>A rich-text message, with an embedded image, might be represented
+ as:</p>
+
+ <pre>
+[
+ {
+ 'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
+ 'message-sender': 42,
+ 'message-sent': 1210067943,
+ 'message-received': 1210067947,
+ 'message-type': 0, # = Channel_Text_Message_Type_Normal
+ 'pending-message-id': 437,
+ },
+ { 'alternative': 'main',
+ 'content-type': 'text/html',
+ 'content': 'Here is a photo of my cat:&lt;br /&gt;' +
+ '&lt;img src="cid:catphoto" alt="lol!" /&gt;' +
+ '&lt;br /&gt;Isn't it cute?',
+ },
+ { 'alternative': 'main',
+ 'content-type': 'text/plain',
+ 'content': 'Here is a photo of my cat:\n[IMG: lol!]\nIsn't it cute?',
+ },
+ { 'identifier': 'catphoto',
+ 'content-type': 'image/jpeg',
+ 'size': 101000,
+ 'needs-retrieval': True,
+ },
+]</pre>
+
+ <p>telepathy-ring, Nokia's GSM connection manager, represents vCards
+ sent via SMS as:</p>
+
+ <pre>
+[
+ {
+ 'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
+ 'message-sender': 42,
+ 'message-sent': 1210067943,
+ 'message-received': 1210067947,
+ 'message-type': 0, # = Channel_Text_Message_Type_Normal
+ 'pending-message-id': 437,
+ },
+ { 'content-type': 'text/x-vcard',
+ 'content': [ 0x66, 0x69, 0x71, ...], # vCard data as an array of bytes
+ },
+]</pre>
+
+ <h3>Delivery reports</h3>
+
+ <div>
+ <p>Delivery reports are also represented as messages with the
+ <tt>message-type</tt> header mapping to
+ <tp:type>Channel_Text_Message_Type</tp:type> Delivery_Report.
+ Delivery reports SHOULD contain the <tt>message-sender</tt> header,
+ mapping to the intended recipient of the original message, if
+ possible; other headers specific to delivery reports are defined by
+ the <tp:type>Delivery_Report_Header_Key</tp:type> type. The second
+ and subsequent parts, if present, are a human-readable report from
+ the IM service.</p>
+
+ <p>For backwards- and forwards-compatibility, whenever a delivery
+ error report is signalled—that is, with <tt>delivery-status</tt>
+ mapping to <tp:type>Delivery_Status</tp:type> Temporarily_Failed or
+ Permanently_Failed—<tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
+ SHOULD also be emitted; whenever <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
+ is emitted, a delivery report MUST also be signalled.
+ Delivery report messages on this interface MUST be represented in
+ emissions of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
+ as messages with the Non_Text_Content
+ <tp:type>Channel_Text_Message_Flags</tp:type>; clients which
+ understand this interface SHOULD ignore the SendError signal in
+ favour of listening for delivery reports, as mentioned in the
+ introduction.</p>
+
+ <p>The result of attempting to send delivery reports using
+ <tp:member-ref>SendMessage</tp:member-ref> is currently
+ undefined.</p>
+
+ <h4>Example delivery reports</h4>
+
+ <dl>
+ <dt>A minimal delivery report indicating permanent failure of the
+ sent message whose token was
+ <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> for an unknown
+ reason</dt>
+ <dd><pre>
+[{
+# header
+'message-sender': 123,
+'message-type': Channel_Text_Message_Type_Delivery_Report,
+'delivery-status': Delivery_Status_Permanently_Failed,
+'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
+}
+# no body
+]</pre></dd>
+
+ <dt>A delivery report where the failed message is echoed back to the
+ sender rather than being referenced by ID, and the failure reason
+ is that this protocol cannot send messages to offline contacts
+ such as the contact with handle 123</dt>
+ <dd><pre>
+[{ # header
+'message-sender': 123,
+'message-type': Channel_Text_Message_Type_Delivery_Report,
+'delivery-status': Delivery_Status_Temporarily_Failed,
+'delivery-error': Channel_Text_Send_Error_Offline,
+'delivery-echo':
+ [{ # header of original message
+ 'message-sender': 1,
+ 'message-sent': 1210067943,
+ },
+ { # body of original message
+ 'content-type': 'text/plain',
+ 'content': 'Hello, world!',
+ }]
+ ],
+
+# no body
+]</pre></dd>
+
+ <dt>A maximally complex delivery report: the server reports a
+ bilingual human-readable failure message because the user sent
+ a message "Hello, world!" with token
+ <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> to a contact
+ with handle 123, but that handle represents a contact who does not
+ actually exist</dt>
+ <dd><pre>
+[{ # header
+'message-sender': 123,
+'message-type': Channel_Text_Message_Type_Delivery_Report,
+'delivery-status': Delivery_Status_Permanently_Failed,
+'delivery-error': Channel_Text_Send_Error_Invalid_Contact,
+'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
+'delivery-echo':
+ [{ # header of original message
+ 'message-sender': 1,
+ 'message-sent': 1210067943,
+ },
+ { # body of original message
+ 'content-type': 'text/plain',
+ 'content': 'Hello, world!',
+ }]
+ ],
+},
+{ # message from server (alternative in English)
+'alternative': '404',
+'content-type': 'text/plain',
+'lang': 'en',
+'content': 'I have no contact with that name',
+},
+{ # message from server (alternative in German)
+'alternative': '404'.
+'content-type': 'text/plain',
+'lang': 'de',
+'content', 'Ich habe keinen Kontakt mit diesem Namen',
+}
+]</pre></dd>
+
+ <dt>A minimal delivery report indicating successful delivery
+ of the sent message whose token was
+ <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code></dt>
+ <dd><pre>
+[{
+# header
+'message-sender': 123,
+'message-type': Channel_Text_Message_Type_Delivery_Report,
+'delivery-status': Delivery_Status_Delivered,
+'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
+}
+# no body
+]</pre></dd>
+
+ </dl>
+
+ </div>
+ </tp:docstring>
+
+ <tp:member name="Key" type="s">
+ <tp:docstring>
+ A key, which SHOULD be one of the well-known keys specified by
+ <tp:type>Message_Header_Key</tp:type>,
+ <tp:type>Message_Body_Key</tp:type> or
+ <tp:type>Delivery_Report_Header_Key</tp:type> if possible.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Value" type="v">
+ <tp:docstring>
+ The value corresponding to the given key, which SHOULD be one of the
+ specified types for well-known keys.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:simple-type type="s" name="Message_Header_Key">
+ <tp:added version="0.19.8"/>
+ <tp:changed version="0.21.5">
+ Removed <tt>protocol-token</tt>—which had never been implemented—and
+ respecified <tt>message-token</tt> not to have unimplementable
+ uniqueness guarantees.
+ </tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
+ message, which contains metadata about the message as a whole, along
+ with the corresponding value types. Some keys make sense for both
+ incoming and outgoing messages, while others are only meaningful for
+ one or the other.</p>
+
+ <dl>
+ <dt>message-token (s -
+ <tp:type>Protocol_Message_Token</tp:type>)
+ </dt>
+ <dd>
+ <p>An opaque identifier for the message, as used by the
+ underlying protocol. For outgoing messages, this SHOULD be
+ globally unique; for incoming messages, this is <em>not</em>
+ guaranteed to uniquely identify a message, <em>even within the
+ scope of a single channel or contact</em>; the only guarantee
+ made is that two messages with different <tt>message-token</tt>
+ headers are different messages.</p>
+
+ <p>Clients wishing to determine whether a new message with the
+ <tt>scrollback</tt> header matches a previously-logged message
+ with the same <tt>message-token</tt> SHOULD compare the
+ message's sender, contents, <tt>message-sent</tt> or
+ <tt>message-received</tt> timestamp, etc. Note that, in XMPP,
+ the server only supplies a timestamp for scrollback messages,
+ not for messages received while you are in a room; thus,
+ non-scrollback messages will lack a <tt>message-sent</tt>
+ timestamp.</p>
+
+ <tp:rationale>
+ <p>In practice, most protocols do not provide globally-unique
+ identifiers for messages. Connection managers, being
+ stateless, do not have the necessary information — namely, IM
+ logs — to generate reliable unique tokens for messages.</p>
+
+ <p>For instance, some XMPP clients (including Gabble) stamp
+ messages they send with unique identifiers, but others number
+ outgoing messages in a conversation from 1 upwards.</p>
+ </tp:rationale>
+ </dd>
+
+ <dt>message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>The time the message was sent (if unavailable, the time
+ it arrived at a central server MAY be used). Omitted if no
+ reasonable approximation is available; SHOULD always be present
+ on outgoing messages.</dd>
+
+ <dt>message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>The time the message was received locally. SHOULD always
+ be present.</dd>
+
+ <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>)</dt>
+ <dd>The contact who sent the message. If 0 or omitted, the contact
+ who sent the message could not be determined.</dd>
+
+ <dt>message-sender-id (s)</dt>
+ <dd>The identifier of the contact who sent the message,
+ i.e. the result of calling <tp:dbus-ref
+ namespace="ofdT.Connection">InspectHandles</tp:dbus-ref>
+ on <code>message-sender</code>. If omitted, clients MUST
+ fall back to looking at <code>message-sender</code>.</dd>
+
+ <dt>sender-nickname (s)</dt>
+ <dd>The nickname chosen by the sender of the message, which can be
+ different for each message in a conversation.</dd>
+
+ <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>)
+ </dt>
+ <dd>The type of message; if omitted,
+ Channel_Text_Message_Type_Normal MUST be assumed. MAY
+ be omitted for normal chat messages.</dd>
+
+ <dt>supersedes (s – <tp:type>Protocol_Message_Token</tp:type>)</dt>
+ <dd>If present, this message supersedes a previous message,
+ identified by its <tt>message-token</tt> header. The user
+ interface MAY, for example, choose to replace the superseded
+ message with this message, or grey out the superseded message.
+
+ <tp:rationale>Skype, for example, allows the user to amend
+ messages they have already sent (to correct typos,
+ etc.).</tp:rationale>
+
+ Connection Managers SHOULD represent repeatedly edited messages
+ in the following form:
+ <pre>
+ message {token = a};
+ message {token = b, supersedes = a};
+ message {token = c, supersedes = a};
+ </pre>
+
+ <tp:rationale>The alternative form is:
+ <pre>
+ message {token = a};
+ message {token = b, supersedes = a};
+ message {token = c, supersedes = b};
+ </pre>
+ but it is more difficult to implement in UIs/loggers, and it
+ breaks irrecoverably if message b is lost. If a CM is forced
+ to use this form, it should be tested extensively for
+ interoperability with existing clients.
+ </tp:rationale>
+
+ Clients should deal gracefully if the original message gets
+ lost, but one or more corrections to it get through:
+ <pre>
+ message {token = x} gets lost;
+ message {token = y, supersedes = x};
+ message {token = z, supersedes = x};
+ </pre>
+
+ <tp:rationale>This is the form that CMs will use to mean "I know
+ that this message was edited, but I don't know what it
+ originally said." It is often in the interests of the
+ remote side for message x to be lost (e.g. to hide
+ embarassing mistakes or sensitive information) so it might not
+ be possible to retrieve it (even on protocols with reliable
+ message-delivery guarantees).</tp:rationale></dd>
+
+ <dt>original-message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>The <tt>message-sent</tt> header of the message that this
+ one supersedes.
+ This key should only be present if <tt>supersedes</tt> is also
+ present. It MAY be used as a hint to help clients locate the
+ original message in its logs. If present, comparing the tuple
+ (original-message-sent, supersedes) with (message-sent,
+ message-token) SHOULD be enough to uniquely
+ identify the original message.</dd>
+
+ <dt>original-message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>The <tt>message-received</tt> header of the message that this
+ one supersedes.
+ This key should only be present if <tt>supersedes</tt> is also
+ present. It MAY be used as a hint in a similar way to
+ <tt>original-message-sent</tt>.</dd>
+
+ <dt>pending-message-id (u - <tp:type>Message_ID</tp:type>)</dt>
+ <dd>The incoming message ID. This MUST NOT be present on outgoing
+ messages. Clients SHOULD NOT store this key - it is only valid
+ for as long as the message remains unacknowledged.</dd>
+
+ <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
+ <dd>This message is specific to the given interface, which is
+ neither Text nor Messages. It SHOULD be ignored if that
+ interface is not supported. (Note that an 'interface' key
+ can also appear on the second and subsequent parts, where
+ it indicates that that part (only) should be ignored if
+ unsupported.)</dd>
+
+ <dt>scrollback (b)</dt>
+ <dd>If present and true, the incoming message was part of a
+ replay of message history (this matches the Scrollback flag in
+ <tp:type>Channel_Text_Message_Flags</tp:type>). This flag
+ does not make sense on outgoing messages and SHOULD NOT
+ appear there.</dd>
+
+ <dt>rescued (b)</dt>
+ <dd>If present and true, the incoming message has been seen in
+ a previous channel during the lifetime of the Connection,
+ but had not been acknowledged when that channel closed, causing
+ an identical channel (in which the message now appears) to open.
+ This matches the Rescued flag in
+ <tp:type>Channel_Text_Message_Flags</tp:type>; it
+ does not make sense on outgoing messages, and SHOULD NOT
+ appear there.</dd>
+ </dl>
+
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type type="s" name="Message_Body_Key">
+ <tp:added version="0.19.8"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Well-known keys for the second and subsequent
+ <tp:type>Message_Part</tp:type>s of a message, which contain the
+ message content, along with the corresponding value types.</p>
+
+ <dl>
+ <dt>identifier (s —
+ <tp:type>Protocol_Content_Identifier</tp:type>)</dt>
+ <dd>An opaque identifier for this part.
+ Parts of a message MAY reference other parts by treating
+ this identifier as if it were a MIME Content-ID and using
+ the cid: URI scheme.</dd>
+
+ <dt>alternative (s)</dt>
+ <dd>
+ <p>If present, this part of the message is an alternative for
+ all other parts with the same value for "alternative".
+ Clients SHOULD only display one of them (this is expected to
+ be used for XHTML messages in a future version of this
+ specification).</p>
+
+ <p>If omitted, this part is not an alternative for any other
+ part.</p>
+
+ <p>Parts of a message MAY reference the group of alternatives
+ as a whole (i.e. a reference to whichever of them is chosen)
+ by treating this identifier as if it were the MIME Content-ID
+ of a multipart/alternative part, and using the cid: URI
+ scheme.</p>
+ </dd>
+
+ <dt>content-type (s)</dt>
+ <dd>
+ <p>The MIME type of this part. See the documentation
+ for <tp:member-ref>MessageReceived</tp:member-ref> and
+ <tp:member-ref>MessageSent</tp:member-ref> for notes on the
+ special status of "text/plain" parts.</p>
+
+ <p>Connection managers MUST NOT signal parts without a
+ 'content-type' key; if a protocol provides no way to determine
+ the MIME type, the connection manager is responsible for
+ guessing it, but MAY fall back to "text/plain" for text and
+ "application/octet-stream" for non-text.</p>
+
+ <p>Clients MUST ignore parts without a 'content-type' key, which
+ are reserved for future expansion.</p>
+
+ <p>When sending messages, clients SHOULD normalize the
+ content-type to lower case, but connection managers SHOULD NOT
+ rely on this. When signalling sent or received messages,
+ connection managers MUST normalize the content-type to lower
+ case.</p>
+ </dd>
+
+ <dt>lang (s)</dt>
+ <dd>The natural language of this part, identified by a
+ RFC 3066 language tag.
+
+ <tp:rationale>
+ XMPP allows alternative-selection by language as well as
+ by content-type.
+ </tp:rationale>
+ </dd>
+
+ <dt>size (u)</dt>
+ <dd>The size in bytes (if needs-retrieval is true, this MAY be an
+ estimated or approximate size). SHOULD be omitted if 'content'
+ is provided.
+
+ <tp:rationale>
+ There's no point in providing the size if you're already
+ providing all the content.
+ </tp:rationale>
+ </dd>
+
+ <dt>thumbnail (b)</dt>
+ <dd>
+ <p>This part is a thumbnail. To represent an image together with
+ its thumbnail in a single message, there should be one part for
+ the full image followed by a part for the thumbnail (following
+ the “more complete versions first” requirement), with the same
+ 'alternative' value. For example:</p>
+
+ <pre>
+[ ... ,
+ { 'alternative': 'catphoto',
+ 'content-type': 'image/jpeg',
+ 'size': 150000,
+ 'content': [0xFF, 0xD8, ... 0xFF 0xD9],
+ },
+ { 'alternative': 'catphoto',
+ 'content-type': 'image/jpeg'
+ 'size': 1024,
+ 'thumbnail': True,
+ 'content': [0xFF, 0xD8, ... 0xFF 0xD9],
+ },
+ ...
+]</pre>
+ </dd>
+
+ <dt>needs-retrieval (b)</dt>
+ <dd>If false or omitted, the connection
+ manager already holds this part in memory. If present and true,
+ this part must be retrieved on demand (like MIME's
+ <tt>message/external-body</tt>) by a mechanism to be defined later.
+
+ <tp:rationale>The mechanism was meant to be
+ <tp:member-ref>GetPendingMessageContent</tp:member-ref>, but
+ that didn't work out. It's worth leaving the header in in
+ preparation for a future mechanism.
+ </tp:rationale>
+ </dd>
+
+ <dt>truncated (b)</dt>
+ <dd>The content available via the 'content' key has been truncated
+ by the server or connection manager (equivalent to
+ Channel_Text_Message_Flag_Truncated in the Text interface).
+ </dd>
+
+ <dt>content (s or ay)</dt>
+ <dd>The part's content, if it is available and
+ sufficiently small to include here (implies that
+ 'needs-retrieval' is false or omitted). Otherwise, omitted.
+ If the part is human-readable text or HTML, the value for this
+ key MUST be a UTF-8 string (D-Bus signature 's').
+ If the part is not text, the value MUST be a byte-array
+ (D-Bus signature 'ay'). If the part is a text-based format
+ that is not the main body of the message (e.g. an iCalendar
+ or an attached XML document), the value SHOULD be a UTF-8 string,
+ transcoding from another charset to UTF-8 if necessary, but
+ MAY be a byte-array (of unspecified character set) if
+ transcoding fails or the source charset is not known.</dd>
+
+ <!-- FIXME: "sufficiently small to include" is not currently
+ defined; we should add some API so clients can tell the
+ CM how large a message it should emit in the signal.-->
+
+ <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
+ <dd>This part is specific to the given interface, which is
+ neither Text nor Messages. It SHOULD be ignored if that
+ interface is not supported. (Note that an 'interface' key
+ can also appear on the first part, where it indicates that the
+ entire message should be ignored if unsupported.)</dd>
+ </dl>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type type="s" name="Delivery_Report_Header_Key">
+ <tp:added version="0.19.8"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
+ delivery report, along with the corresponding value types. Some of
+ these are special-cases of headers defined by
+ <tp:type>Message_Header_Key</tp:type>.</p>
+
+ <dl>
+ <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>, as
+ defined by <tp:type>Message_Header_Key</tp:type>)</dt>
+ <dd>MUST be the intended recipient of the original message, if
+ available (zero or omitted if the intended recipient is
+ unavailable or is not a contact, e.g. a chatroom), even if the
+ delivery report actually came from an intermediate server.</dd>
+
+ <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>,
+ as defined by <tp:type>Message_Header_Key</tp:type>)</dt>
+ <dd>MUST be Channel_Text_Message_Type_Delivery_Report.</dd>
+
+ <dt>delivery-status (u - <tp:type>Delivery_Status</tp:type>)</dt>
+ <dd>The status of the message. All delivery reports MUST contain
+ this key in the first Message_Part.</dd>
+
+ <dt>delivery-token (s - <tp:type>Protocol_Message_Token</tp:type>)</dt>
+
+ <dd>
+ <p>An identifier for the message to which this delivery report
+ refers. MUST NOT be an empty string. Omitted if not
+ available.</p>
+
+ <p>Clients may match this against the token produced by the
+ SendMessage method and MessageSent signal. A status report
+ with no token could match any sent message, and a sent
+ message with an empty token could match any status report.
+ If multiple sent messages match, clients SHOULD use some
+ reasonable heuristic.</p>
+
+ <tp:rationale>
+ In an ideal world, we could unambiguously match reports
+ against messages; however, deployed protocols are not ideal,
+ and not all reports and messages can be matched.
+ </tp:rationale>
+ </dd>
+
+ <dt>delivery-error (u -
+ <tp:type>Channel_Text_Send_Error</tp:type>)</dt>
+ <dd>
+ The reason for the failure. MUST be omitted if this was a
+ successful delivery; SHOULD be omitted if it would be
+ Channel_Text_Send_Error_Unknown.
+ </dd>
+
+ <dt>delivery-dbus-error (s -
+ <tp:type>DBus_Error_Name</tp:type>)</dt>
+ <dd>
+ The reason for the failure, specified as a (possibly
+ implementation-specific) D-Bus error. MUST be omitted if this was
+ a successful delivery. If set, the 'delivery-error' key SHOULD be
+ set to the closest available value.
+ </dd>
+
+ <dt>delivery-error-message (s)</dt>
+ <dd>
+ Debugging information on why the message could not be delivered.
+ MUST be omitted if this was a successful delivery; MAY always be
+ omitted.
+ </dd>
+
+ <dt>delivery-echo (aa{sv} - <tp:type>Message_Part[]</tp:type>)</dt>
+ <dd>
+ <p>The message content, as defined by the Messages interface.
+ Omitted if no content is available. Content MAY have been
+ truncated, message parts MAY have been removed, and message
+ parts MAY have had their content removed (i.e. the message part
+ metadata is present, but the 'content' key is not).</p>
+
+ <tp:rationale>
+ Some protocols, like XMPP, echo the failing message back to
+ the sender. This is sometimes the only way to match it
+ against the sent message, so we include it here.
+ </tp:rationale>
+ </dd>
+
+ </dl>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type type="u" name="Message_Part_Index"
+ array-name="Message_Part_Index_List">
+ <tp:deprecated version="0.21.5">
+ This type is only used by
+ <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
+ unimplemented and deprecated.
+ </tp:deprecated>
+ <tp:added version="0.17.17"/>
+ <tp:docstring>
+ The index of a message part within a message.
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:mapping name="Message_Part_Content_Map">
+ <tp:added version="0.17.17"/>
+ <tp:deprecated version="0.21.5">
+ This structure is only used by
+ <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
+ unimplemented and deprecated.
+ </tp:deprecated>
+ <tp:docstring>
+ A mapping from message part indexes to their content, as returned by
+ <tp:member-ref>GetPendingMessageContent</tp:member-ref>.
+ </tp:docstring>
+
+ <tp:member type="u" tp:type="Message_Part_Index" name="Part">
+ <tp:docstring>
+ Indexes into the array of <tp:type>Message_Part</tp:type>s that
+ represents a message. The "headers" part (which is not a valid
+ argument to GetPendingMessageContent) is considered to be part 0,
+ so the valid part numbers start at 1 (for the second message part).
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="v" name="Content">
+ <tp:docstring>
+ The message part's content. The variant MUST contain either type
+ 's' or 'ay' (UTF-8 text string, or byte array), following the
+ same rules as for the value of the 'content' key in
+ the <tp:type>Message_Part</tp:type> mappings.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:simple-type type="s" name="Protocol_Message_Token"
+ array-name="Protocol_Message_Token_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An opaque token used to identify messages in the underlying.
+ protocol. As a special case, the empty string indicates that there
+ is no particular identification for a message.</p>
+
+ <p>CM implementations SHOULD use an identifier expected to be unique,
+ such as a UUID, for outgoing messages (if possible).</p>
+
+ <p>Some protocols can only track a limited number of messages
+ in a small message-ID space (SMS messages are identified by a single
+ byte), and some implementations send non-unique identifiers (some
+ XMPP clients use very simple message IDs, such as an incrementing
+ integer that resets to 1 at the beginning of each connection). As a
+ result, clients MUST NOT assume that protocol tokens will not be
+ re-used.</p>
+
+ <p>In particular, clients SHOULD use a heuristic to assign delivery
+ reports to messages, such as matching on message content or
+ timestamp (if available), or assuming that the delivery report
+ refers to the most recent message with that ID.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="Protocol_Content_Identifier" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A protocol-specific identifier for a blob of content, as used for
+ the <tt>identifier</tt> key in a <tp:type>Message_Part</tp:type>. The
+ same identifier MAY be re-used if the same content, byte-for-byte,
+ appears as a part of several messages.</p>
+
+ <tp:rationale>
+ <p>On XMPP, these identifiers might be Content-IDs for custom
+ smileys implemented using <a
+ href="http://xmpp.org/extensions/xep-0231.html">XEP-0232 Bits of
+ Binary</a>; the same smiley might well appear in multiple
+ messages.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <method name="SendMessage" tp:name-for-bindings="Send_Message">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Submit a message to the server for sending.
+ If this method returns successfully, the message has been submitted
+ to the server and the <tp:member-ref>MessageSent</tp:member-ref>
+ signal is emitted. A corresponding
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
+ signal on the Text interface MUST also be emitted.</p>
+
+ <p>This method MUST return before the MessageSent signal is
+ emitted.</p>
+
+ <tp:rationale>
+ <p>This means that the process sending the message is the first
+ to see the <tp:type>Protocol_Message_Token</tp:type>, and can
+ relate the message to the corresponding
+ <tp:member-ref>MessageSent</tp:member-ref> signal by comparing
+ message tokens (if supported by the protocol).</p>
+ </tp:rationale>
+
+ <p>If this method fails, message submission to the server has failed
+ and no signal on this interface (or the Text interface) is
+ emitted.</p>
+
+ <p>If this method succeeds, message submission to the server has
+ succeeded, but the message has not necessarily reached its intended
+ recipient. If a delivery failure is detected later, this is
+ signalled by receiving a message whose <code>message-type</code>
+ header maps to
+ <tp:value-ref type="Channel_Text_Message_Type">Delivery_Report</tp:value-ref>.
+ Similarly, if delivery is detected to have been successful
+ (which is not possible in all protocols), a successful delivery
+ report will be signalled.</p>
+ </tp:docstring>
+
+ <arg direction="in" type="aa{sv}" tp:type="Message_Part[]"
+ name="Message">
+ <tp:docstring>
+ The message content, including any attachments or alternatives.
+ This MUST NOT include the following headers, or any others that
+ do not make sense for a client to specify:
+ <code>message-sender</code>, <code>message-sender-id</code>,
+ <code>message-sent</code>, <code>message-received</code>,
+ <code>pending-message-id</code>.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Flags" type="u"
+ tp:type="Message_Sending_Flags">
+ <tp:docstring>
+ Flags affecting how the message is sent. The channel MAY ignore some
+ or all flags, depending on
+ <tp:member-ref>DeliveryReportingSupport</tp:member-ref>; the flags
+ that were handled by the CM are provided in
+ <tp:member-ref>MessageSent</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="s" tp:type="Protocol_Message_Token"
+ name="Token">
+ <tp:docstring>
+ An opaque token used to match any incoming delivery or failure
+ reports against this message, or an empty string if the message
+ is not readily identifiable.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The requested message is malformed and cannot be sent.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:flags name="Message_Sending_Flags" value-prefix="Message_Sending_Flag"
+ type="u">
+ <tp:docstring>
+ Flags altering the way a message is sent. The "most usual" action
+ should always be to have these flags unset. Some indication of which
+ flags are supported is provided by the
+ <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property.
+ </tp:docstring>
+
+ <tp:flag suffix="Report_Delivery" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Provide a successful delivery report if possible, even if this is
+ not the default for this protocol. Ignored if delivery reports are
+ not possible on this protocol.</p>
+
+ <tp:rationale>
+ <p>In some protocols, like XMPP, it is not conventional to request
+ or send positive delivery notifications.</p>
+ </tp:rationale>
+
+ <p>Delivery failure reports SHOULD always be sent, but if this flag
+ is present, the connection manager MAY also try harder to obtain
+ failed delivery reports or allow them to be matched to outgoing
+ messages.</p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Report_Read" value="2">
+ <tp:added version="0.19.9"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Provide a delivery report when the message is read by the
+ recipient, even if this is not the default for this protocol.
+ Ignored if read reports are not possible on this protocol.</p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Report_Deleted" value="4">
+ <tp:added version="0.19.9"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Provide a delivery report when the message is deleted by the
+ recipient, even if this is not the default for this protocol.
+ Ignored if such reports are not possible on this protocol.</p>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <signal name="MessageSent" tp:name-for-bindings="Message_Sent">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Signals that a message has been submitted for sending. This
+ MUST be emitted exactly once per emission of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
+ signal on the Text interface, for backwards-compatibility; clients
+ SHOULD ignore the latter if this interface is present, as mentioned
+ in the introduction.</p>
+
+ <p>This SHOULD be emitted as soon as the CM determines it's
+ theoretically possible to send the message (e.g. the parameters are
+ supported and correct).</p>
+
+ <tp:rationale>
+ <p>This signal allows a process that is not the caller of
+ SendMessage to log sent messages.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg type="aa{sv}" tp:type="Message_Part[]" name="Content">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The message content (see <tp:type>Message_Part</tp:type> for full
+ details). If the message that was passed to
+ <tp:member-ref>SendMessage</tp:member-ref> has a formatted text
+ part that the connection manager recognises, but no
+ <tt>text/plain</tt> alternative, the CM MUST use the formatted text
+ part to generate a <tt>text/plain</tt> alternative which is also
+ included in this signal argument.</p>
+
+ <p>The connection manager SHOULD include the
+ <code>message-sender</code>, <code>message-sender-id</code> and
+ <code>message-sent</code> headers in the representation of the
+ message that is signalled here. If the channel has
+ channel-specific handles, the <code>message-sender</code> and
+ <code>message-sender-id</code> SHOULD reflect the sender that
+ other contacts will see.</p>
+
+ <p>If the connection manager can predict that the message will be
+ altered during transmission, this argument SHOULD reflect what
+ other contacts will receive, rather than being a copy of the
+ argument to SendMessage (if the message is truncated,
+ formatting or alternatives are dropped, etc., then the edited
+ version SHOULD appear in this signal).</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Flags" type="u" tp:type="Message_Sending_Flags">
+ <tp:docstring>
+ <p>Flags affecting how the message was sent. The flags might be a
+ subset of those passed to SendMessage if the caller requested
+ unsupported flags.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Message_Token" type="s" tp:type="Protocol_Message_Token">
+ <tp:docstring>
+ An opaque token used to match any incoming delivery or failure
+ reports against this message, or an empty string if the message
+ is not readily identifiable.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="PendingMessages" type="aaa{sv}" access="read"
+ tp:type="Message_Part[][]" tp:name-for-bindings="Pending_Messages">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of incoming messages that have neither been acknowledged nor
+ rejected. This list is a more detailed version of the one returned
+ by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text.ListPendingMessages</tp:dbus-ref>,
+ and contains the same messages, uniquely identified by the same
+ pending message IDs. Its items can be removed using
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.</p>
+
+ <p>Change notification is via
+ <tp:member-ref>MessageReceived</tp:member-ref> and
+ <tp:member-ref>PendingMessagesRemoved</tp:member-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="PendingMessagesRemoved"
+ tp:name-for-bindings="Pending_Messages_Removed">
+ <tp:docstring>
+ The messages with the given IDs have been removed from the
+ <tp:member-ref>PendingMessages</tp:member-ref> list. Clients SHOULD NOT
+ attempt to acknowledge those messages.
+
+ <tp:rationale>
+ This completes change notification for the PendingMessages property
+ (previously, there was change notification when pending messages
+ were added, but not when they were removed).
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Message_IDs" type="au" tp:type="Message_ID[]">
+ <tp:docstring>
+ The messages that have been removed from the pending message list.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="GetPendingMessageContent"
+ tp:name-for-bindings="Get_Pending_Message_Content">
+ <tp:deprecated version='0.21.5'
+ xmlns="http://www.w3.org/1999/xhtml">
+ This method has never been implemented, and in any case would have been
+ impossible to use correctly when multiple clients (such as a logger and
+ the handler) are interested in a text channel. See <a
+ href='https://bugs.freedesktop.org/show_bug.cgi?id=26417'>freedesktop.org
+ bug #26417</a> for more details.
+ </tp:deprecated>
+ <tp:docstring>
+ Retrieve the content of one or more parts of a pending message.
+ Note that this function may take a considerable amount of time
+ to return if the part's 'needs-retrieval' flag is true; consider
+ extending the default D-Bus method call timeout. Additional API is
+ likely to be added in future, to stream large message parts.
+ </tp:docstring>
+
+ <arg name="Message_ID" type="u" tp:type="Message_ID" direction="in">
+ <tp:docstring>
+ The ID of a pending message
+ </tp:docstring>
+ </arg>
+
+ <arg name="Parts" type="au" direction="in"
+ tp:type="Message_Part_Index[]">
+ <tp:docstring>
+ The desired entries in the array of message parts, identified by
+ their position. The "headers" part (which is not a valid argument
+ to this method) is considered to be part 0, so the valid part
+ numbers start at 1 (for the second Message_Part).
+ </tp:docstring>
+ </arg>
+
+ <arg name="Content" type="a{uv}" direction="out"
+ tp:type="Message_Part_Content_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The content of the requested parts. The keys in this mapping
+ are positions in the array of message parts; the values are
+ either of type 's' or 'ay' (UTF-8 text string, or byte array),
+ following the same rules as for the value of the 'content' key in
+ the <tp:type>Message_Part</tp:type> mappings.</p>
+
+ <p>If the one of the requested part numbers was greater than zero
+ but referred to a part that had no content (i.e. it had no
+ 'content-type' key or no 'content' key), it is simply omitted from
+ this mapping; this is not considered to be an error condition.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Either there is no pending message with the given message ID,
+ or one of the part numbers given was 0 or too large.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="MessageReceived" tp:name-for-bindings="Message_Received">
+ <tp:docstring>
+ Signals that a message has been received and added to the pending
+ messages queue. This MUST be emitted exactly once per emission of the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
+ signal on the Text interface, for backwards-compatibility; clients
+ SHOULD ignore the latter in favour of this signal if this interface is
+ present, as mentioned in the introduction.
+ </tp:docstring>
+
+ <arg type="aa{sv}" tp:type="Message_Part[]" name="Message">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The message content, including any attachments or alternatives. If
+ the incoming message contains formatted text without a plain text
+ alternative, the connection manager MUST generate a
+ <tt>text/plain</tt> alternative from the formatted text, and
+ include it in this message (both here, and in the
+ <tp:member-ref>PendingMessages</tp:member-ref> property).</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="Delivery_Status" value-prefix="Delivery_Status"
+ plural="Delivery_Statuses" type="u">
+ <tp:docstring>
+ <p>The status of a message as indicated by a delivery report.</p>
+
+ <p>If this enum is extended in future specifications, this should
+ only be to add new, non-overlapping conditions (i.e. all failures
+ should still be signalled as either Temporarily_Failed
+ or Permanently_Failed). If additional detail is required (e.g.
+ distinguishing between the various types of permanent failure) this
+ will be done using additional
+ <tp:type>Delivery_Report_Header_Key</tp:type>s.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ The message's disposition is unknown.
+ Clients SHOULD consider all messages to have status
+ Delivery_Status_Unknown unless otherwise specified; connection
+ managers SHOULD NOT signal this delivery status explicitly.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Delivered" value="1">
+ <tp:docstring>
+ The message has been delivered to the intended recipient.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Temporarily_Failed" value="2">
+ <tp:docstring>
+ Delivery of the message has failed. Clients SHOULD notify the user,
+ but MAY automatically try sending another copy of the message.
+
+ <tp:rationale>
+ Similar to errors with type="wait" in XMPP; analogous to
+ 4xx errors in SMTP.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Permanently_Failed" value="3">
+ <tp:docstring>
+ Delivery of the message has failed. Clients SHOULD NOT try again
+ unless by specific user action. If the user does not modify the
+ message or alter configuration before re-sending, this error is
+ likely to happen again.
+
+ <tp:rationale>
+ Similar to errors with type="cancel", type="modify"
+ or type="auth" in XMPP; analogous to 5xx errors in SMTP.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Accepted" value="4">
+ <tp:docstring>
+ An intermediate server has accepted the message but the message
+ has not been yet delivered to the ultimate recipient. The
+ connection manager might send a Failed report or Delivered report
+ later.
+
+ <tp:rationale>
+ Similar to "202 Accepted" success code in SIP; analogous to
+ 251 and 252 responses in SMTP.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Read" value="5">
+ <tp:added version="0.19.9"/>
+ <tp:docstring>
+ The message has been read by the intended recipient.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Deleted" value="6">
+ <tp:added version="0.19.9"/>
+ <tp:docstring>
+ The message has been deleted by the intended recipient. This MAY be
+ signalled on its own if the message is deleted without being read, or
+ after <code>Read</code> if the message was read before being deleted.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:flags name="Delivery_Reporting_Support_Flags"
+ value-prefix="Delivery_Reporting_Support_Flag" type="u">
+ <tp:docstring>
+ Flags indicating the level of support for delivery reporting on this
+ channel, as found on the
+ <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property. Any
+ future flags added to this set will conform to the
+ convention that the presence of an extra flag implies that
+ more operations will succeed. Note that CMs may always provide more
+ reports than are requested in the
+ <tp:type>Message_Sending_Flags</tp:type> passed to
+ <tp:member-ref>SendMessage</tp:member-ref>.
+
+ <tp:rationale>
+ If senders want delivery reports, they should ask for them. If they
+ don't want delivery reports, they can just ignore them, so there's no
+ need to have capability discovery for what will happen if a delivery
+ report isn't requested.
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:flag suffix="Receive_Failures" value="1">
+ <tp:docstring>
+ Clients MAY expect to receive negative delivery reports if
+ Message_Sending_Flag_Report_Delivery is specified when sending.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Receive_Successes" value="2">
+ <tp:docstring>
+ Clients MAY expect to receive positive delivery reports if
+ Message_Sending_Flag_Report_Delivery is specified when sending.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Receive_Read" value="4">
+ <tp:added version="0.19.9"/>
+ <tp:docstring>
+ Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
+ <code>Read</code> reports if Message_Sending_Flag_Report_Read
+ is specified when sending.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Receive_Deleted" value="8">
+ <tp:added version="0.19.9"/>
+ <tp:docstring>
+ Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
+ <code>Deleted</code> reports if Message_Sending_Flag_Report_Deleted
+ is specified when sending.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <property name="DeliveryReportingSupport" access="read"
+ tp:type="Delivery_Reporting_Support_Flags" type="u"
+ tp:name-for-bindings="Delivery_Reporting_Support"
+ tp:immutable="yes">
+ <tp:docstring>
+ A bitfield indicating features supported by this channel.
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Password.xml b/spec/spec/Channel_Interface_Password.xml
new file mode 100644
index 000000000..8f08627e2
--- /dev/null
+++ b/spec/spec/Channel_Interface_Password.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Password" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>
+Copyright © 2005-2011 Collabora Limited
+Copyright © 2005-2009 Nokia Corporation
+Copyright © 2006 INdT
+ </tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Password">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:flags name="Channel_Password_Flags" value-prefix="Channel_Password_Flag" type="u">
+ <tp:flag suffix="Provide" value="8">
+ <tp:docstring>
+ The <tp:member-ref>ProvidePassword</tp:member-ref> method must be
+ called now for the user to join the channel
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Hint" value="4">
+ <tp:added version="0.25.0"/>
+ <tp:docstring>
+ The <tp:dbus-ref namespace="ofdT.Channel.Interface">RoomConfig1.PasswordHint</tp:dbus-ref>
+ contains a hint for the password.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+ <method name="GetPasswordFlags" tp:name-for-bindings="Get_Password_Flags">
+ <arg direction="out" type="u" tp:type="Channel_Password_Flags"
+ name="Password_Flags">
+ <tp:docstring>
+ An integer with the logical OR of all the flags set
+ (values of ChannelPasswordFlags)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns the bitwise-OR of the flags relevant to the password on this
+ channel. The user interface can use this to present information about
+ which operations are currently valid.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+ <signal name="PasswordFlagsChanged"
+ tp:name-for-bindings="Password_Flags_Changed">
+ <arg name="Added" type="u" tp:type="Channel_Password_Flags">
+ <tp:docstring>
+ A bitwise OR of the flags which have been set
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="u" tp:type="Channel_Password_Flags">
+ <tp:docstring>
+ A bitwise OR of the flags which have been cleared
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the flags as returned by
+ <tp:member-ref>GetPasswordFlags</tp:member-ref> are changed.
+ The user interface should be updated as appropriate.
+ </tp:docstring>
+ </signal>
+ <method name="ProvidePassword" tp:name-for-bindings="Provide_Password">
+ <arg direction="in" name="Password" type="s">
+ <tp:docstring>
+ The password
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="b" name="Correct">
+ <tp:docstring>
+ A boolean indicating whether or not the password was correct
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Provide the password so that the channel can be joined. Must be
+ called with the correct password in order for channel joining to
+ proceed if the 'provide' password flag is set.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for channels that may have a password set that users need
+ to provide before being able to join. The
+ <tp:member-ref>GetPasswordFlags</tp:member-ref> method and the
+ associated <tp:member-ref>PasswordFlagsChanged</tp:member-ref>
+ signal indicate whether the user must now provide a password to join
+ the channel.</p>
+
+ <p>Once the user has joined the channel, the current
+ password-protectedness of the room can be checked (and possibly
+ modified) using the <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>RoomConfig1</tp:dbus-ref>
+ interface, if implemented.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Picture.xml b/spec/spec/Channel_Interface_Picture.xml
new file mode 100644
index 000000000..fb2fcf3d2
--- /dev/null
+++ b/spec/spec/Channel_Interface_Picture.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Picture"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Picture1"
+ tp:causes-havoc="draft">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.25.0"/>
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
+ value="true"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface channels can implement to support a picture. Most
+ of the time this will be implemented by channels implementing
+ the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Room2</tp:dbus-ref>
+ interface. Note that this interface is not restricted to
+ Text channels, and can also be used on Call channels.</p>
+
+ <tp:rationale>
+ This is a separate interface from
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">RoomConfig1</tp:dbus-ref>
+ because (a) it's possible some protocol might support pictures for
+ 1:1 chats; and (b) it avoids downloading an unwanted picture in a
+ GetAll request.
+ </tp:rationale>
+ </tp:docstring>
+
+ <method name="SetPicture" tp:name-for-bindings="Set_Picture">
+ <arg direction="in" type="ay" name="Picture">
+ <tp:docstring>The new picture.</tp:docstring>
+ </arg>
+ <arg direction="in" type="s" name="MIME_Type">
+ <tp:docstring>The MIME type.</tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Set the room's picture. Clients SHOULD look at the picture
+ flags before calling this method as the user might not have
+ permission to set the picture.</p>
+
+ <p>A successful return of this method indicates a successful
+ change in picture, but clients should still listen for changes
+ to the <tp:member-ref>Picture</tp:member-ref> property for
+ further changes by other users or the server.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Picture is somehow invalid: e.g. unsupported MIME type,
+ too big, etc.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="Picture" tp:name-for-bindings="Picture"
+ type="(ays)" tp:type="Avatar" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The picture representing this channel.</p>
+
+ <p>This property may change during the lifetime of the channel and
+ MUST not be included in a channel request.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Actor" tp:name-for-bindings="Actor"
+ type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The normalized contact ID representing who last modified
+ the picture, or the empty string if it is not known.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ActorHandle" tp:name-for-bindings="Actor_Handle"
+ type="u" tp:type="Contact_Handle" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The handle corresponding to <tp:member-ref>Actor</tp:member-ref>,
+ or 0 if the <tp:member-ref>Actor</tp:member-ref> is unknown.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Timestamp" tp:name-for-bindings="Timestamp"
+ type="x" tp:type="Unix_Timestamp64" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A unix timestamp indicating when the picture was last
+ modified, or <code>INT_MAX64</code> if unknown.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CanSet" tp:name-for-bindings="Can_Set"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>TRUE if the <tp:member-ref>Picture</tp:member-ref> property
+ can be set by the user by calling
+ <tp:member-ref>SetPicture</tp:member-ref>, otherwise
+ FALSE.</p>
+
+ <p>If implementations are unsure of what this value should be
+ it SHOULD still be set to what it believes the value
+ is. As a result, clients should be aware that
+ <tp:member-ref>SetPicture</tp:member-ref> can still fail
+ even with this property set to TRUE.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="SupportedMIMETypes"
+ tp:name-for-bindings="Supported_MIME_Types"
+ type="as" access="read" tp:immutable="yes">
+ <tp:docstring>
+ An array of supported MIME types (e.g. "image/jpeg").
+ Clients MAY assume that the first type in this array is preferred.
+ </tp:docstring>
+ </property>
+
+ <property name="MinimumHeight"
+ tp:name-for-bindings="Minimum_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The minimum height in pixels of the picture, which MAY be 0.
+ </tp:docstring>
+ </property>
+
+ <property name="MinimumWidth"
+ tp:name-for-bindings="Minimum_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The minimum width in pixels of the picture, which MAY be 0.
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedHeight"
+ tp:name-for-bindings="Recommended_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The recommended height in pixels of the picture, or 0 if
+ there is no preferred height.
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedWidth"
+ tp:name-for-bindings="Recommended_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The recommended width in pixels of the picture, or 0 if
+ there is no preferred width.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumHeight"
+ tp:name-for-bindings="Maximum_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The maximum height in pixels of the picture, or 0 if
+ there is no limit.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumWidth"
+ tp:name-for-bindings="Maximum_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The maximum width in pixels of the picture, or 0 if
+ there is no limit.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumBytes"
+ tp:name-for-bindings="Maximum_Bytes"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The maximum size in bytes of the picture, or 0 if
+ there is no limit.
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Room.xml b/spec/spec/Channel_Interface_Room.xml
new file mode 100644
index 000000000..92423b67c
--- /dev/null
+++ b/spec/spec/Channel_Interface_Room.xml
@@ -0,0 +1,368 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Room"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Room2">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.24.0">(version 2)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Different IM protocols use a variety of ways to name chat rooms. The
+ simplest example is perhaps IRC, where chat rooms have short,
+ persistent, human-readable string names, and are generally global
+ across the network. Skype chat rooms have persistent string names, so
+ you can leave and re-join a room, but these names are opaque unique
+ identifiers. MSN chat rooms are unnamed, and you can only join one by
+ being invited. And XMPP wins the coveted “most complicated chat rooms”
+ prize: chat rooms may be hosted by different servers with different DNS
+ names; normally they have human-readable names, except that all MUCs on
+ Google Talk's conference server have UUIDs as names, and <a
+ href="http://xmpp.org/extensions/xep-0045.html#createroom-unique"><acronym
+ title="XMPP Extension Protocol">XEP</acronym>-0045 §10.1.4
+ <q>Requesting a Unique Room Name</q></a> defines a protocol for
+ requesting a unique, opaque room name on the server. Note that
+ this interface is not restricted to Text channels, and can
+ also be used on Call channels.</p>
+
+ <p>This interface intends to support and differentiate these mechanisms
+ more clearly than the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ properties can alone. It initially contains a pair of properties used
+ to represent the human-readable parts of a
+ <tp:type>Room_Handle</tp:type>'s identifier, if any. The above examples
+ for different protocols are represented as follows:</p>
+
+ <ul>
+ <li>The IRC channel <tt>#telepathy</tt> on Freenode is represented by a
+ channel with properties
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>Room</code>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ = <code>"#telepathy"</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>"#telepathy"</code>,
+ <tp:member-ref>Server</tp:member-ref> = <code>""</code>, indicating
+ that the room has a human-readable identifier, and is not confined to
+ a particular server on the network.
+
+ <tp:rationale>
+ Actually, IRC supports creating “local” channels specific to the
+ server they are created on. These channels have identifiers
+ starting with <tt>&amp;</tt> rather than <tt>#</tt>. These could be
+ represented by setting <tp:member-ref>Server</tp:member-ref>
+ appropriately.
+ </tp:rationale>
+ </li>
+
+ <li>A Skype group chat with opaque identifier <tt>0xdeadbeef</tt> has
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>Room</code>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ = <code>"0xdeadbeef"</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>""</code>,
+ <tp:member-ref>Server</tp:member-ref> = <code>""</code>, indicating
+ that the room has an identifier but no human-readable name.
+ </li>
+
+ <li>An MSN group chat has
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>None</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>""</code>,
+ <tp:member-ref>Server</tp:member-ref> = <code>""</code>, indicating
+ that the room has neither an identifier (so it cannot be re-joined
+ later) nor a human-readable name.
+ </li>
+
+ <li>A standard Jabber multi-user chat
+ <tt>jdev@conference.jabber.org</tt> has
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>Room</code>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ = <code>"jdev@conference.jabber.org"</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>"jdev"</code>,
+ <tp:member-ref>Server</tp:member-ref> = <code>"conference.jabber.org"</code>.
+ </li>
+
+ <li>A Google Talk private MUC <tt>private-chat-11111x1x-11xx-111x-1111-111x1xx11x11@groupchat.google.com</tt> has
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>Room</code>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ = <code>"private-chat-11111x1x-11xx-111x-1111-111x1xx11x11@groupchat.google.com"</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>""</code>,
+ <tp:member-ref>Server</tp:member-ref> =
+ <code>"groupchat.google.com"</code>, indicating that the room has a
+ persistent identifier, no human-readable name, and is hosted by a
+ particular server.
+ </li>
+
+ <li>Similarly, a XEP-0045 §10.1.4 uniquely-named room
+ <tt>lrcgsnthzvwm@conference.jabber.org</tt> has
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = <code>Room</code>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ = <code>"lrcgsnthzvwm@conference.jabber.org"</code>,
+ <tp:member-ref>RoomName</tp:member-ref> = <code>""</code>,
+ <tp:member-ref>Server</tp:member-ref> =
+ <code>"conference.jabber.org"</code>, indicating that the room has a
+ persistent identifier, no human-readable name, and is hosted by a
+ particular server.
+ </li>
+ </ul>
+
+ <h4>Requestable channel classes</h4>
+
+ <p>If the connection supports joining text chat rooms by unique
+ identifier, like Skype, it should advertise a
+ <tp:type>Requestable_Channel_Class</tp:type> matching:</p>
+
+ <blockquote>
+ <pre>
+( Fixed = { ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >Text</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref>: Room,
+ },
+ Allowed = [ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetID</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandle</tp:dbus-ref>,
+ ]
+)</pre></blockquote>
+
+ <p>Channel requests must specify either <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetID</tp:dbus-ref> or <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandle</tp:dbus-ref>.</p>
+
+ <p>If, like IRC, the room identifiers are also human-readable, the
+ RCCs should also include RoomName in <var>Allowed_Properties</var>:</p>
+
+ <blockquote>
+ <pre>
+( Fixed = { ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >Text</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref>: Room,
+ },
+ Allowed = [ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetID</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandle</tp:dbus-ref>,
+ ...<tp:member-ref>RoomName</tp:member-ref>
+ ]
+),
+
+( Fixed = { ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >Text</tp:dbus-ref>
+ },
+ Allowed = [ ...<tp:member-ref>RoomName</tp:member-ref>,
+ ]
+)</pre></blockquote>
+
+ <p>Requests may specify the RoomName in place of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref> or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ . Note how <tp:member-ref>RoomName</tp:member-ref> appears
+ in <var>Allowed_Properties</var> of a different RCC because
+ when <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref> is omitted (or is None), both
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandle</tp:dbus-ref> and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetID</tp:dbus-ref> must also be omitted.
+ <tp:member-ref>RoomName</tp:member-ref> is allowed in conjuction
+ with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref> or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ in some situations, as explained below in the <em>Requesting room
+ channels</em> section.
+ </p>
+
+ <p>If rooms may be on different servers, <tp:member-ref>Server</tp:member-ref>
+ should also be included in the allowed properties, but
+ CMs MUST use a reasonable default
+ <tp:member-ref>Server</tp:member-ref> if not explicitly
+ specified in a channel request. The CM's default server MAY
+ be configurable by a connection parameter specified on a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.ConnectionManager"
+ >RequestConnection</tp:dbus-ref> call, similarly to how the
+ fallback conference server is specified on jabber connections in
+ gabble.</p>
+
+ <p>If the protocol supports unnamed rooms, <tp:member-ref>RoomName</tp:member-ref>
+ should be fixed to the empty string, and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ should be None:</p>
+
+ <blockquote>
+ <pre>
+( Fixed = { ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >Text</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref>: None,
+ ...<tp:member-ref>RoomName</tp:member-ref>: "",
+ },
+ Allowed = [ ]
+)</pre></blockquote>
+
+ <h4>Requesting room channels</h4>
+
+ <p>When explicitly joining a room, the CM cannot know whether the room
+ ID is unique or not. As a result, if this is the case, adding an
+ empty string <tp:member-ref>RoomName</tp:member-ref> into the channel
+ request will ensure the CM knows. For example:</p>
+
+ <blockquote>
+ <pre>
+{ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>: Room,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>: "qwerasdfzxcv@conference.jabber.org",
+ ...<tp:member-ref>RoomName</tp:member-ref>: ""
+}</pre></blockquote>
+
+ <p>If <tp:member-ref>RoomName</tp:member-ref> features in
+ <var>Allowed_Properties</var> then the only value allowed in conjunction
+ with <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ or <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ is the empty string. Requests with conflicting
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>
+ and <tp:member-ref>RoomName</tp:member-ref> properties
+ will fail with InvalidArgument.</p>
+
+ <p>To create a XEP-0045 §10.1.4 uniquely-named room channel
+ on the conference.jabber.org server, then the following channel
+ request should be made:</p>
+
+ <blockquote>
+ <pre>
+{ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>,
+ ...<tp:member-ref>RoomName</tp:member-ref>: ""
+ ...<tp:member-ref>Server</tp:member-ref>: "conference.jabber.org"
+}</pre>
+ </blockquote>
+
+ <p>If everything is successful, then when the channel request is
+ satisfied, a new channel will appear with the following properties:</p>
+
+ <blockquote>
+ <pre>
+{ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>: Room,
+ ...<tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>: "kajsdhkajshdfjkshdfjkhs@conference.jabber.org",
+ ...<tp:member-ref>RoomName</tp:member-ref>: ""
+ ...<tp:member-ref>Server</tp:member-ref>: "conference.jabber.org"
+}</pre>
+ </blockquote>
+
+ <p>The CM will have received the unique room name (kajsdhkajshdfjkshdfjkhs)
+ and then created a room with such a name on the said server. The empty
+ <tp:member-ref>RoomName</tp:member-ref> property shows that the room name
+ is not human-readable.</p>
+
+ </tp:docstring>
+
+ <property name="RoomName" tp:name-for-bindings="Room_Name" type="s"
+ access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The human-readable identifier of a chat room. Note that if
+ non-empty, this property (and perhaps also
+ <tp:member-ref>Server</tp:member-ref>) should be sufficient in
+ a channel request to join the room. XMPP MUCs have a room name
+ concept which is more like a topic, except more
+ persistent. This D-Bus property is <strong>not</strong> this
+ XMPP room name, but the bit before the @ in the room jid; see
+ <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>RoomConfig1.Title</tp:dbus-ref>
+ for that concept.</p>
+
+ <p>This property cannot change during the lifetime of the channel. It
+ should appear in the <var>Allowed_Properties</var> of a
+ <tp:type>Requestable_Channel_Class</tp:type> for the connection if
+ rooms on this connection have human-readable names, and can be joined
+ by name.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Server" tp:name-for-bindings="Server" type="s"
+ access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>For protocols with a concept of chatrooms on multiple servers with
+ different DNS names (like XMPP), the DNS name of the server hosting
+ this channel (for example, <tt>"conference.jabber.org"</tt> or
+ <tt>"groupchat.google.com"</tt>). For other protocols, the empty
+ string.</p>
+
+ <p>This property cannot change during the lifetime of the channel. It
+ should appear in the <var>Allowed_Properties</var> of a
+ <tp:type>Requestable_Channel_Class</tp:type> for the connection if
+ and only if non-empty values are supported.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Creator" tp:name-for-bindings="Creator"
+ type="s" access="read" tp:immutable="yes">
+ <tp:added version="0.25.0"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The normalized contact ID representing who created the room; or
+ the empty string if unknown.
+ </tp:docstring>
+ </property>
+
+ <property name="CreatorHandle" tp:name-for-bindings="Creator_Handle"
+ type="u" tp:type="Contact_Handle" access="read"
+ tp:immutable="yes">
+ <tp:added version="0.25.0"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The handle corresponding to <tp:member-ref>Creator</tp:member-ref>;
+ or 0 if <tp:member-ref>Creator</tp:member-ref> is unknown.
+ </tp:docstring>
+ </property>
+
+ <property name="CreationTimestamp"
+ tp:name-for-bindings="Creation_Timestamp"
+ type="x" tp:type="Unix_Timestamp64" access="read"
+ tp:immutable="yes">
+ <tp:added version="0.25.0"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A unix timestamp indicating when the room was created; or
+ <code>INT_MAX64</code> if unknown.
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Room_Config.xml b/spec/spec/Channel_Interface_Room_Config.xml
new file mode 100644
index 000000000..18bb06f0c
--- /dev/null
+++ b/spec/spec/Channel_Interface_Room_Config.xml
@@ -0,0 +1,267 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Room_Config"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.RoomConfig1">
+ <tp:added version="0.24.0">version 1. This replaces the old-school
+ Telepathy properties on <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>.</tp:added>
+ <tp:requires interface='org.freedesktop.Telepathy.Channel.Interface.Room2'/>
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
+ value="true"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Represents the configuration of a chatroom, some aspects of which may
+ be modifiable by the user, depending on their priviledges. This
+ corresponds to the room configuration on XMPP, and various channel mode
+ flags on IRC.</p>
+
+ <p>The “topic” (on IRC) or “subject” (on XMPP) is not part of this
+ interface; it can be found on the <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Subject2</tp:dbus-ref>
+ interface.</p>
+ </tp:docstring>
+
+ <property name="Anonymous" tp:name-for-bindings="Anonymous" type="b" access="read">
+ <tp:docstring>
+ <code>True</code> if people may join the channel without other members being made
+ aware of their identity.
+ </tp:docstring>
+ </property>
+ <property name="InviteOnly" tp:name-for-bindings="InviteOnly" type="b" access="read">
+ <tp:docstring>
+ <code>True</code> if people may not join the channel until they have been invited.
+ </tp:docstring>
+ </property>
+ <property name="Limit" tp:name-for-bindings="Limit" type="u" access="read">
+ <tp:docstring>
+ The limit to the number of members; or <tt>0</tt> if there is no limit.
+ </tp:docstring>
+ </property>
+ <property name="Moderated" tp:name-for-bindings="Moderated" type="b" access="read">
+ <tp:docstring>
+ <code>True</code> if channel membership is not sufficient to allow participation.
+ </tp:docstring>
+ </property>
+ <property name="Title" tp:name-for-bindings="Title" type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A human-visible name for the channel, if it differs from <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Room2.RoomName</tp:dbus-ref>; the
+ empty string, otherwise.
+
+ <tp:rationale>
+ <p>On XMPP, this represents the <code>muc#roomconfig_roomname</code>
+ field of the <a
+ href='http://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner'><code>muc#roomconfig</code></a>
+ form. So for <code>jdev@conference.jabber.org</code>, for example:</p>
+
+ <ul>
+ <li><tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Room2.RoomName</tp:dbus-ref>
+ = <code>"jdev"</code>;</li>
+ <li><tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Room2.Server</tp:dbus-ref>
+ = <code>"conference.jabber.org"</code>;</li>
+ <li><tp:member-ref>Title</tp:member-ref> = <code>"General Jabber
+ development discussion"</code>.</li>
+ </ul>
+
+ <p>XEP-0045 is awful.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+ <property name="Description" tp:name-for-bindings="Description" type="s" access="read">
+ <tp:docstring>
+ A human-readable description of the channel's overall purpose; if any.
+ </tp:docstring>
+ </property>
+ <property name="Persistent" tp:name-for-bindings="Persistent" type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <code>True</code> if the channel will remain in existence on the server after all
+ members have left it.
+ </tp:docstring>
+ </property>
+ <property name="Private" tp:name-for-bindings="Private" type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <code>True</code> if the channel is not visible to non-members.
+ </tp:docstring>
+ </property>
+
+ <property name="PasswordProtected" type="b" access="read"
+ tp:name-for-bindings="Password_Protected">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <code>True</code> if contacts joining this channel must provide a
+ password to be granted entry. Note that this property does not
+ indicate that a password is required <em>right now</em>; see the
+ <tp:dbus-ref namespace='ofdT.Channel.Interface'>Password</tp:dbus-ref>
+ interface for the API used to provide a password while joining a room.
+ </tp:docstring>
+ </property>
+
+ <property name="Password" tp:name-for-bindings="Password" type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ If <tp:member-ref>PasswordProtected</tp:member-ref> is
+ <code>True</code>, the password required to enter the channel, if
+ known. If the password is unknown, or
+ <tp:member-ref>PasswordProtected</tp:member-ref> is
+ <code>False</code>, the empty string.
+
+ <tp:rationale>
+ On XMPP—bless its cotton socks!—non-owners of a MUC cannot see its
+ current password, even if they just provided the password in order to
+ join the room…
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="PasswordHint" tp:name-for-bindings="Password_Hint"
+ type="s" access="read">
+ <tp:added version="0.25.0"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tp:member-ref>PasswordProtected</tp:member-ref> is
+ <code>True</code>, an optional hint for the password.</p>
+
+ <p>On protocols supporting PasswordHint (indicated by its presence
+ in <tp:member-ref>MutableProperties</tp:member-ref>),
+ <tp:member-ref>Password</tp:member-ref> and PasswordHint MUST be
+ set in a single call to
+ <tp:member-ref>UpdateConfiguration</tp:member-ref>.</p>
+
+ <tp:rationale>
+ Skype requires that the password and its hint be supplied together.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="CanUpdateConfiguration" type="b" access="read"
+ tp:name-for-bindings="Can_Update_Configuration">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ If <code>True</code>, the user may call
+ <tp:member-ref>UpdateConfiguration</tp:member-ref> to change the values
+ of the properties listed in
+ <tp:member-ref>MutableProperties</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <property name="MutableProperties" type="as" access="read"
+ tp:name-for-bindings="Mutable_Properties">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of (unqualified) property names on this interface which may
+ be modified using <tp:member-ref>UpdateConfiguration</tp:member-ref>
+ (if <tp:member-ref>CanUpdateConfiguration</tp:member-ref> is
+ <code>True</code>). Properties not listed here cannot be
+ modified.</p>
+
+ <p>For example, IRC does not have the concept of joining a room without
+ other participants knowing your true identity; so on IRC the
+ <tp:member-ref>Anonymous</tp:member-ref> property will always be
+ <code>False</code>, and
+ <tp:member-ref>MutableProperties</tp:member-ref> will not include
+ <code>"Anonymous"</code>.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ConfigurationRetrieved" type="b" access="read"
+ tp:name-for-bindings="Configuration_Retrieved">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p><code>True</code> once the initial room configuration has been
+ retrieved, or <code>False</code> otherwise. On some services, this
+ may take some time after you've joined a room to fetch the
+ configuration. Once this property changes to <code>True</code>, the
+ other properties on this interface can be assumed to be accurate;
+ this property MUST not change to <code>False</code> after it becomes
+ <code>True</code>.</p>
+
+ <tp:rationale>
+ <p>An application's “configure this room” dialog might choose to
+ display a spinner while this property is <code>False</code>, rather
+ than allowing the user to edit probably-inaccurate
+ configuration.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="UpdateConfiguration" tp:name-for-bindings="Update_Configuration">
+ <arg direction="in" name="Properties" type="a{sv}">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The new values of one or more properties on this interface, which
+ must be listed in
+ <tp:member-ref>MutableProperties</tp:member-ref>. For
+ instance, to set up a channel for discussing top-secret corporate
+ merge plans, this parameter might be:
+ </p>
+
+ <blockquote>
+ <pre>{
+ 'Private': True,
+ 'InviteOnly': True,
+ 'Description': "The first rule of #inteltakeover is: do not talk about #inteltakeover",
+}</pre></blockquote>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tp:member-ref>CanUpdateConfiguration</tp:member-ref> is
+ <code>True</code>, modifies the current values of one or more
+ room properties. This method SHOULD NOT return until the change has
+ been accepted or declined by the server.</p>
+
+ <p>Note that the server may ostensibly accept the changes (thus
+ allowing this method to return success) but signal different values;
+ for example, the server might truncate
+ <tp:member-ref>Title</tp:member-ref> to some maximum length. Callers
+ SHOULD continue to listen for the <code>PropertiesChanged</code>
+ signal, and trust the values it signals over those provided to this
+ method.</p>
+ </tp:docstring>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The user is not allowed to reconfigure this room.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ One or more of the specified properties is unknown, or ill-typed.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ One or more of the specified properties cannot be modified on this
+ protocol.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The room's current configuration has not yet been retrieved, so we
+ cannot update it just yet. The application might like to try again
+ once the <tp:member-ref>ConfigurationRetrieved</tp:member-ref>
+ property becomes <code>True</code>.
+ </tp:docstring>
+ </tp:error>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_SASL_Authentication.xml b/spec/spec/Channel_Interface_SASL_Authentication.xml
new file mode 100644
index 000000000..7985a6bd5
--- /dev/null
+++ b/spec/spec/Channel_Interface_SASL_Authentication.xml
@@ -0,0 +1,723 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_SASL_Authentication"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2010 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.SASLAuthentication">
+ <tp:added version="0.21.5">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel interface for SASL authentication,
+ as defined by
+ <a href="http://tools.ietf.org/html/rfc4422">RFC 4422</a>.
+ When this interface appears on a <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channel, it represents authentication with the server. In future,
+ it could also be used to authenticate with secondary services,
+ or even to authenticate end-to-end connections with contacts. As a result,
+ this interface does not REQUIRE <tp:dbus-ref namespace="ofdT.Channel.Type"
+ >ServerAuthentication</tp:dbus-ref> to allow for a potential future
+ Channel.Type.PeerAuthentication interface.</p>
+
+ <p>In any protocol that requires a password, the connection manager can
+ use this channel to let a user interface carry out a simple SASL-like
+ handshake with it, as a way to get the user's credentials
+ interactively. This can be used to connect to protocols that may
+ require a password, without requiring that the password is saved in
+ the <tp:dbus-ref
+ namespace="ofdT">Account.Parameters</tp:dbus-ref>.</p>
+
+ <p>In some protocols, such as XMPP, authentication with the server
+ is also carried out using SASL. In these protocols, a channel with this
+ interface can provide a simple 1:1 mapping of the SASL negotiations
+ taking place in the protocol, allowing more advanced clients to
+ perform authentication via SASL mechanisms not known to the
+ connection manager.</p>
+
+ <tp:rationale>
+ <p>By providing SASL directly when the protocol supports it, we can
+ use mechanisms like Kerberos or Google's <code>X-GOOGLE-TOKEN</code>
+ without specific support in the connection manager.</p>
+ </tp:rationale>
+
+ <p>For channels managed by a
+ <tp:dbus-ref namespace="ofdT">ChannelDispatcher</tp:dbus-ref>,
+ only the channel's <tp:dbus-ref
+ namespace="ofdT.Client">Handler</tp:dbus-ref> may call the
+ methods on this interface. Other clients MAY observe the
+ authentication process by watching its signals and properties.</p>
+
+ <tp:rationale>
+ <p>There can only be one Handler, which is a good fit for SASL's
+ 1-1 conversation between a client and a server.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:simple-type name="SASL_Mechanism" type="s"
+ array-name="SASL_Mechanism_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A SASL mechanism, as defined by
+ <a href="http://tools.ietf.org/html/rfc4422">RFC 4422</a>
+ and registered in
+ <a href="http://www.iana.org/assignments/sasl-mechanisms">the
+ IANA registry of SASL mechanisms</a>, or an unregistered
+ SASL mechanism such as <code>X-GOOGLE-TOKEN</code> used in the
+ same contexts.</p>
+
+ <p>As a special case, pseudo-mechanisms starting with
+ <code>X-TELEPATHY-</code> are defined by this specification.
+ Use of these pseudo-mechanisms indicates that the user's credentials
+ are to be passed to the connection manager, which will then use
+ them for authentication with the service, either by implementing
+ the client side of some SASL mechanisms itself or by using a
+ non-SASL protocol. The only such pseudo-mechanism currently
+ defined is <code>X-TELEPATHY-PASSWORD</code>.</p>
+
+ <p>The <code>X-TELEPATHY-PASSWORD</code> mechanism is extremely
+ simple:</p>
+
+ <ul>
+ <li>The client MUST call
+ <tp:member-ref>StartMechanismWithData</tp:member-ref>, with
+ Initial_Data set to the password encoded in UTF-8.
+ For simplicity, calling <tp:member-ref>StartMechanism</tp:member-ref>
+ followed by calling <tp:member-ref>Respond</tp:member-ref> is not
+ allowed in this mechanism.</li>
+
+ <li>The connection manager uses the password, together with
+ authentication details from the Connection parameters, to
+ authenticate itself to the server.</li>
+
+ <li>When the connection manager finishes its attempt to authenticate
+ to the server, the channel's state changes to
+ either SASL_Status_Server_Succeeded or
+ SASL_Status_Server_Failed as appropriate.</li>
+ </ul>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <property name="AvailableMechanisms"
+ tp:name-for-bindings="Available_Mechanisms"
+ type="as" tp:type="SASL_Mechanism[]"
+ access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The SASL mechanisms as offered by the server, plus any
+ pseudo-SASL mechanisms supported by the connection manager for
+ credentials transfer. For instance, in a protocol that
+ natively uses SASL (like XMPP), this might be
+ <code>[ "X-TELEPATHY-PASSWORD", "PLAIN", "DIGEST-MD5",
+ "SCRAM-SHA-1" ]</code>.</p>
+
+ <p>To make it possible to implement a very simple password-querying
+ user interface without knowledge of any particular SASL mechanism,
+ implementations of this interface MUST implement the
+ pseudo-mechanism <code>X-TELEPATHY-PASSWORD</code>, unless none
+ of the available mechanisms use a password at all.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="HasInitialData" tp:name-for-bindings="Has_Initial_Data"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, <tp:member-ref>StartMechanismWithData</tp:member-ref>
+ can be expected to work for SASL mechanisms not starting with
+ <code>X-TELEPATHY-</code> (this is the case in most, but not all,
+ protocols). If false, <tp:member-ref>StartMechanism</tp:member-ref>
+ must be used instead.</p>
+
+ <p>This property does not affect the <code>X-TELEPATHY-</code>
+ pseudo-mechanisms such as <code>X-TELEPATHY-PASSWORD</code>,
+ which can use
+ <tp:member-ref>StartMechanismWithData</tp:member-ref> regardless
+ of the value of this property.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CanTryAgain" tp:name-for-bindings="Can_Try_Again"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, <tp:member-ref>StartMechanism</tp:member-ref> and (if
+ supported) <tp:member-ref>StartMechanismWithData</tp:member-ref>
+ can be expected to work when in one of the Failed states. If
+ false, the only thing you can do after failure is to close the
+ channel.</p>
+
+ <tp:rationale>
+ <p>Retrying isn't required to work, although some protocols and
+ implementations allow it.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property type="u" tp:type="SASL_Status" access="read"
+ name="SASLStatus" tp:name-for-bindings="SASL_Status">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The current status of this channel.
+ Change notification is via the
+ <tp:member-ref>SASLStatusChanged</tp:member-ref> signal.
+ </tp:docstring>
+ </property>
+
+ <property type="s" tp:type="DBus_Error_Name" access="read"
+ name="SASLError" tp:name-for-bindings="SASL_Error">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The reason for the <tp:member-ref>SASLStatus</tp:member-ref>, or
+ an empty string if the state is neither
+ Server_Failed nor Client_Failed.</p>
+
+ <p>In particular, an ordinary authentication failure (as would
+ be produced for an incorrect password) SHOULD be represented by
+ <tp:error-ref>AuthenticationFailed</tp:error-ref>,
+ cancellation by the user's request SHOULD be represented
+ by <tp:error-ref>Cancelled</tp:error-ref>, and
+ cancellation by a local process due to inconsistent or invalid
+ challenges from the server SHOULD be represented by
+ <tp:error-ref>ServiceConfused</tp:error-ref>.</p>
+
+ <p>If this interface appears on a <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channel, and connection to the server fails with an authentication
+ failure, this error code SHOULD be copied into the
+ <tp:dbus-ref
+ namespace="ofdT">Connection.ConnectionError</tp:dbus-ref>
+ signal.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="SASLErrorDetails"
+ tp:name-for-bindings="SASL_Error_Details"
+ access="read" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tp:member-ref>SASLError</tp:member-ref> is non-empty,
+ any additional information about the last
+ disconnection; otherwise, the empty map. The keys and values are
+ the same as for the second argument of
+ <tp:dbus-ref
+ namespace="ofdT">Connection.ConnectionError</tp:dbus-ref>.</p>
+
+ <p>If this interface appears on a <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channel, and connection to the server fails with an authentication
+ failure, these details SHOULD be copied into the
+ <tp:dbus-ref
+ namespace="ofdT">Connection.ConnectionError</tp:dbus-ref>
+ signal.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="AuthorizationIdentity"
+ tp:name-for-bindings="Authorization_Identity"
+ type="s" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The identity for which authorization is being attempted,
+ typically the 'account' from the <tp:dbus-ref
+ namespace="ofdT.ConnectionManager">RequestConnection</tp:dbus-ref>
+ parameters, normalized and formatted according to the
+ conventions used for SASL in this protocol.</p>
+
+ <tp:rationale>
+ <p>The normalization used for SASL might not be the same
+ normalization used elsewhere: for instance, in a protocol
+ with email-like identifiers such as XMPP or SIP, the user
+ "juliet@example.com" might have to authenticate to the
+ example.com server via SASL PLAIN as "juliet".</p>
+ </tp:rationale>
+
+ <p>This is usually achieved by using the authorization identity for
+ authentication, but an advanced Handler could offer the option
+ to authenticate under a different identity.</p>
+
+ <p>The terminology used here is that the authorization identity
+ is who you want to act as, and the authentication identity is
+ used to prove that you may do so. For instance, if Juliet is
+ authorized to access a role account, "sysadmin@example.com",
+ and act on its behalf, it might be possible to authenticate
+ as "juliet@example.com" with her own password, but request to
+ be authorized as "sysadmin@example.com" instead of her own
+ account. See
+ <a href="http://tools.ietf.org/html/rfc4422#section-3.4.1">RFC
+ 4422 §3.4.1</a> for more details.</p>
+
+ <tp:rationale>
+ <p>In SASL the authorization identity is normally guessed from
+ the authentication identity, but the information available
+ to the connection manager is the identity for which
+ authorization is required, such as the desired JID in XMPP,
+ so that's what we signal to UIs; it's up to the UI to
+ choose whether to authenticate as the authorization identity
+ or some other identity.</p>
+
+ <p>As a concrete example, the "sysadmin" XMPP account mentioned
+ above would have <code>{ 'account': 'sysadmin@example.com' }</code>
+ in its Parameters, and this property would also be
+ 'sysadmin@example.com'. A simple Handler would
+ merely prompt for sysadmin@example.com's password,
+ and use that JID as both the authorization and authentication
+ identity, which might result in SASL PLAIN authentication with the
+ initial response
+ '\000sysadmin@example.com\000root'.</p>
+
+ <p>A more advanced Handler might also ask for an authentication
+ identity, defaulting to 'sysadmin@example.com'; if Juliet
+ provided authentication identity 'juliet@example.com' and
+ password 'romeo', the Handler might perform SASL PLAIN
+ authentication using the initial response
+ 'sysadmin@example.com\000juliet@example.com\000romeo'.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="DefaultUsername"
+ tp:name-for-bindings="Default_Username"
+ type="s" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The default username for use with SASL mechanisms that deal
+ with a "simple username" (as defined in <a
+ href="http://tools.ietf.org/html/rfc4422">RFC 4422</a>). If
+ such a SASL mechanism is in use, clients SHOULD default to
+ using the DefaultUsername; also, if the client uses
+ the DefaultUsername, it SHOULD assume that the authorization
+ identity <tp:member-ref>AuthorizationIdentity</tp:member-ref>
+ will be derived from it by the server.</p>
+
+ <tp:rationale>
+ <p>In XMPP, <a href="http://trac.tools.ietf.org/wg/xmpp/trac/ticket/49">
+ servers typically expect</a> "user@example.com" to
+ authenticate with username "user"; this was a SHOULD in <a
+ href="http://tools.ietf.org/html/rfc3920">RFC 3920</a>.</p>
+
+ <p><a
+ href="http://tools.ietf.org/html/draft-ietf-xmpp-3920bis-19">3920bis</a>
+ weakens that SHOULD to "in the absence of local information
+ provided by the server, an XMPP client SHOULD assume that
+ the authentication identity for such a SASL mechanism is the
+ combination of a user name and password, where the simple
+ user name is the localpart of the user's JID".</p>
+ </tp:rationale>
+
+ <p>For example, in the simple case, if the user connects with
+ <tp:dbus-ref
+ namespace="ofdT.ConnectionManager">RequestConnection</tp:dbus-ref>({
+ account: "<tt>user@example.com</tt>" }) and use PLAIN with
+ password "password", he or she should authenticate like so:
+ "<tt>\0user\0password</tt>" and the channel will look like
+ this:</p>
+
+<blockquote><pre>{ "...<tp:member-ref>DefaultUsername</tp:member-ref>": "user",
+ "...<tp:member-ref>AuthorizationIdentity</tp:member-ref>": "user@example.com }
+</pre></blockquote>
+
+ <p>In the complex case, if the same user is using his or her
+ sysadmin powers to log in as the "announcements" role address,
+ he or she would connect with <tp:dbus-ref
+ namespace="ofdT.ConnectionManager">RequestConnection</tp:dbus-ref>({
+ account: "<tt>announcements@example.com</tt>" }) and the SASL
+ channel would look like this:</p>
+
+<blockquote><pre>{ "...<tp:member-ref>DefaultUsername</tp:member-ref>": "announcements",
+ "...<tp:member-ref>AuthorizationIdentity</tp:member-ref>": "announcements@example.com }
+</pre></blockquote>
+
+ <p>A sufficiently elaborate UI could give the opportunity
+ to override the username from "announcements" to "user".
+ The user's simple username is still "user", and the password is
+ still "password", but this time he or she is trying to authorize
+ to act as <tt>announcements@example.com</tt>, so the UI would
+ have to perform SASL PLAIN with this string:
+ "<tt>announcements@example.com\0user\0password</tt>", where
+ "announcements@example.com" is the
+ <tp:member-ref>AuthorizationIdentity</tp:member-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="DefaultRealm" tp:name-for-bindings="Default_Realm"
+ type="s" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The default realm (as defined in
+ <a href="http://tools.ietf.org/html/rfc2831#section-2.1.1">RFC
+ 2831</a>) to use for authentication, if the server does not
+ supply one.</p>
+
+ <tp:rationale>
+ <p>The server is not required to provide a realm; if it doesn't,
+ the client is expected to ask the user or provide a sensible
+ default, typically the requested DNS name of the server.
+ In some implementations of <code>DIGEST-MD5</code>, the
+ server does not specify a realm, but expects that the client
+ will choose a particular default, and authentication will
+ fail if the client's default is different. Connection
+ managers for protocols where this occurs are more easily able
+ to work around these implementations than a generic client
+ would be.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="MaySaveResponse" tp:name-for-bindings="May_Save_Response"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Whether or not the client can save the authentication response and
+ re-use it to automate future authentication challenges.</p>
+
+ <p>If this property is <code>False</code>, the client SHOULD NOT attempt
+ to cache the authentication response in its own keyring.</p>
+
+ <p>If this property is not specified, it should be treated as if it were
+ <code>True</code>.</p>
+
+ <tp:rationale>Some protocols or services may have terms and conditions
+ that prohibit caching a user's credentials.</tp:rationale>
+
+ </tp:docstring>
+ </property>
+
+
+ <method name="StartMechanism" tp:name-for-bindings="Start_Mechanism">
+ <arg direction="in" name="Mechanism" type="s" tp:type="SASL_Mechanism">
+ <tp:docstring>
+ The chosen mechanism.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Start an authentication try using <var>Mechanism</var>, without
+ sending initial data (an "initial response" as defined in RFC
+ 4422).</p>
+
+ <tp:rationale>
+ <p>This method is appropriate for mechanisms where the client
+ cannot send anything until it receives a challenge from the
+ server, such as
+ <code><a href="http://tools.ietf.org/html/rfc2831">DIGEST-MD5</a></code>
+ in "initial authentication" mode.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The channel is not in a state where starting authentication makes
+ sense (i.e. SASL_Status_Not_Started, or (if
+ <tp:member-ref>CanTryAgain</tp:member-ref> is true)
+ SASL_Status_Server_Failed or
+ SASL_Status_Client_Failed). You should call
+ <tp:member-ref>AbortSASL</tp:member-ref> and wait for
+ SASL_Status_Client_Failed before starting another attempt.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The server or connection manager doesn't implement the given
+ SASL mechanism. Choose a SASL mechanism from
+ <tp:member-ref>AvailableMechanisms</tp:member-ref>, or abort
+ authentication if none of them are suitable.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="StartMechanismWithData"
+ tp:name-for-bindings="Start_Mechanism_With_Data">
+ <arg direction="in" name="Mechanism" type="s" tp:type="SASL_Mechanism">
+ <tp:docstring>
+ The chosen mechanism.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Initial_Data" type="ay">
+ <tp:docstring>
+ Initial data (an "initial response" in RFC 4422's terminology) to send
+ with the mechanism.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Start an authentication try using <var>Mechanism</var>, and send
+ <var>Initial_Data</var> as the "initial response" defined in
+ <a href="http://tools.ietf.org/html/rfc4422#section-3.3">RFC 4422
+ §3.3</a>.</p>
+
+ <tp:rationale>
+ <p>This method is appropriate for mechanisms where the client may
+ send data first, such as <code>PLAIN</code>, or must send data
+ first, such as
+ <code><a href="http://tools.ietf.org/html/rfc2831">DIGEST-MD5</a></code>
+ in "subsequent authentication" mode.</p>
+
+ <p>Having two methods allows any mechanism where it makes a difference
+ to distinguish between the absence of an initial response
+ (<tp:member-ref>StartMechanism</tp:member-ref>) and a zero-byte
+ initial response (StartMechanismWithData, with Initial_Data
+ empty).</p>
+ </tp:rationale>
+
+ <p>If the <tp:member-ref>HasInitialData</tp:member-ref>
+ property is false, this indicates that the underlying protocol
+ does not make it possible to send initial data. In such protocols,
+ this method may only be used for the <code>X-TELEPATHY-</code>
+ pseudo-mechanisms (such as <code>X-TELEPATHY-PASSWORD</code>),
+ and will fail if used with an ordinary SASL mechanism.</p>
+
+ <tp:rationale>
+ <p>For instance, the IRC SASL extension implemented in Charybdis and
+ Atheme does not support initial data - the first message in the
+ exchange only carries the mechanism. This is significant if using
+ <code><a href="http://tools.ietf.org/html/rfc2831">DIGEST-MD5</a></code>,
+ which cannot be used in the faster "subsequent authentication"
+ mode on a protocol not supporting initial data.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The channel is not in a state where starting authentication makes
+ sense (i.e. SASL_Status_Not_Started, or (if
+ <tp:member-ref>CanTryAgain</tp:member-ref> is true)
+ SASL_Status_Server_Failed or
+ SASL_Status_Client_Failed). You should call
+ <tp:member-ref>AbortSASL</tp:member-ref> and wait for
+ SASL_Status_Client_Failed before starting another attempt.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The server or connection manager doesn't implement the given
+ SASL mechanism (choose one from
+ <tp:member-ref>AvailableMechanisms</tp:member-ref>, or abort
+ authentication if none of them are suitable), or doesn't allow
+ initial data to be sent (as indicated by
+ <tp:member-ref>HasInitialData</tp:member-ref>; call
+ <tp:member-ref>StartMechanism</tp:member-ref> instead).
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Respond" tp:name-for-bindings="Respond">
+ <arg direction="in" name="Response_Data" type="ay">
+ <tp:docstring>
+ The response data.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Send a response to the the last challenge received via
+ <tp:member-ref>NewChallenge</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ Either the state is not In_Progress, or no challenge has been
+ received yet, or you have already responded to the last challenge.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AcceptSASL" tp:name-for-bindings="Accept_SASL">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If the channel's status is SASL_Status_Server_Succeeded,
+ this method confirms successful authentication and advances
+ the status of the channel to SASL_Status_Succeeded.</p>
+
+ <p>If the channel's status is SASL_Status_In_Progress, calling this
+ method indicates that the last
+ <tp:member-ref>NewChallenge</tp:member-ref> signal was in fact
+ additional data sent after a successful SASL negotiation, and
+ declares that from the client's point of view, authentication
+ was successful. This advances the state of the channel to
+ SASL_Status_Client_Accepted.</p>
+
+ <p>In mechanisms where the server authenticates itself to the client,
+ calling this method indicates that the client considers this to have
+ been successful. In the case of <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channels, this means that the connection manager MAY continue to
+ connect, and MAY advance the <tp:dbus-ref
+ namespace="ofdT">Connection.Status</tp:dbus-ref> to Connected.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ Either the state is neither In_Progress nor Server_Succeeded, or no
+ challenge has been received yet, or you have already responded to
+ the last challenge.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AbortSASL" tp:name-for-bindings="Abort_SASL">
+ <arg direction="in" name="Reason" type="u" tp:type="SASL_Abort_Reason">
+ <tp:docstring>
+ Reason for abort.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Debug_Message" type="s">
+ <tp:docstring>
+ Debug message for abort.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Abort the current authentication try.</p>
+
+ <p>If the current status is SASL_Status_Server_Failed or
+ SASL_Status_Client_Failed, this method returns successfully, but has
+ no further effect. If the current status is SASL_Status_Succeeded
+ or SASL_Status_Client_Accepted then NotAvailable is raised.
+ Otherwise, it changes the channel's state to
+ SASL_Status_Client_Failed, with an appropriate error name and
+ reason code.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The current state is either Succeeded or Client_Accepted.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="SASLStatusChanged" tp:name-for-bindings="SASL_Status_Changed">
+ <tp:docstring>
+ Emitted when the status of the channel changes.
+ </tp:docstring>
+ <arg type="u" tp:type="SASL_Status" name="Status">
+ <tp:docstring>
+ The new value of <tp:member-ref>SASLStatus</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <arg type="s" tp:type="DBus_Error_Name" name="Reason">
+ <tp:docstring>
+ The new value of <tp:member-ref>SASLError</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <arg type="a{sv}" tp:type="String_Variant_Map" name="Details">
+ <tp:docstring>
+ The new value of <tp:member-ref>SASLErrorDetails</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="NewChallenge" tp:name-for-bindings="New_Challenge">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a new challenge is received from the server, or when
+ a message indicating successful authentication and containing
+ additional data is received from the server.</p>
+
+ <p>When the channel's handler is ready to proceed, it should respond
+ to the challenge by calling <tp:member-ref>Respond</tp:member-ref>,
+ or respond to the additional data by calling
+ <tp:member-ref>AcceptSASL</tp:member-ref>. Alternatively, it may call
+ <tp:member-ref>AbortSASL</tp:member-ref> to abort authentication.</p>
+ </tp:docstring>
+ <arg name="Challenge_Data" type="ay">
+ <tp:docstring>
+ The challenge data or additional data from the server.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="SASL_Abort_Reason" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A reason why SASL authentication was aborted by the client.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Invalid_Challenge" value="0">
+ <tp:docstring>
+ The server sent an invalid challenge or data.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="User_Abort" value="1">
+ <tp:docstring>
+ The user aborted the authentication.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="SASL_Status" type="u" plural="SASL_Statuses">
+ <tp:enumvalue suffix="Not_Started" value="0">
+ <tp:docstring>
+ The initial state. The Handler SHOULD either
+ call <tp:member-ref>AbortSASL</tp:member-ref>, or connect to the
+ <tp:member-ref>NewChallenge</tp:member-ref> signal then call
+ <tp:member-ref>StartMechanism</tp:member-ref> or
+ <tp:member-ref>StartMechanismWithData</tp:member-ref>.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="In_Progress" value="1">
+ <tp:docstring>
+ The challenge/response exchange is in progress. The Handler SHOULD
+ call either <tp:member-ref>Respond</tp:member-ref> or
+ <tp:member-ref>AcceptSASL</tp:member-ref> exactly once per emission
+ of <tp:member-ref>NewChallenge</tp:member-ref>, or call
+ <tp:member-ref>AbortSASL</tp:member-ref> at any time.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Server_Succeeded" value="2">
+ <tp:docstring>
+ The server has indicated successful authentication, and the
+ connection manager is waiting for confirmation from the Handler.
+ The Handler must call either <tp:member-ref>AcceptSASL</tp:member-ref> or
+ <tp:member-ref>AbortSASL</tp:member-ref> to indicate whether it
+ considers authentication to have been successful.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Client_Accepted" value="3">
+ <tp:docstring>
+ The Handler has indicated successful authentication, and the
+ connection manager is waiting for confirmation from the server.
+ The state will progress to either Succeeded or Server_Failed when
+ confirmation is received.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Succeeded" value="4">
+ <tp:docstring>
+ Everyone is happy (the server sent success, and the client has called
+ <tp:member-ref>AcceptSASL</tp:member-ref>). Connection to the server
+ will proceed as soon as this state is reached. The Handler SHOULD
+ call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ to close the channel.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Server_Failed" value="5">
+ <tp:docstring>
+ The server has indicated an authentication failure.
+ If <tp:member-ref>CanTryAgain</tp:member-ref> is true,
+ the client may try to authenticate again, by calling
+ <tp:member-ref>StartMechanism</tp:member-ref> or
+ <tp:member-ref>StartMechanismWithData</tp:member-ref> again.
+ Otherwise, it should give up completely, by calling <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ on the channel.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Client_Failed" value="6">
+ <tp:docstring>
+ The client has indicated an authentication failure. The
+ possible actions are the same as for Server_Failed.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_SMS.xml b/spec/spec/Channel_Interface_SMS.xml
new file mode 100644
index 000000000..497e94519
--- /dev/null
+++ b/spec/spec/Channel_Interface_SMS.xml
@@ -0,0 +1,287 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_SMS"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008–2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.SMS">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
+ <tp:added version='0.19.12'>Imported from
+ rtcom-telepathy-glib, with the unused properties removed and the
+ documentation tidied up.</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface contains SMS-specific properties for text
+ channels.</p>
+
+ <p>The presence of this interface on a channel does not imply that
+ messages will be delivered via SMS.</p>
+
+ <p>This interface MAY appear in the
+ <tp:dbus-ref namespace="ofdT.Channel">Interfaces</tp:dbus-ref> property
+ of channels where <tp:member-ref>SMSChannel</tp:member-ref> would be
+ immutable and false. It SHOULD appear on channels where
+ <tp:member-ref>SMSChannel</tp:member-ref> is immutable and true, and
+ also on channels where <tp:member-ref>SMSChannel</tp:member-ref> is
+ mutable (i.e. channels that might fall back to sending SMS at any
+ time, such as on MSN).</p>
+
+ <h4>Handler filters</h4>
+
+ <p>A handler for class 0 SMSes should advertise the following filter:</p>
+
+ <blockquote><code>
+{ ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>,<br/>
+  ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>:
+ <tp:value-ref type="Handle_Type">Contact</tp:value-ref>,<br/>
+  ...<tp:dbus-ref namespace='ofdT.Channel.Interface'>SMS.Flash</tp:dbus-ref>:
+ True,<br/>
+}</code></blockquote>
+
+ <p>It should also set its <tp:dbus-ref
+ namespace='ofdT.Client.Handler'>BypassApproval</tp:dbus-ref> property
+ to <code>True</code>, so that it is invoked immediately for new
+ channels.</p>
+
+ <h4>Contact Capabilities</h4>
+
+ <p>Contacts to whom SMSes can be sent SHOULD indicate this via a
+ requestable channel class with
+ <tp:member-ref>SMSChannel</tp:member-ref> = True as a fixed
+ property.</p>
+
+ <p>For instance, a contact that can accept both text and SMS channels:</p>
+
+ <blockquote><code>
+[<br/>
+ ({ ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>,<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>:
+ <tp:value-ref type="Handle_Type">Contact</tp:value-ref>,<br/>
+  },<br/>
+  [ ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace='ofdT.Channel'>TargetID</tp:dbus-ref> ]),<br/>
+<br/>
+ ({ ...<tp:dbus-ref namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>:
+ ...<tp:dbus-ref namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>,<br/>
+    ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>:
+ <tp:value-ref type="Handle_Type">Contact</tp:value-ref>,<br/>
+    ...<tp:member-ref>SMSChannel</tp:member-ref>: True,<br/>
+  },<br/>
+  [ ...<tp:dbus-ref namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace='ofdT.Channel'>TargetID</tp:dbus-ref> ]),<br/>
+]
+ </code></blockquote>
+ </tp:docstring>
+
+ <property name="Flash" tp:name-for-bindings="Flash"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <code>True</code>, then this channel is exclusively for
+ receiving class 0 SMSes (and no SMSes can be sent using <tp:dbus-ref
+ namespace='ofdT.Channel.Interface.Messages'>SendMessage</tp:dbus-ref>
+ on this channel). If <code>False</code>, no incoming class 0 SMSes
+ will appear on this channel.</p>
+
+ <p>This property is immutable (cannot change), and therefore SHOULD
+ appear wherever immutable properties are reported, e.g. <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Requests"
+ >NewChannels</tp:dbus-ref> signals.</p>
+
+ <tp:rationale>
+ <p>Class 0 SMSes should be displayed immediately to the user, and
+ need not be saved to the device memory unless the user explicitly
+ chooses to do so. This is unlike “normal”, class 1 SMSes, which
+ must be stored, but need not be shown immediately in their entirity
+ to the user.</p>
+
+ <p>Separating class 0 SMSes into their own channel with this
+ immutable property allows them to be dispatched to a different
+ <tp:dbus-ref namespace='ofdT.Client'>Handler</tp:dbus-ref>—which
+ would include this property in its <tp:dbus-ref
+ namespace='ofdT.Client.Handler'
+ >HandlerChannelFilter</tp:dbus-ref>—avoiding the normal Text
+ channel handler having to decide for each message whether it should
+ be displayed to the user immediately or handled normally.</p>
+
+ <p>Currently, no mechanism is defined for <em>sending</em> class 0
+ SMSes. It seems reasonable to support specifying the class of an
+ outgoing SMS in its header <tp:type>Message_Part</tp:type>, rather
+ than requiring the UI to request a special channel for such SMSes;
+ hence, we define here that channels with Flash set to
+ <code>True</code> are read-only.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="SMSChannel"
+ tp:name-for-bindings="SMS_Channel"
+ type="b"
+ access="read" tp:requestable="yes" tp:immutable="sometimes">
+ <tp:added version="0.21.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If TRUE, messages sent and received on this channel are transmitted
+ via SMS.</p>
+
+ <p>If this property is included in the channel request, the
+ Connection Manager MUST return an appropriate channel (i.e. if TRUE
+ the channel must be for SMSes, if FALSE it must not), or else fail
+ to provide the requested channel with the
+ <tp:error-ref>NotCapable</tp:error-ref>
+ error.</p>
+
+ <p>For example, to explicitly request an SMS channel to a contact.
+ You might construct a channel request like:</p>
+
+ <blockquote><pre>{
+ Channel.Type: Channel.Type.Text,
+ Channel.TargetHandleType: Handle_Type_Contact,
+ Channel.TargetID: escher.cat,
+ Channel.Interface.SMS.SMSChannel: True,
+}</pre></blockquote>
+
+ <tp:rationale>
+ Some protocols allow us to send SMSes to a remote contact, without
+ knowing the phone number to which those SMSes will be sent. This
+ provides a mechanism to request such channels.
+ </tp:rationale>
+
+ <p>If this property is not included in the channel request, the
+ Connection Manager MAY return an SMS channel if that is the most
+ appropriate medium (i.e. if the channel target is a phone
+ number).</p>
+
+ <tp:rationale>
+ To some types of identifiers (i.e. phone numbers) it only makes
+ sense to return an SMS channel, this is what happens currently with
+ telepathy-ring. We don't want to break this behaviour when we are
+ not explicit about the type of channel we want. Alternatively, for
+ protocols where there is an SMS fallback for IM messages, it's
+ possible that we don't care what sort of channel we get, and simply
+ want notification of the transport.
+ </tp:rationale>
+
+ <p>Some protocols have a fallback to deliver IM messages via SMS.
+ On these protocols, the Connection Manager SHOULD set the property
+ value as appropriate, and notify its change with
+ <tp:member-ref>SMSChannelChanged</tp:member-ref>.</p>
+
+ <tp:rationale>
+ Protocols such as MSN can fall back to delivering IM messages via
+ SMS. Where possible we want clients to be able to inform the user
+ that their messages are going to be redirected to the remote
+ contact's phone.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <signal name="SMSChannelChanged"
+ tp:name-for-bindings="SMS_Channel_Changed">
+ <tp:added version="0.21.7"/>
+ <arg name="SMSChannel" type="b">
+ <tp:docstring>
+ The new value for <tp:member-ref>SMSChannel</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ This signal indicates a change in the
+ <tp:member-ref>SMSChannel</tp:member-ref> property.
+ </tp:docstring>
+ </signal>
+
+ <method name="GetSMSLength"
+ tp:name-for-bindings="Get_SMS_Length">
+ <tp:added version="0.23.1"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Returns the number of 140 octet chunks required to send a message
+ via SMS, as well as the number of remaining characters available in
+ the final chunk and, if possible, an estimate of the cost.</p>
+
+ <tp:rationale>
+ <p>There are a number of different SMS encoding mechanisms, and the
+ client doesn't know which mechanisms an individual CM might support.
+ This method allows the client, without any knowledge of the
+ encoding mechanism, to provide length details to the user.</p>
+ </tp:rationale>
+
+ <p>Clients SHOULD limit the frequency with which this method is called
+ and SHOULD NOT call it for every keystroke. Clients MAY estimate the
+ remaining size between single keystrokes.</p>
+ </tp:docstring>
+
+ <arg name="Message" type="aa{sv}" tp:type="Message_Part[]" direction="in">
+ <tp:docstring>
+ The message the user wishes to send.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Chunks_Required" type="u" direction="out">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The number of 140 octet chunks required to send this message.</p>
+
+ <p>For example, in the GSM standard 7-bit encoding, a 162 character
+ message would require 2 chunks.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Remaining_Characters" type="i" direction="out">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The number of further characters that can be fit in the final
+ chunk. A negative value indicates that the message will be
+ truncated by <code>abs(Remaining_Characters)</code>. The value
+ <code>MIN_INT32</code> (<code>-2<sup>31</sup></code>)
+ indicates the message will be truncated by an unknown amount.</p>
+
+ <p>For example, in the GSM standard 7-bit encoding, a 162 character
+ message would return 144 remaining characters (because of the
+ space required for the multipart SMS header).</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Estimated_Cost" type="i" direction="out">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The estimated cost of sending this message. The currency and
+ scale of this value are the same as the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface">Balance.AccountBalance</tp:dbus-ref>
+ property.</p>
+
+ <p>A value of <code>-1</code> indicates the cost could not be
+ estimated.</p>
+
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised when the method is not available on this channel.
+ Clients MAY choose to make their own estimation.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Raised when the content cannot be encoded into a valid SMS.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+ </interface>
+</node>
diff --git a/spec/spec/Channel_Interface_Securable.xml b/spec/spec/Channel_Interface_Securable.xml
new file mode 100644
index 000000000..d9d971394
--- /dev/null
+++ b/spec/spec/Channel_Interface_Securable.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Securable"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2010 Collabora Ltd.</tp:copyright>
+
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Securable">
+ <tp:added version="0.21.5">as stable API</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface exists to expose security information about
+ <tp:dbus-ref namespace="ofdT">Channel</tp:dbus-ref>s. The two
+ properties are sometimes immutable and can be used to make
+ decisions on how cautious to be about transferring sensitive
+ data. The special case of <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channels is one example of where the two properties are
+ immutable.</p>
+
+ <p>For example, clients MAY use these properties to decide
+ whether the <code>PLAIN</code> mechanism is acceptable for a
+ <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">SASLAuthentication</tp:dbus-ref>
+ channel.</p>
+ </tp:docstring>
+
+ <property name="Encrypted"
+ tp:name-for-bindings="Encrypted" type="b"
+ access="read" tp:immutable="sometimes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if this channel occurs over an encrypted
+ connection. This <strong>does not</strong> imply that steps
+ have been taken to avoid man-in-the-middle attacks.</p>
+
+ <tp:rationale>
+ <p>For future support for <a
+ href="http://tools.ietf.org/html/rfc5056">RFC 5056 Channel
+ Binding</a> it is desirable to be able to use some SASL
+ mechanisms over an encrypted connection to an unverified peer,
+ which can prove that it is the desired destination during
+ the SASL negotiation.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="Verified"
+ tp:name-for-bindings="Verified" type="b"
+ access="read" tp:immutable="sometimes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if this channel occurs over a connection that is
+ protected against tampering, and has been verified to be with
+ the desired destination: for instance, one where TLS was
+ previously negotiated, and the TLS certificate has been
+ verified against a configured certificate authority or
+ accepted by the user.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Service_Point.xml b/spec/spec/Channel_Interface_Service_Point.xml
new file mode 100644
index 000000000..787397b20
--- /dev/null
+++ b/spec/spec/Channel_Interface_Service_Point.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Service_Point" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.ServicePoint">
+ <tp:added version="0.19.7">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for channels
+ that can indicate when/if they are connected to some form
+ of service point. For example, when
+ dialing 9-1-1 in the US, a GSM modem/network will recognize that as
+ an emergency call, and inform higher levels of the stack that the
+ call is being handled by an emergency service. In this example,
+ the call is handled by a Public Safety Answering Point (PSAP) which is labeled
+ as "urn:service:sos". Other networks and protocols may handle this
+ differently while still using this interface.</p>
+
+ <p>Note that while the majority of examples given in this
+ documentation are for GSM calls, they could just as easily be
+ SIP calls, GSM SMS's, etc.</p>
+ </tp:docstring>
+
+ <property name="InitialServicePoint" tp:name-for-bindings="Initial_Service_Point"
+ type="(us)" tp:type="Service_Point" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This property is used to indicate that the channel target is a
+ well-known service point. Please note that the CM (or lower layers
+ of the stack or network) may forward the connection to other other
+ service points, which the CM SHOULD indicate via
+ <tp:member-ref>ServicePointChanged</tp:member-ref>
+ signal.</p>
+
+ <p>This property SHOULD be set for channel requests that are
+ specifically targeting service points.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CurrentServicePoint" tp:name-for-bindings="Current_Service_Point"
+ type="(us)" tp:type="Service_Point" access="read">
+ <tp:docstring>
+ The service point that the channel is connected to. If the channel is
+ not connected to a service point, the CM MUST set the
+ <tp:type>Service_Point_Type</tp:type> field to None; for instance,
+ this will be the case for ordinary calls.
+ </tp:docstring>
+ </property>
+
+ <signal name="ServicePointChanged" tp:name-for-bindings="Service_Point_Changed">
+ <tp:docstring>
+ <p>Emitted when a channel changes the service point that it's connected to. This
+ might be a new call being connected to a service, a call connected to
+ a service being routed to a different service
+ (ie, an emergency call being routed from a generic emergency PSAP to
+ a poison control PSAP), or any number of other things.</p>
+
+ <p>Note that this should be emitted as soon as the CM has been notified
+ of the switch, and has updated its internal state. The CM MAY still
+ be in the process of connecting to the new service point.</p>
+ </tp:docstring>
+
+ <arg name="Service_Point" type="(us)" tp:type="Service_Point">
+ <tp:docstring>
+ The new service point that is being used.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Splittable.xml b/spec/spec/Channel_Interface_Splittable.xml
new file mode 100644
index 000000000..760c13406
--- /dev/null
+++ b/spec/spec/Channel_Interface_Splittable.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Splittable"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Channel.Interface.Splittable.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for channels that can be made conceptually part of a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Conference</tp:dbus-ref>, and can then be detached from that
+ conference.</p>
+
+ <tp:rationale>
+ <p>This interface addresses part of freedesktop.org <a
+ href="http://bugs.freedesktop.org/show_bug.cgi?id=24906">bug
+ #24906</a> (GSM-compatible conference calls). GSM is currently
+ the only protocol known to implement this; PBXs might implement
+ it too.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <method name="Split"
+ tp:name-for-bindings="Split">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that this channel is removed from any
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Conference</tp:dbus-ref> of which it is a part.</p>
+
+ <p>This implies that the media streams within the conference are put on
+ hold and the media streams within the member channel leaving the
+ conference are unheld.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ This channel isn't in a conference.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This channel is in a conference but can't currently be split away
+ from it.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
diff --git a/spec/spec/Channel_Interface_Subject.xml b/spec/spec/Channel_Interface_Subject.xml
new file mode 100644
index 000000000..fcaf39836
--- /dev/null
+++ b/spec/spec/Channel_Interface_Subject.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Subject"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010–2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Subject2">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.24.0">(version 2)</tp:added>
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
+ value="true"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface channels can implement to support subjects. Most
+ of the time this will be implemented by channels implementing
+ the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Room2</tp:dbus-ref>
+ interface, but some protocols support subjects in 1-to-1 chats
+ (such as XMPP). Note that this interface is not restricted to
+ Text channels, and can also be used on Call channels.</p>
+ </tp:docstring>
+
+ <method name="SetSubject" tp:name-for-bindings="Set_Subject">
+ <arg direction="in" type="s" name="Subject">
+ <tp:docstring>The new subject.</tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Set the room's subject. Clients SHOULD look at the subject
+ flags before calling this method as the user might not have
+ permission to set the subject.</p>
+
+ <p>A successful return of this method indicates a successful
+ change in subject, but clients should still listen for changes
+ to the <tp:member-ref>Subject</tp:member-ref> property for
+ further changes by other users or the server.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="Subject" tp:name-for-bindings="Subject"
+ type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The human-readable subject on the channel such as the topic
+ in an IRC channel, or the room name in XMPP MUCs.</p>
+
+ <tp:rationale>This property replaces the subject Telepathy
+ property of Text channels, as Telepathy properties are soon to
+ be deprecated completely.</tp:rationale>
+
+ <p>This property may change during the lifetime of the channel and
+ MUST not be included in a channel request.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Actor" tp:name-for-bindings="Actor"
+ type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The normalized contact ID representing who last modified
+ the subject, or the empty string if it is not known.</p>
+
+ <tp:rationale>This property replaces the subject-contact
+ Telepathy property of Text channels, as Telepathy properties
+ are soon to be deprecated completely.</tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ActorHandle" tp:name-for-bindings="Actor_Handle"
+ type="u" tp:type="Contact_Handle" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The handle corresponding to <tp:member-ref>Actor</tp:member-ref>,
+ or 0 if the <tp:member-ref>Actor</tp:member-ref> is unknown.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Timestamp" tp:name-for-bindings="Timestamp"
+ type="x" tp:type="Unix_Timestamp64" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A unix timestamp indicating when the subject was last
+ modified, or <code>INT_MAX64</code> if unknown.</p>
+
+ <tp:rationale>This property replaces the subject-timestamp
+ Telepathy property of Text channels, as Telepathy properties
+ are soon to be deprecated completely.</tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="CanSet" tp:name-for-bindings="Can_Set"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>TRUE if the <tp:member-ref>Subject</tp:member-ref> property
+ can be set by the user by calling
+ <tp:member-ref>SetSubject</tp:member-ref>, otherwise
+ FALSE.</p>
+
+ <p>If implementations are unsure of what this value should be
+ it SHOULD still be set to what it believes the value
+ is. As a result, clients should be aware that
+ <tp:member-ref>SetSubject</tp:member-ref> can still fail
+ even with this property set to TRUE.</p>
+
+ <tp:rationale>In XMPP it is impossible to know whether an
+ occupant can set the subject as XMPP server implementations
+ are wildly inconsistent.</tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Transfer.xml b/spec/spec/Channel_Interface_Transfer.xml
new file mode 100644
index 000000000..02591c1d1
--- /dev/null
+++ b/spec/spec/Channel_Interface_Transfer.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Transfer" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Transfer"
+ tp:causes-havoc='not well-tested'>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <method name="Transfer">
+ <arg direction="in" name="Member" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the member to transfer
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Destination" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the destination contact
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that the given channel member instead connects to a different
+ contact ID.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+ <tp:docstring>
+ An interface for channels where you may request that one of the members
+ connects to somewhere else instead.
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Interface_Tube.xml b/spec/spec/Channel_Interface_Tube.xml
new file mode 100644
index 000000000..f31ab2138
--- /dev/null
+++ b/spec/spec/Channel_Interface_Tube.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Tube" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Interface.Tube">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A <i>tube</i> is a mechanism for arbitrary data transfer between
+ two or more IM users, used to allow applications on the users'
+ systems to communicate without having to establish network
+ connections themselves. Currently, two types of tube exist:
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Channel.Type.DBusTube</tp:dbus-ref> and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Channel.Type.StreamTube</tp:dbus-ref>. This interface contains
+ the properties, signals and methods common to both types of tube;
+ you can only create channels of a specific tube type, not of this
+ type. A tube channel contains exactly one tube; if you need several
+ tubes, you have to create several tube channels.</p>
+
+ <p>Tube channels can be requested for <tp:type>Handle_Type</tp:type>
+ Contact (for 1-1 communication) or Room (to communicate with others in
+ the room simultaneously).</p>
+
+ <p>As an exception to the usual handling of capabilities, connection managers
+ for protocols with capability discovery (such as XMPP) SHOULD advertise the
+ capability representing each Tube type that they support
+ (<tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Type.DBusTube</tp:dbus-ref> and/or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Type.StreamTube</tp:dbus-ref>)
+ even if no client has indicated via
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities">UpdateCapabilities</tp:dbus-ref>
+ that such a tube is supported. They SHOULD also allow clients to offer tubes with any
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.StreamTube">Service</tp:dbus-ref> or
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.DBusTube">ServiceName</tp:dbus-ref>
+ to any contact which supports the corresponding tube capability.</p>
+
+ <tp:rationale>
+ <p>This lowers the barrier to entry for those writing new tube
+ applications, and preserves interoperability with older versions of
+ the Telepathy stack which did not support rich capabilities.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <property name="Parameters" type="a{sv}" tp:type="String_Variant_Map"
+ access="read" tp:name-for-bindings="Parameters">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Each tube has a dictionary of arbitrary parameters. Parameters are
+ commonly used to bootstrap legacy protocols where you can't
+ negotiate parameters in-band. The allowable keys,
+ types and values are defined by the service, but connection managers
+ must support the value being a string (D-Bus type <tt>'s'</tt>),
+ array of bytes (D-Bus type <tt>'ay'</tt>), unsigned integer (D-Bus
+ type <tt>'u'</tt>), integer (D-Bus type <tt>'i'</tt>) and boolean
+ (D-Bus type <tt>'b'</tt>).</p>
+
+ <p>When the tube is offered, the parameters are transmitted with the
+ offer and appear as a property of the incoming tube for other
+ participants.</p>
+
+ <p>For example, a stream tube for <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.StreamTube">Service</tp:dbus-ref>
+ <tt>"smb"</tt> (<cite>Server Message Block over TCP/IP</cite>) might
+ use the following properties, as defined in <a
+ href="http://www.dns-sd.org/ServiceTypes.html">DNS SRV (RFC 2782)
+ Service Types</a>:</p>
+
+ <pre>
+{ 'u': 'some-username',
+ 'p': 'top-secret-password',
+ 'path': '/etc/passwd',
+}</pre>
+
+ <p>When requesting a tube with
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>,
+ this property MUST NOT be included in the request; instead, it is set
+ when <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamTube.Offer</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">DBusTube.Offer</tp:dbus-ref>
+ (as appropriate) is called. Its value is undefined until the tube is
+ offered; once set, its value MUST NOT change.</p>
+
+ <p>When receiving an incoming tube, this property is immutable and so advertised in the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="State" type="u" tp:type="Tube_Channel_State" access="read"
+ tp:name-for-bindings="State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>State of the tube in this channel.</p>
+
+ <p>When requesting a tube with
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>,
+ this property MUST NOT be included in the request.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="Tube_Channel_State" type="u">
+ <tp:enumvalue suffix="Local_Pending" value="0">
+ <tp:docstring>
+ The initiator offered the tube. The tube is waiting to be
+ accepted/closed locally. If the client accepts the tube, the tube's
+ state will be Open.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Remote_Pending" value="1">
+ <tp:docstring>
+ The tube is waiting to be accepted/closed remotely. If the
+ recipient accepts the tube, the tube's state will be Open.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Open" value="2">
+ <tp:docstring>
+ The initiator offered the tube and the recipient accepted it. The
+ tube is open for traffic. The tube's state stays in this state until
+ it is closed.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Not_Offered" value="3">
+ <tp:docstring>
+ The tube channel has been requested but the tube is not yet offered.
+ The client should offer the tube to the recipient and the tube's
+ state will be Remote_Pending. The method used to offer the tube
+ depends on the tube type.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <signal name="TubeChannelStateChanged"
+ tp:name-for-bindings="Tube_Channel_State_Changed">
+ <tp:docstring>
+ Emitted when the state of the tube channel changes. Valid state
+ transitions are documented with <tp:type>Tube_Channel_State</tp:type>.
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="Tube_Channel_State">
+ <tp:docstring>
+ The new state of the tube.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="Socket_Address_Type" type="u">
+ <tp:enumvalue suffix="Unix" value="0">
+ <tp:docstring>
+ A Unix socket. The address variant contains a byte-array, signature 'ay',
+ containing the path of the socket.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Abstract_Unix" value="1">
+ <tp:docstring>
+ An abstract Unix socket. The address variant contains a byte-array,
+ signature 'ay', containing the path of the socket including the
+ leading null byte.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="IPv4" value="2">
+ <tp:docstring>
+ An IPv4 socket. The address variant contains a Socket_Address_IPv4,
+ i.e. a structure with signature (sq)
+ in which the string is an IPv4 dotted-quad address literal
+ (and must not be a DNS name), while the 16-bit unsigned integer is
+ the port number.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="IPv6" value="3">
+ <tp:docstring>
+ An IPv6 socket. The address variant contains a Socket_Address_IPv6,
+ i.e. a structure with signature (sq)
+ in which the string is an IPv6 address literal as specified in
+ RFC2373 (and must not be a DNS name), while the 16-bit unsigned
+ integer is the port number.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ </tp:enum>
+
+ <tp:enum name="Socket_Access_Control" type="u"
+ array-name="Socket_Access_Control_List">
+ <tp:enumvalue suffix="Localhost" value="0">
+ <tp:docstring>
+ <p>The IP or Unix socket can be accessed by any local user (e.g.
+ a Unix socket that accepts all local connections, or an IP socket
+ listening on 127.0.0.1 (or ::1) or rejecting connections not from
+ that address). The associated variant must be ignored.</p>
+
+ <p>For a D-Bus tube, this means that the "same user" access
+ control typically provided by default in D-Bus implementations
+ SHOULD be disabled. If the socket is only available to local users
+ (e.g. a Unix socket, an IPv4 socket bound to 127.0.0.1, or an
+ IPv6 socket bound to ::1), the <code>ANONYMOUS</code>
+ authentication mechanism MAY be enabled.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Port" value="1">
+ <tp:docstring>
+ May only be used on IP sockets, and only for Stream tubes.
+ <!-- ... and maybe Datagram tubes, one day... -->
+ The associated variant must contain
+ a struct Socket_Address_IPv4 (or Socket_Address_IPv6)
+ containing the string form of an IP address of the appropriate
+ version, and a port number. The socket can only be accessed if the
+ connecting process has that address and port number; all other
+ connections will be rejected.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Netmask" value="2">
+ <tp:deprecated version="0.17.25">This has never been implemented.
+ If you want to share a service to your whole LAN, Telepathy is
+ not the way to do it.</tp:deprecated>
+ <tp:docstring>
+ May only be used on IP sockets. The associated variant must contain
+ a struct Socket_Netmask_IPv4 (or Socket_Netmask_IPv6) with
+ signature (sy), containing the string form of an
+ IP address of the appropriate version, and a prefix length "n".
+ The socket can only be accessed if the first n bits of the
+ connecting address match the first n bits of the given address.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Credentials" value="3">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The high-level meaning of this access control type is that
+ only the same user (e.g. same numeric Unix uid) is allowed to
+ interact with the tube. Exactly how this is achieved varies by
+ channel type.</p>
+
+ <p>For <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >StreamTube</tp:dbus-ref> channels, this access control type
+ may only be used on UNIX sockets.
+ The connecting process must send a byte when
+ it first connects, which is not considered to be part of the data
+ stream. If the operating system uses sendmsg() with SCM_CREDS or
+ SCM_CREDENTIALS to pass credentials over sockets, the connecting
+ process must do so if possible; if not, it must still send the
+ byte, without any attached credentials. (This mechanism is
+ very similar to the first byte of a D-Bus connection, except that
+ in D-Bus the byte is always zero, whereas in Tubes it can be
+ nonzero.)</p>
+
+ <p>For <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type"
+ >DBusTube</tp:dbus-ref> channels, this access control type
+ may be used on any type of socket, and there is no extra byte
+ added by Telepathy at the beginning of the stream: all bytes in
+ the stream are part of the D-Bus tube connection. The connecting
+ process should prove its identity via any of the SASL
+ authentication mechanisms usually used for D-Bus (in typical
+ D-Bus implementations this involves either sending and receiving
+ credentials as above, or demonstrating the ability to write to a
+ file in the user's home directory).</p>
+
+ <p>In either case, the listening process will disconnect the
+ connection unless it can determine by OS-specific means that
+ the connecting process has the same user ID as the listening
+ process.</p>
+
+ <p>In either tube type, the associated variant must be ignored.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ </interface>
+
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Request.xml b/spec/spec/Channel_Request.xml
new file mode 100644
index 000000000..dd10049e1
--- /dev/null
+++ b/spec/spec/Channel_Request.xml
@@ -0,0 +1,345 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Request"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008–2011 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008–2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.ChannelRequest">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel request is an object in the <tp:dbus-ref
+ namespace='ofdT'>ChannelDispatcher</tp:dbus-ref> representing
+ an ongoing request for some channels to be created or found. They are
+ created by methods such as <tp:dbus-ref
+ namespace='ofdT.ChannelDispatcher'>CreateChannel</tp:dbus-ref>. There
+ can be any number of ChannelRequest objects at the same time.</p>
+
+ <p>Its well-known bus name is the same as that of the ChannelDispatcher,
+ <code>"org.freedesktop.Telepathy.ChannelDispatcher"</code>.</p>
+
+ <tp:rationale>
+ <p>See
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelDispatcher.CreateChannel</tp:dbus-ref>
+ for rationale for ChannelRequest being a separate object.</p>
+ </tp:rationale>
+
+ <p>A channel request can be cancelled by any client (not just the one
+ that requested it). This means that the ChannelDispatcher will
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ the resulting channel, or refrain from requesting it at all, rather
+ than dispatching it to a handler.</p>
+ </tp:docstring>
+
+ <property name="Account" tp:name-for-bindings="Account"
+ type="o" access="read">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ on which this request was made. This property cannot change.
+ </tp:docstring>
+ </property>
+
+ <property name="UserActionTime" tp:name-for-bindings="User_Action_Time"
+ type="x" tp:type="User_Action_Timestamp" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which user action occurred, or 0 if this channel
+ request is for some reason not involving user action.</p>
+
+ <p>This property is set when the channel request is created,
+ and can never change.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="PreferredHandler" tp:name-for-bindings="Preferred_Handler"
+ type="s" tp:type="DBus_Well_Known_Name" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Either the well-known bus name (starting with
+ <code>org.freedesktop.Telepathy.Client.</code>)
+ of the preferred handler for this
+ channel, or an empty string to indicate that any handler would be
+ acceptable.</p>
+
+ <p>This property is set when the channel request is created,
+ and can never change.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Requests" tp:name-for-bindings="Requests" type="aa{sv}"
+ tp:type="Qualified_Property_Value_Map[]"
+ access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of dictionaries containing desirable properties for
+ the channel or channels to be created.</p>
+
+ <tp:rationale>
+ <p>This is an array so that we could add a CreateChannels method in
+ future without redefining the API of ChannelRequest.</p>
+ </tp:rationale>
+
+ <p>This property is set when the channel request is created,
+ and can never change.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read" tp:type="DBus_Interface[]">
+ <tp:docstring>
+ A list of the extra interfaces provided by this channel request.
+ This property cannot change.
+ </tp:docstring>
+ </property>
+
+ <method name="Proceed" tp:name-for-bindings="Proceed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Proceed with the channel request.</p>
+
+ <tp:rationale>
+ <p>The client that created this object calls this method
+ when it has connected signal handlers for
+ <tp:member-ref>Succeeded</tp:member-ref> and
+ <tp:member-ref>Failed</tp:member-ref>.</p>
+ </tp:rationale>
+
+ <p>Clients other than the client which created the ChannelRequest
+ MUST NOT call this method.</p>
+
+ <p>This method SHOULD return immediately; on success, the request
+ might still fail, but this will be indicated asynchronously
+ by the <tp:member-ref>Failed</tp:member-ref> signal.</p>
+
+ <p>Proceed cannot fail, unless clients have got the life-cycle
+ of a ChannelRequest seriously wrong (e.g. a client calls this
+ method twice, or a client that did not create the ChannelRequest
+ calls this method). If it fails, clients SHOULD assume that the
+ whole ChannelRequest has become useless.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This method has already been called, so it is no longer
+ available. Stop calling it.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Cancel" tp:name-for-bindings="Cancel">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Cancel the channel request. The precise effect depends on the
+ current progress of the request.</p>
+
+ <p>If the connection manager has not already been asked to create
+ a channel, then <tp:member-ref>Failed</tp:member-ref> is emitted
+ immediately, and the channel request is removed.</p>
+
+ <p>If the connection manager has already been asked to create a
+ channel but has not produced one yet (e.g. if <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ has been called, but has not yet returned), then the
+ ChannelDispatcher will remember that the request has been cancelled.
+ When the channel appears, it will be closed (if it was newly
+ created and can be closed), and will not be dispatched to a
+ handler.</p>
+
+ <p>If the connection manager has already returned a channel, but the
+ channel has not yet been dispatched to a handler
+ then the channel dispatcher will not dispatch that
+ channel to a handler. If the channel was newly created for this
+ request, the channel dispatcher will close it with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>;
+ otherwise, the channel dispatcher will ignore it. In either case,
+ <tp:member-ref>Failed</tp:member-ref> will be emitted when processing
+ has been completed.</p>
+
+ <p>If <tp:member-ref>Failed</tp:member-ref> is emitted in response to
+ this method, the error SHOULD be
+ <code>org.freedesktop.Telepathy.Error.Cancelled</code>.</p>
+
+ <p>If the channel has already been dispatched to a handler, then
+ it's too late to call this method, and the channel request will
+ no longer exist.</p>
+ </tp:docstring>
+ </method>
+
+ <signal name="Failed" tp:name-for-bindings="Failed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel request has failed. It is no longer present,
+ and further methods must not be called on it.</p>
+ </tp:docstring>
+
+ <arg name="Error" type="s" tp:type="DBus_Error_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of a D-Bus error. This can come from various sources,
+ including the error raised by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>,
+ or an error generated
+ to represent failure to establish the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Message" type="s">
+ <tp:docstring>
+ If the first argument of the D-Bus error message was a string,
+ that string. Otherwise, an empty string.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="Succeeded" tp:name-for-bindings="Succeeded">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel request has succeeded. It is no longer present,
+ and further methods must not be called on it.</p>
+ </tp:docstring>
+ </signal>
+
+ <property name="Hints" tp:name-for-bindings="Hints"
+ type="a{sv}" access="read">
+ <tp:added version="0.21.5"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary of metadata provided by the channel
+ requester, which the handler and other clients MAY choose to
+ interpret. Clients MAY
+ choose to use platform-specific keys for their own purposes, but MUST
+ ignore unknown keys and MUST cope with expected keys being
+ missing. Clients SHOULD namespace hint names by having them
+ start with a reversed domain name, in the same way as D-Bus
+ interface names.</p>
+
+ <tp:rationale>This property might be used to pass a contact ID for a
+ telephone number shared between two contacts from the address book to
+ the call UI, so that if you try to call “Mum”, the call UI knows this
+ rather than having to guess or show “Calling Mum or Dad”. The format
+ of these contact IDs would be platform-specific, so we leave the
+ definition of the dictionary entry up to the platform in question.
+ But third-party channel requesters might not include the contact ID,
+ so the call UI has to be able to deal with it not being
+ there.</tp:rationale>
+
+ <p>The channel dispatcher does not currently interpret any of these
+ hints: they are solely for communication between cooperating
+ clients. If hints that do affect the channel dispatcher are added in
+ future, their names will start with an appropriate reversed domain
+ name (e.g. <code>org.freedesktop.Telepathy</code> for hints defined
+ by this specification, or an appropriate vendor name for third-party
+ plugins).</p>
+
+ <p>This property may be set when the channel request is created, and
+ can never change. Since it is immutable, it SHOULD be included in the
+ dictionary of properties passed to <tp:dbus-ref
+ namespace="ofdT.Client.Interface.Requests">AddRequest</tp:dbus-ref>
+ by the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatcher</tp:dbus-ref>.</p>
+ <p>The following standardised hints are defined:</p>
+
+ <dl>
+ <dt>org.freedesktop.Telepathy.ChannelRequest.DelegateToPreferredHandler - b</dt>
+ <dd>If present and True the client currently handling the channel
+ SHOULD pass the channel to the
+ <tp:member-ref>PreferredHandler</tp:member-ref> using
+ <tp:dbus-ref namespace="ofdT.ChannelDispatcher">DelegateChannels</tp:dbus-ref>.
+
+ <tp:rationale>
+ This hint allows the user to request a channel in their
+ preferred client in a situation where there are two chat
+ handlers (for example: requesting a channel in Empathy which is
+ currently being handled by gnome-shell).
+ </tp:rationale>
+
+ If the channel is currently unhandled, clients SHOULD ignore this
+ hint.
+
+ <tp:rationale>
+ It is assumed that Mission Control will correctly delegate an
+ unhandled channel to the preferred Handler. This allows
+ requesting clients to always include this hint in their channel
+ request.
+ </tp:rationale>
+
+ The Handler should check each
+ <tp:dbus-ref namespace="ofdT">ChannelRequest</tp:dbus-ref>
+ of the Requests_Satisfied parameter of
+ <tp:dbus-ref namespace="ofdT.Client.Handler">HandleChannels</tp:dbus-ref>
+ for the hint. The first request containing the hint SHOULD be used
+ and all further hints SHOULD be ignored.
+
+ <tp:rationale>
+ This covers the very unlikely case where
+ <tp:dbus-ref namespace="ofdT.Client.Handler">HandleChannels</tp:dbus-ref>
+ satisfies two separate requests which have different
+ <tp:member-ref>PreferredHandler</tp:member-ref>s.
+ </tp:rationale>
+ </dd>
+ </dl>
+
+ </tp:docstring>
+ </property>
+
+ <signal name="SucceededWithChannel" tp:name-for-bindings="Succeeded_With_Channel">
+ <tp:added version="0.21.5"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Variant of the <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">Succeeded</tp:dbus-ref> signal
+ allowing to get the channel which has been created.</p>
+
+ <p>This signal MUST be emitted if the
+ <tp:dbus-ref namespace="ofdT">ChannelDispatcher</tp:dbus-ref>'s
+ <tp:dbus-ref
+ namespace="ofdT.ChannelDispatcher">SupportsRequestHints</tp:dbus-ref>
+ property is true. If supported, it MUST be emitted before
+ the <tp:member-ref>Succeeded</tp:member-ref> signal.</p>
+ </tp:docstring>
+
+ <arg name="Connection" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The Connection owning the channel.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Connection_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A subset of the Connection's properties, currently unused.
+ This parameter may be used in future.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channel" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The channel which has been created.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channel_Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same immutable properties of the Channel that would appear
+ in a <tp:dbus-ref namespace="ofdT.Connection.Interface.Requests"
+ >NewChannels</tp:dbus-ref> signal.</p>
+ </tp:docstring>
+ </arg>
+
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Call.xml b/spec/spec/Channel_Type_Call.xml
new file mode 100644
index 000000000..0ea1319c6
--- /dev/null
+++ b/spec/spec/Channel_Type_Call.xml
@@ -0,0 +1,1583 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Call" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2009-2010 Nokia Corporation</tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.Call1"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.0">(draft 1)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires
+ interface="org.freedesktop.Telepathy.Call1.Interface.Mute"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for making audio and video calls. Call
+ channels supersede the old <tp:dbus-ref
+ namespace="ofdT.Channel.Type">StreamedMedia</tp:dbus-ref>
+ channel type. Call channels are much more flexible than its
+ predecessor and allow more than two participants.</p>
+
+ <p>Handlers are advised against executing all the media
+ signalling, codec and candidate negotiation themselves but
+ instead use a helper library such as <a
+ href="http://telepathy.freedesktop.org/doc/telepathy-farstream/">telepathy-farstream</a>
+ which when given a new Call channel will set up the
+ transports and codecs and create GStreamer pads which
+ can be added to the handler UI. This is useful as it means
+ the handler does not have to worry how exactly the
+ connection between the call participants is being made.</p>
+
+ <p>The <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandle</tp:dbus-ref> and
+ <tp:dbus-ref namespace="ofdT.Channel">TargetID</tp:dbus-ref>
+ properties in a Call channel refer to the contact that the
+ user initially called, or which contact initially called the
+ user. Even in a conference call, where there are multiple
+ contacts in the call, these properties refer to the
+ initial contact, who might have left the conference since
+ then. As a result, handlers should not rely on these
+ properties.</p>
+
+ <h4>Contents</h4>
+
+ <p><tp:dbus-ref namespace="ofdT.Call1">Content</tp:dbus-ref>
+ objects represent the actual media that forms the Call (for
+ example an audio content and a video content). Calls always
+ have one or more Content objects associated with them. As a
+ result, a new Call channel request MUST have either
+ <tp:member-ref>InitialAudio</tp:member-ref>=True, or
+ <tp:member-ref>InitialVideo</tp:member-ref>=True, or both,
+ as the Requestable Channel Classes will document.</p>
+
+ <p><tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref> objects have
+ one or more stream associated with them. More information on
+ these streams and how to maniuplate them can be found on the
+ <tp:dbus-ref namespace="ofdT.Call1">Content</tp:dbus-ref>
+ interface page.</p>
+
+ <h4>Outgoing calls</h4>
+
+ <p>To make an audio-only call to a contact <tt>foo@example.com</tt>
+ handlers should call:</p>
+
+ <blockquote>
+ <pre>
+<tp:dbus-ref namespace="ofdT.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>({
+ ...<tp:dbus-ref namespace="ofdT.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref>: Contact,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetID</tp:dbus-ref>: 'foo@example.com',
+ ...<tp:member-ref>InitialAudio</tp:member-ref>: True,
+})</pre></blockquote>
+
+ <p>As always, <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandle</tp:dbus-ref> may be used
+ in place of
+ <tp:dbus-ref namespace="ofdT.Channel">TargetID</tp:dbus-ref>
+ if the contact's handle is already known. To make an audio
+ and video call, the handler should also specify
+ <tp:member-ref>InitialVideo</tp:member-ref> The
+ connection manager SHOULD return a channel whose immutable
+ properties contain the local user as the <tp:dbus-ref
+ namespace="ofdT.Channel">InitiatorHandle</tp:dbus-ref>, the
+ remote contact as the <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref namespace="ofdT.Channel">Requested</tp:dbus-ref> =
+ <code>True</code> (indicating the call is outgoing).</p>
+
+ <p>After a new Call channel is requested, the
+ <tp:member-ref>CallState</tp:member-ref> property will be
+ <tp:value-ref type="Call_State">Pending_Initiator</tp:value-ref>. As the local
+ user is the initiator, the call must be accepted by the handler
+ by calling the <tp:member-ref>Accept</tp:member-ref> method.
+ At this point, <tp:member-ref>CallState</tp:member-ref> changes
+ to <tp:value-ref type="Call_State">Initialising</tp:value-ref>, which signifies
+ that the call is waiting for the network to do
+ something. When the CM has information indicating that the remote contact has been
+ notified about the call (or immediately if the network is known not to convey such
+ information) it should also change to
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>. All changes to
+ the <tp:member-ref>CallState</tp:member-ref> property are signalled using
+ the <tp:member-ref>CallStateChanged</tp:member-ref> signal.</p>
+
+ <p>When the call is accepted by the remote contact, the
+ <tp:member-ref>CallStateChanged</tp:member-ref> signal fires
+ again to show that <tp:member-ref>CallState</tp:member-ref> =
+ <tp:value-ref type="Call_State">Accepted</tp:value-ref>.</p>
+
+ <p>At this point <a
+ href="http://telepathy.freedesktop.org/doc/telepathy-farstream/">telepathy-farstream</a>
+ will signal that a pad is available for the handler to show
+ in the user interface. Once media is correctly flowing in both
+ directions, the state will change to
+ <tp:value-ref type="Call_State">Active</tp:value-ref>, to inform the user that they
+ have a correctly working call there is nothing amiss.</p>
+
+ <h5>Missed calls</h5>
+
+ <p>If the remote contact does not accept the call in time, then
+ the call can be terminated by the server. Note that this only
+ happens in some protocols. Most XMPP clients, for example, do
+ not do this and rely on the call initiator terminating the call.
+ A missed call is shown in a Call channel by the
+ <tp:member-ref>CallState</tp:member-ref> property changing to
+ <tp:value-ref type="Call_State">Ended</tp:value-ref>, and the
+ <tp:member-ref>CallStateReason</tp:member-ref> property changing
+ to (remote contact,
+ <tp:value-ref type="Call_State_Change_Reason">No_Answer</tp:value-ref>, "").</p>
+
+ <h5>Rejected calls</h5>
+
+ <p>If the remote contact decides he or she does not feel like
+ talking to the local user, he or she can reject his or her
+ incoming call. This will be shown in the Call channel by
+ <tp:member-ref>CallState</tp:member-ref> changing to
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> and the
+ <tp:member-ref>CallStateReason</tp:member-ref> property
+ changing to (remote contact,
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>,
+ "org.freedesktop.Telepathy.Error.Rejected").</p>
+
+ <h4>Incoming calls</h4>
+
+ <p>When an incoming call occurs, something like the following
+ <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal will occur:</p>
+
+ <blockquote>
+ <pre>
+<tp:dbus-ref namespace="ofdT.Connection.Interface.Requests">NewChannels</tp:dbus-ref>([
+ /org/freedesktop/Telepathy/Connection/foo/bar/foo_40bar_2ecom/CallChannel,
+ {
+ ...<tp:dbus-ref namespace="ofdT.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref>: Contact,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetID</tp:dbus-ref>: 'foo@example.com',
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetHandle</tp:dbus-ref>: 42,
+ ...<tp:dbus-ref namespace="ofdT.Channel">Requested</tp:dbus-ref>: False,
+ ...<tp:member-ref>InitialAudio</tp:member-ref>: True,
+ ...<tp:member-ref>InitialVideo</tp:member-ref>: True,
+ ...<tp:member-ref>InitialAudioName</tp:member-ref>: "audio",
+ ...<tp:member-ref>InitialVideoName</tp:member-ref>: "video",
+ ...<tp:member-ref>MutableContents</tp:member-ref>: True,
+ }])</pre></blockquote>
+
+ <p>The <tp:member-ref>InitialAudio</tp:member-ref> and
+ <tp:member-ref>InitialVideo</tp:member-ref> properties show that
+ the call has been started with two contents: one for audio
+ streaming and one for video streaming. The
+ <tp:member-ref>InitialAudioName</tp:member-ref> and
+ <tp:member-ref>InitialVideoName</tp:member-ref> properties also
+ show that the aforementioned audio and video contents have names
+ "audio" and "video".</p>
+
+ <p>Once the handler has notified the local user that there is an
+ incoming call waiting for acceptance, the handler should call
+ <tp:member-ref>SetRinging</tp:member-ref> to let the CM know.
+ The new channel should also be given to telepathy-farstream to
+ work out how the two participants will connect together.
+ telepathy-farstream will call the appropriate methods on the call's
+ <tp:dbus-ref namespace="ofdT.Call1">Content</tp:dbus-ref>s
+ to negotiate codecs and transports.</p>
+
+ <p>To pick up the call, the handler should call
+ <tp:member-ref>Accept</tp:member-ref>. The
+ <tp:member-ref>CallState</tp:member-ref> property changes to
+ <tp:value-ref type="Call_State">Accepted</tp:value-ref> and once media is
+ being transferred, telepathy-farstream will notify the
+ handler of a new pad to be shown to the local user in the
+ UI. Once media is correctly flowing in both directions, the state will
+ change to <tp:value-ref type="Call_State">Active</tp:value-ref>, to inform the user
+ that they have a correctly working call there is nothing amiss.</p>
+
+ <p>To reject the call, the handler should call the
+ <tp:member-ref>Hangup</tp:member-ref> method. The
+ <tp:member-ref>CallState</tp:member-ref> property will change to
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> and the
+ <tp:member-ref>CallStateReason</tp:member-ref> property will
+ change to (self handle,
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>,
+ "org.freedesktop.Telepathy.Error.Rejected").</p>
+
+ <h4>Ongoing calls</h4>
+
+ <h5>Adding and removing contents</h5>
+
+ <p>When a call is open, new contents can be added as long as the
+ CM supports it. The
+ <tp:member-ref>MutableContents</tp:member-ref> property will let
+ the handler know whether further contents can be added or
+ existing contents removed. An example of this is starting a
+ voice call between a contact and then adding a video content.
+ To do this, the should call
+ <tp:member-ref>AddContent</tp:member-ref> like this:</p>
+
+ <blockquote>
+ <pre><tp:member-ref>AddContent</tp:member-ref>("video",
+ <tp:value-ref type="Media_Stream_Type">Video</tp:value-ref>)</pre>
+ </blockquote>
+
+ <p>Assuming no errors, the new video content will be added to
+ the call. telepathy-farstream will pick up the new content and
+ perform the transport and codec negotiation automatically.
+ telpathy-farstream will signal when the video is ready to
+ show in the handler's user interface.</p>
+
+ <p>A similar method is used for removing contents from a call,
+ except that the <tp:dbus-ref
+ namespace="ofdT.Call1.Content">Remove</tp:dbus-ref> method
+ is on the <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref> object.</p>
+
+ <h5>Ending the call</h5>
+
+ <p>To end the call, the handler should call the
+ <tp:member-ref>Hangup</tp:member-ref> method. The
+ <tp:member-ref>CallState</tp:member-ref> property will change to
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> and
+ <tp:member-ref>CallStateReason</tp:member-ref> will change
+ to (self handle,
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>,
+ "org.freedesktop.Telepathy.Error.Cancelled").</p>
+
+ <p>If the other participant hangs up first then the
+ <tp:member-ref>CallState</tp:member-ref> property will change to
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> and
+ <tp:member-ref>CallStateReason</tp:member-ref> will change
+ to (remote contact,
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>,
+ "org.freedesktop.Telepathy.Error.Terminated").</p>
+
+ <h4>Multi-party calls</h4>
+
+ <h4>Requestable channel classes</h4>
+
+ <p>The <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Requests">RequestableChannelClasses</tp:dbus-ref>
+ for <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref> channels
+ can be:</p>
+
+ <blockquote>
+ <pre>
+[( Fixed = { ...<tp:dbus-ref namespace="ofdT.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref>: Contact,
+ ...<tp:member-ref>InitialVideo</tp:member-ref>: True
+ },
+ Allowed = [ ...<tp:member-ref>InitialVideoName</tp:member-ref>,
+ ...<tp:member-ref>InitialAudio</tp:member-ref>,
+ ...<tp:member-ref>InitialAudioName</tp:member-ref>
+ ]
+),
+( Fixed = { ...<tp:dbus-ref namespace="ofdT.Channel">ChannelType</tp:dbus-ref>: ...<tp:dbus-ref namespace="ofdT.Channel.Type">Call1</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref>: Contact,
+ ...<tp:member-ref>InitialAudio</tp:member-ref>: True
+ },
+ Allowed = [ ...<tp:member-ref>InitialAudioName</tp:member-ref>,
+ ...<tp:member-ref>InitialVideo</tp:member-ref>,
+ ...<tp:member-ref>InitialVideoName</tp:member-ref>
+ ]
+)]</pre></blockquote>
+
+ <p>Clients aren't allowed to make outgoing calls that have
+ neither initial audio nor initial video. Clearly, CMs
+ which don't support video should leave out the first class and
+ omit <tp:member-ref>InitialVideo</tp:member-ref> from the second
+ class, and vice versa for CMs without audio support.</p>
+
+ <p>Handlers should not close <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref> channels
+ without first calling <tp:member-ref>Hangup</tp:member-ref> on
+ the channel. If a Call handler crashes, the <tp:dbus-ref
+ namespace="ofdT">ChannelDispatcher</tp:dbus-ref> will call
+ <tp:dbus-ref namespace="ofdT.Channel">Close</tp:dbus-ref> on the
+ channel which SHOULD also imply a call to
+ <tp:member-ref>Hangup</tp:member-ref>(<tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref>,
+ "org.freedesktop.Telepathy.Error.Terminated", "") before
+ actually closing the channel.</p>
+
+ </tp:docstring>
+
+ <method name="SetRinging" tp:name-for-bindings="Set_Ringing">
+ <tp:changed version="0.21.2">renamed from Ringing</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Indicate that the local user has been alerted about the incoming
+ call.</p>
+
+ <p>This method is only useful if the
+ channel's <tp:dbus-ref namespace="ofdT.Channel">Requested</tp:dbus-ref>
+ property is False, and
+ the <tp:member-ref>CallState</tp:member-ref> is
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref> (an incoming
+ call is ready and waiting for the user to be notified). Calling this method
+ SHOULD set <tp:member-ref>CallFlags</tp:member-ref>' bit
+ <tp:value-ref type="Call_Flags">Locally_Ringing</tp:value-ref>, and notify the
+ remote contact that the local user has been alerted (if the
+ protocol supports this); repeated calls to this method
+ SHOULD succeed, but have no further effect.</p>
+
+ <p>In all other states, this method SHOULD fail with the error
+ NotAvailable.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The call was <tp:dbus-ref namespace="ofdT.Channel"
+ >Requested</tp:dbus-ref>, so ringing does not make sense.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The call is no longer in state
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="SetQueued" tp:name-for-bindings="Set_Queued">
+ <tp:changed version="0.21.2">renamed from Ringing</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Notifies the CM that the local user is already in a call, so this
+ call has been put in a call-waiting style queue.</p>
+
+ <p>This method is only useful if the
+ channel's <tp:dbus-ref namespace="ofdT.Channel">Requested</tp:dbus-ref>
+ property is False, and
+ the <tp:member-ref>CallState</tp:member-ref> is
+ <tp:value-ref type="Call_State">Initialising</tp:value-ref> or
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>. Calling this method
+ SHOULD set <tp:member-ref>CallFlags</tp:member-ref>' bit
+ <tp:value-ref type="Call_Flags">Locally_Queued</tp:value-ref>, and notify the
+ remote contact that the call is in a queue (if the
+ protocol supports this); repeated calls to this method
+ SHOULD succeed, but have no further effect.</p>
+
+ <p>Locally_Queued is a little like Locally_Held, but applies to calls that have not
+ been Accepted (the Locally_Queued flag should be unset by the CM when Accept
+ is called). It should also be set in response to the state of the
+ world, rather than in response to user action.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The call was <tp:dbus-ref namespace="ofdT.Channel"
+ >Requested</tp:dbus-ref>, so ringing does not make sense.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The call is no longer in state
+ <tp:value-ref type="Call_State">Initialising</tp:value-ref> or _Ringing.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Accept" tp:name-for-bindings="Accept">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>For incoming calls in state
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>, accept the incoming call.
+ This changes the <tp:member-ref>CallState</tp:member-ref> to
+ <tp:value-ref type="Call_State">Accepted</tp:value-ref>.</p>
+
+ <p>For outgoing calls in state
+ <tp:value-ref type="Call_State">Pending_Initiator</tp:value-ref>, actually
+ call the remote contact; this changes the
+ <tp:member-ref>CallState</tp:member-ref> to
+ <tp:value-ref type="Call_State">Initialising</tp:value-ref>.</p>
+
+ <p>Otherwise, this method SHOULD fail with the error NotAvailable.</p>
+
+ <p>This method should be called exactly once per Call, by whatever
+ client (user interface) is handling the channel.</p>
+
+ <p>When this method is called, for each <tp:dbus-ref
+ namespace="ofdT.Call1" >Content</tp:dbus-ref> whose
+ <tp:dbus-ref namespace="ofdT.Call1.Content"
+ >Disposition</tp:dbus-ref> is
+ <tp:value-ref type="Call_Content_Disposition">Initial</tp:value-ref>, any
+ streams where the <tp:dbus-ref
+ namespace="ofdT.Call1.Stream">LocalSendingState</tp:dbus-ref>
+ is <tp:value-ref type="Sending_State">Pending_Send</tp:value-ref> will be
+ moved to <tp:value-ref type="Sending_State">Sending</tp:value-ref> as if
+ <tp:dbus-ref namespace="ofdT.Call1.Stream"
+ >SetSending</tp:dbus-ref>(True) had been called.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The call is not in one of the states where this method makes sense.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Hangup" tp:name-for-bindings="Hangup">
+ <tp:docstring>
+ Request that the call is ended. All contents will be removed
+ from the Call so that the
+ <tp:member-ref>Contents</tp:member-ref> property will be the
+ empty list.
+ </tp:docstring>
+
+ <arg direction="in" name="Reason"
+ type="u" tp:type="Call_State_Change_Reason">
+ <tp:docstring>
+ A generic hangup reason.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Detailed_Hangup_Reason"
+ type="s" tp:type="DBus_Error_Name">
+ <tp:docstring>
+ A more specific reason for the call hangup, if one is available, or
+ an empty string otherwise.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Message" type="s">
+ <tp:docstring>
+ A human-readable message to be sent to the remote contact(s).
+
+ <tp:rationale>
+ XMPP Jingle allows calls to be terminated with a human-readable
+ message.
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The call has already been ended.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AddContent" tp:name-for-bindings="Add_Content">
+ <tp:docstring>
+ Request that a new <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref> of type
+ Content_Type is added to the Call1. Handlers should check the
+ value of the <tp:member-ref>MutableContents</tp:member-ref>
+ property before trying to add another content as it might not
+ be allowed.
+ </tp:docstring>
+ <arg direction="in" name="Content_Name" type="s">
+ <tp:docstring>
+ <p>The suggested name of the content to add.</p>
+
+ <tp:rationale>
+ The content name property should be meaningful, so should
+ be given a name which is significant to the user. The name
+ could be a localized "audio", "video" or perhaps include
+ some string identifying the source, such as a webcam
+ identifier.
+ </tp:rationale>
+
+ <p>If there is already a content with the same name as this
+ property then a sensible suffix should be added. For example,
+ if this argument is "audio" but a content of the same name
+ already exists, a sensible suffix such as " (1)" is appended
+ to name the new content "audio (1)". A further content with the
+ name "audio" would then be named "audio (2)".</p>
+
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Content_Type" type="u"
+ tp:type="Media_Stream_Type">
+ <tp:docstring>
+ The media stream type of the content to be added to the
+ call.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Content" type="o">
+ <tp:docstring>
+ Path to the newly-created <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Call1.Content</tp:dbus-ref> object.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The media stream type given is invalid.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The media stream type requested is not implemented by the
+ CM.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Media.UnsupportedType">
+ <tp:docstring>
+ The media stream type requested is not supported by either the
+ local or remote side.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable">
+ <tp:docstring>
+ The content type requested cannot be added to this
+ call. Examples of why this might be the case include
+ because a second video stream cannot be added, or a
+ content cannot be added when the content set isn't
+ mutable.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="ContentAdded"
+ tp:name-for-bindings="Content_Added">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a new <tp:dbus-ref namespace="ofdT.Call1"
+ >Content</tp:dbus-ref> is added to the call.</p>
+ </tp:docstring>
+ <arg name="Content" type="o">
+ <tp:docstring>
+ Path to the newly-created <tp:dbus-ref namespace="ofdT.Call1"
+ >Content</tp:dbus-ref> object.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="ContentRemoved" tp:name-for-bindings="Content_Removed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a <tp:dbus-ref namespace="ofdT.Call1"
+ >Content</tp:dbus-ref> is removed from the call.</p>
+ </tp:docstring>
+ <arg name="Content" type="o">
+ <tp:docstring>
+ The <tp:dbus-ref namespace="ofdT.Call1"
+ >Content</tp:dbus-ref> which was removed.
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ Why the content was removed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Contents" type="ao" access="read"
+ tp:name-for-bindings="Contents">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The list of <tp:dbus-ref
+ namespace="ofdT.Call1">Content</tp:dbus-ref> objects that
+ are part of this call. Change notification is via the
+ <tp:member-ref>ContentAdded</tp:member-ref> and
+ <tp:member-ref>ContentRemoved</tp:member-ref> signals.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum type="u" name="Call_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The state of a call, as a whole.</p>
+
+ <p>The allowed transitions are:</p>
+
+ <ul>
+ <li>Pending_Initiator → Initialising (for outgoing calls,
+ when <tp:member-ref>Accept</tp:member-ref> is called)</li>
+ <li>Initialising → Ringing (for outgoing calls, when
+ the remote client indicates that the user has been notified about
+ the call. If the network is known not to provide feedback about whether
+ the remote side is ringing, then the call should immediately be
+ set to Ringing.</li>
+ <li>Initialising → Ringing (for incoming calls, when e.g. the
+ implementation has been initialised far enough that it is sensible
+ to notify the user about the call (to reduce the probability that
+ the user will pick up the call and have it immediately fail).
+ The UI should then alert the user about the call, and call
+ <tp:member-ref>SetRinging</tp:member-ref>)</li>
+ <li>Ringing → Accepted (for outgoing calls to a contact,
+ when the remote contact accepts the call; for incoming calls, when
+ <tp:member-ref>Accept</tp:member-ref> is called.)</li>
+ <li>Accepted → Active (when the local user successfully
+ joins the call/conference, and media is known to be flowing
+ successfully; also, when temporary connection problems are
+ resolved (See below)). If the network is known not to provide
+ feedback about when the call is properly connected, the call
+ should immediately be set to Active.</li>
+ <li>Active → Accepted (when there are temporary connection problems
+ that the CM is aware of and able to recover from)</li>
+ <li>any state → Ended (when the call is terminated
+ normally, or when an error occurs that the CM is unable to recover
+ from)</li>
+ </ul>
+
+ <p>Clients MAY consider unknown values from this enum to be an
+ error - additional values will not be defined after the Call
+ specification is declared to be stable.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ The call state is not known. This call state MUST NOT appear as a
+ value of the <tp:member-ref>CallState</tp:member-ref> property, but
+ MAY be used by client code to represent calls whose state is as yet
+ unknown.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Pending_Initiator" value="1">
+ <tp:docstring>
+ The initiator of the call hasn't accepted the call yet. This state
+ only makes sense for outgoing calls, where it means that the local
+ user has not yet sent any signalling messages to the remote user(s),
+ and will not do so until <tp:member-ref>Accept</tp:member-ref> is
+ called.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Initialising" value="2">
+ <tp:docstring>
+ Progress has been made in placing the call, but the
+ contact has not been made aware of the call yet. This corresponds to SIP's
+ status code 183 Session Progress, and should be used for the period
+ where the CM is waiting for the streaming implementation to
+ initialise (before sending the initial INVITE or equivalent) and when the
+ outgoing call has reached a gateway or ICE negotiation is pending.
+ UIs should not produce a dialtone or start ringing if the call is in
+ this state.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Ringing" value="3">
+ <tp:docstring>
+ In the outgoing case: at least one called user has been alerted
+ about the call (a SIP 180 (Ringing) packet or equivalent has been
+ received) but none have answered, so the call cannot go to Accepted
+ (use <tp:value-ref type="Call_Member_Flags">Ringing</tp:value-ref> to determine which
+ members have been informed and which haven't, if you care). UIs
+ SHOULD produce a dialtone for outgoing calls in this state.
+
+ In the incoming case, the local user should be informed of the call
+ as soon as the call reaches this state (and
+ <tp:member-ref>SetRinging</tp:member-ref> should be called
+ to inform the CM that this has happened, so that it can relay this
+ fact to the caller using a SIP 180 (Ringing) packet or equivalent).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Accepted" value="4">
+ <tp:docstring>
+ The contact being called has accepted the call, but the call is not
+ in the Active state (The most common reason for this is that the
+ streaming implementation hasn't connected yet).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Active" value="5">
+ <tp:docstring>
+ The contact being called has accepted the call, and discourse between
+ at least two parties should now be possible.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Ended" value="6">
+ <tp:docstring>
+ The call has ended, either via normal termination or an error.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:flags name="Call_Flags" value-prefix="Call_Flag" type="u">
+ <tp:docstring>
+ A set of flags representing additional information than is available
+ in <tp:member-ref>CallState</tp:member-ref>. Many of these flags only make
+ sense in a particular (or may explain why a call is in a specific
+ state).
+ </tp:docstring>
+ <tp:flag suffix="Locally_Held" value="1">
+ <tp:docstring>
+ The call has been put on hold by the local user, e.g. using
+ the <tp:dbus-ref namespace="ofdT.Channel.Interface"
+ >Hold</tp:dbus-ref> interface. This flag SHOULD only be set
+ if there is at least one Content, and all Contents are
+ locally held.
+
+ <tp:rationale>
+ Otherwise, in transient situations where some but not all contents
+ are on hold, UIs would falsely indicate that the call as a whole
+ is on hold, which could lead to the user saying something they'll
+ regret, while under the impression that the other contacts can't
+ hear them!
+
+ This flag exists as a simplified proxy for <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.Hold"
+ >HoldStateChanged</tp:dbus-ref>,
+ to reduce the number of signals that need to be
+ listened to by a simple UI.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Locally_Muted" value="2">
+ <tp:docstring>
+ The call has been muted by the local user, e.g. using the
+ <tp:dbus-ref namespace="ofdT.Call1.Interface"
+ >Mute</tp:dbus-ref> interface. This flag SHOULD only
+ be set if there is at least one Content, and all Contents
+ are locally muted (for the same reason as Locally_Held).
+
+ <tp:rationale>
+ This flag exists to provide a simplified verson of <tp:dbus-ref
+ namespace="ofdT.Call1.Interface.Mute"
+ >MuteStateChanged</tp:dbus-ref>,
+ to reduce the number of signals that need to be
+ listened to by a simple UI.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Locally_Ringing" value="4">
+ <tp:docstring>
+ This flag exists for observability of the
+ <tp:member-ref>SetRinging</tp:member-ref> method (e.g. so that
+ loggers can tell whether the call got as far as alerting the user,
+ or whether something went wrong before then). It should be set when
+ the SetRinging is called, and unset when the call leaves
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Locally_Queued" value="8">
+ <tp:docstring>
+ This flag exists for observability of the
+ <tp:member-ref>SetQueued</tp:member-ref> method. It should be set
+ when the SetQueued is called, and unset when the call leaves
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Forwarded" value="16">
+ <tp:docstring>
+ The initiator of the call originally called a contact other than the
+ current recipient of the call, but the call was then forwarded or
+ diverted. This flag only makes sense on outgoing calls. It SHOULD be
+ set or unset according to informational messages from other
+ contacts.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Clearing" value="32">
+ <tp:docstring>
+ This flag only occurs when the CallState is Ended. The call with
+ this flag set has ended, but not all resources corresponding to the
+ call have been freed yet.
+
+ Depending on the protocol there might be some audible feedback while
+ the clearing flag is set.
+
+ <tp:rationale>
+ In calls following the ITU-T Q.931 standard there is a period of
+ time between the call ending and the underlying channel being
+ completely free for re-use.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ </tp:flags>
+
+ <property name="CallStateDetails"
+ tp:name-for-bindings="Call_State_Details" type="a{sv}" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map used to provide optional extensible details for the
+ <tp:member-ref>CallState</tp:member-ref>,
+ <tp:member-ref>CallFlags</tp:member-ref> and/or
+ <tp:member-ref>CallStateReason</tp:member-ref>.</p>
+
+ <p>Well-known keys and their corresponding value types include:</p>
+
+ <dl>
+ <dt>hangup-message - s</dt>
+ <dd>An optional human-readable message sent when the call was ended,
+ corresponding to the Message argument to the
+ <tp:member-ref>Hangup</tp:member-ref> method. This is only
+ applicable when the call state is <tp:value-ref type="Call_State">Ended</tp:value-ref>.
+ <tp:rationale>
+ XMPP Jingle can send such messages.
+ </tp:rationale>
+ </dd>
+
+ <dt>queue-message - s</dt>
+ <dd>An optional human-readable message sent when the local contact
+ is being held in a queue. This is only applicable when
+ <tp:value-ref type="Call_Flags">Locally_Queued</tp:value-ref> is in the call flags.
+ <tp:rationale>
+ SIP 182 notifications can have human-readable messages attached.
+ </tp:rationale>
+ </dd>
+
+ <dt>debug-message - s</dt>
+ <dd>A message giving further details of any error indicated by the
+ <tp:member-ref>CallStateReason</tp:member-ref>. This will not
+ normally be localized or suitable for display to users, and is only
+ applicable when the call state is
+ <tp:value-ref type="Call_State">Ended</tp:value-ref>.</dd>
+
+ <dt>balance-required - i</dt>
+ <dd>Optionally included when a call cannot be connected because
+ there is <tp:error-ref>InsufficientBalance</tp:error-ref>,
+ indicating what the required balance would be to place this call.
+ The value of this key has the same units and scale as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.Balance">AccountBalance</tp:dbus-ref>.
+ </dd>
+ </dl>
+ </tp:docstring>
+ </property>
+
+ <property name="CallState" type="u" access="read"
+ tp:name-for-bindings="Call_State" tp:type="Call_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The current high-level state of this call. The
+ <tp:member-ref>CallFlags</tp:member-ref> provide additional
+ information, and the <tp:member-ref>CallStateReason</tp:member-ref>
+ and <tp:member-ref>CallStateDetails</tp:member-ref> explain the
+ reason for the current values for those properties.</p>
+
+ <p>Note that when in a conference call, this property is
+ purely to show your state in joining the call. The receiver
+ (or remote contact) in this context is the conference server
+ itself. The property does not change when other call members'
+ states change.</p>
+
+ <p>Clients MAY consider unknown values in this property to be an
+ error.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="CallFlags" type="u" access="read"
+ tp:name-for-bindings="Call_Flags" tp:type="Call_Flags">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Flags representing the status of the call as a whole,
+ providing more specific information than the
+ <tp:member-ref>CallState</tp:member-ref>.</p>
+
+ <p>Clients are expected to ignore unknown flags in this property,
+ without error.</p>
+
+ <p>When an ongoing call is active and not on hold or has any
+ other problems, this property will be 0.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="Call_State_Change_Reason" type="u">
+ <tp:docstring>
+ A simple representation of the reason for a change in the call's
+ state, which may be used by simple clients, or used as a fallback
+ when the DBus_Reason member of a <tp:type>Call_State_Reason</tp:type>
+ struct is not understood.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ We just don't know. Unknown values of this enum SHOULD also be
+ treated like this.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Progress_Made" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Situation normal. Progress has been made in the setup/teardown of
+ the call (and it didn't require any user interaction).
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="User_Requested" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change was requested by the contact indicated by the Actor
+ member of a <tp:type>Call_State_Reason</tp:type> struct.</p>
+
+ <p>If the Actor is the local user, the DBus_Reason SHOULD be the
+ empty string.</p>
+
+ <p>If the Actor is a remote user, the DBus_Reason SHOULD be the empty
+ string if the call was terminated normally, but MAY be a non-empty
+ error name to indicate error-like call termination reasons (call
+ rejected as busy, kicked from a conference by a moderator, etc.).</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Forwarded" value="3">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The call was forwarded. If known, the handle of the contact
+ the call was forwarded to will be indicated by the Actor member
+ of a <tp:type>Call_State_Reason</tp:type> struct.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Rejected" value="4">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>CallState</tp:member-ref> changed from
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref> or
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> (or a content's direction
+ changed) because it was rejected by the remote user.</p>
+ <p>Corresponds to <tp:error-ref>Rejected</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="No_Answer" value="5">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>CallState</tp:member-ref> changed from
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref> or
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> because the initiator
+ ended the call before the receiver accepted it. With an
+ incoming call this state change reason signifies a missed
+ call, or one that was picked up elsewhere before it was
+ picked up here.</p>
+ <p>Corresponds to <tp:error-ref>NoAnswer</tp:error-ref> or
+ <tp:error-ref>PickedUpElsewhere</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Invalid_Contact" value="6">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>CallState</tp:member-ref> changed because one
+ of the addresses does not exist on the network.</p>
+ <p>Corresponds to <tp:error-ref>DoesNotExist</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Permission_Denied" value="7">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>CallState</tp:member-ref> changed because the
+ local user is not authorised.</p>
+ <p>Corresponds to <tp:error-ref>PermissionDenied</tp:error-ref> or
+ <tp:error-ref>InsufficientBalance</tp:error-ref>
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Busy" value="8">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>CallState</tp:member-ref> changed from
+ <tp:value-ref type="Call_State">Ringing</tp:value-ref>
+ <tp:value-ref type="Call_State">Ended</tp:value-ref> because the receiver is busy
+ (e.g. is already engaged in another call, and has not placed the
+ initiator in a call-waiting queue).</p>
+ <p>Corresponds to <tp:error-ref>Busy</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Internal_Error" value="9">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There has been an unexpected error in either the CM or some other
+ local component.</p>
+ <p>Corresponds to <tp:error-ref>Confused</tp:error-ref> or
+ <tp:error-ref>Media.StreamingError</tp:error-ref>
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Service_Error" value="10">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There has been an unexpected error in the server or some other
+ remote component.</p>
+ <p>Corresponds to
+ <tp:error-ref>ServiceConfused</tp:error-ref>
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Network_Error" value="11">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There has been a network error related to the CM or the
+ signalling part of the call (compare and contrast:
+ Streaming_Error).</p>
+ <p>Corresponds to
+ <tp:error-ref>NetworkError</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Media_Error" value="12">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Some aspect of the content is unsupported so has to be
+ removed from the call.</p>
+ <p>Corresponds to <tp:error-ref>Media.UnsupportedType</tp:error-ref>
+ or <tp:error-ref>Media.CodecsIncompatible</tp:error-ref>
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Connectivity_Error" value="13">
+ <tp:docstring>
+ <p>It was not possible for the streaming implementation to connect
+ to any of the users participating in this call or content.</p>
+ <p>Corresponds to <tp:error-ref>ConnectionFailed</tp:error-ref> or
+ <tp:error-ref>ConnectionLost</tp:error-ref></p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Call_State_Reason">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A description of the reason for a change to the
+ <tp:member-ref>CallState</tp:member-ref> and/or
+ <tp:member-ref>CallFlags</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <tp:member type="u" tp:type="Contact_Handle" name="Actor">
+ <tp:docstring>
+ The contact responsible for the change, or 0 if no contact was
+ responsible.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="u" tp:type="Call_State_Change_Reason" name="Reason">
+ <tp:docstring>
+ The reason, chosen from a limited set of possibilities defined by
+ the Telepathy specification. If
+ <tp:value-ref type="Call_State_Change_Reason">User_Requested</tp:value-ref> then
+ the Actor member will dictate whether it was the local user or
+ a remote contact responsible.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="s" tp:type="DBus_Error_Name" name="DBus_Reason">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A specific reason for the change, which may be a D-Bus error in
+ the Telepathy namespace, a D-Bus error in any other namespace
+ (for implementation-specific errors), or the empty string to
+ indicate that the state change was not an error.</p>
+
+ <p>This SHOULD be an empty string for changes to any state other
+ than Ended.</p>
+
+ <p>The errors Cancelled and Terminated SHOULD NOT be used here;
+ an empty string SHOULD be used instead.</p>
+
+ <tp:rationale>
+ <p>Those error names are used to indicate normal call
+ termination by the local user or another user, respectively,
+ in contexts where a D-Bus error name must appear.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="s" name="Message">
+ <tp:docstring>
+ An optional debug message, to expediate debugging the potentially
+ many processes involved in a call. This may be communicated across
+ the network in protocols that support doing so, but it is not
+ essential.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="CallStateReason" tp:name-for-bindings="Call_State_Reason"
+ type="(uuss)" access="read" tp:type="Call_State_Reason">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The reason for the last change to the
+ <tp:member-ref>CallState</tp:member-ref> and/or
+ <tp:member-ref>CallFlags</tp:member-ref>. The
+ <tp:member-ref>CallStateDetails</tp:member-ref> MAY provide additional
+ information.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="CallStateChanged"
+ tp:name-for-bindings="Call_State_Changed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the state of the call as a whole changes.</p>
+
+ <p>This signal is emitted for any change in the properties
+ corresponding to its arguments, even if the other properties
+ referenced remain unchanged.</p>
+ </tp:docstring>
+
+ <arg name="Call_State" type="u" tp:type="Call_State">
+ <tp:docstring>
+ The new value of the <tp:member-ref>CallState</tp:member-ref>
+ property.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Call_Flags" type="u" tp:type="Call_Flags">
+ <tp:docstring>
+ The new value of the <tp:member-ref>CallFlags</tp:member-ref>
+ property.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Call_State_Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ The new value of the <tp:member-ref>CallStateReason</tp:member-ref>
+ property.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Call_State_Details" type="a{sv}">
+ <tp:docstring>
+ The new value of the <tp:member-ref>CallStateDetails</tp:member-ref>
+ property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="HardwareStreaming" tp:name-for-bindings="Hardware_Streaming"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If this property is True, all of the media streaming is done by some
+ mechanism outside the scope of Telepathy.</p>
+
+ <tp:rationale>
+ <p>A connection manager might be intended for a specialized hardware
+ device, which will take care of the audio streaming (e.g.
+ telepathy-yafono, which uses GSM hardware which does the actual
+ audio streaming for the call).</p>
+ </tp:rationale>
+
+ <p>If this is False, the handler is responsible for doing the actual
+ media streaming for at least some contents itself. Those contents
+ will have the <tp:dbus-ref namespace="ofdT.Call1.Content.Interface"
+ >Media</tp:dbus-ref> interface, to communicate the necessary
+ information to a streaming implementation. Connection managers SHOULD
+ operate like this, if possible.</p>
+
+ <tp:rationale>
+ <p>Many connection managers (such as telepathy-gabble) only do the
+ call signalling, and expect the client to do the actual streaming
+ using something like
+ <a href="http://farsight.freedesktop.org/">Farsight</a>, to improve
+ latency and allow better UI integration.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <tp:flags type="u" name="Call_Member_Flags" value-prefix="Call_Member_Flag">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A set of flags representing the status of a remote contact in a
+ call.</p>
+
+ <p>It is protocol- and client-specific whether a particular contact
+ will ever have a particular flag set on them, and Telepathy clients
+ SHOULD NOT assume that a flag will ever be set.</p>
+
+ <tp:rationale>
+ <p>180 Ringing in SIP, and its equivalent in XMPP, are optional
+ informational messages, and implementations are not required
+ to send them. The same applies to the messages used to indicate
+ hold state.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:flag suffix="Ringing" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The remote contact's client has told us that the contact has been
+ alerted about the call but has not responded.</p>
+
+ <tp:rationale>
+ <p>This is a flag per member, not a flag for the call as a whole,
+ because in Muji conference calls, you could invite someone and
+ have their state be "ringing" for a while.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Held" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The call member has put this call on hold.</p>
+
+ <tp:rationale>
+ <p>This is a flag per member, not a flag for the call as a whole,
+ because in conference calls, any member could put the conference
+ on hold.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Muted" value="4">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The call member has muted their participation in this call. Note
+ that many protocols will not signal this flag, so clients should
+ not rely on it being set.</p>
+
+ <tp:rationale>
+ <p>This is a flag per member, not a flag for the call as a whole,
+ because in conference calls, any member could mute their own
+ streams.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Conference_Host" value="8">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ This contact has merged this call into a conference. Note that GSM
+ provides a notification when the remote party merges a call into a
+ conference, but not when it is split out again; thus, this flag can
+ only indicate that the call has been part of a conference at some
+ point. If a GSM connection manager receives a notification that a
+ call has been merged into a conference a second time, it SHOULD
+ represent this by clearing and immediately re-setting this flag on
+ the remote contact.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:mapping name="Call_Member_Map" array-name="Call_Member_Map_List">
+ <tp:docstring>A mapping from handles to their current state in the call.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Handle" name="key"/>
+ <tp:member type="u" tp:type="Call_Member_Flags" name="Flag"/>
+ </tp:mapping>
+
+ <signal name="CallMembersChanged"
+ tp:name-for-bindings="Call_Members_Changed">
+ <tp:docstring>
+ Emitted when the <tp:member-ref>CallMembers</tp:member-ref> property
+ changes in any way, either because contacts have been added to the
+ call, contacts have been removed from the call, or contacts' flags
+ have changed.
+ </tp:docstring>
+
+ <arg name="Flags_Changed" type="a{uu}" tp:type="Call_Member_Map">
+ <tp:docstring>
+ A map from members of the call to their new call member flags,
+ including at least the members who have been added to
+ <tp:member-ref>CallMembers</tp:member-ref>, and the members whose
+ flags have changed.
+ </tp:docstring>
+ </arg>
+ <arg name="Identifiers" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The identifiers of the contacts in the <var>Flags_Changed</var> map.
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ A list of members who have left the call, i.e. keys to be removed
+ from <tp:member-ref>CallMembers</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="(uuss)" tp:type="Call_State_Reason">
+ <tp:docstring>
+ A structured reason for the change.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="CallMembers" tp:name-for-bindings="Call_Members"
+ type="a{uu}" access="read" tp:type="Call_Member_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping from the remote contacts that are part of this call to flags
+ describing their status. This mapping never has the local user's handle
+ as a key.</p>
+
+ <p>When the call ends, this property should be an empty list,
+ and notified with
+ <tp:member-ref>CallMembersChanged</tp:member-ref></p>
+
+ <p>If the Call implements
+ <tp:dbus-ref namespace="ofdT.Channel.Interface"
+ >Group</tp:dbus-ref> and the Group members are
+ channel-specific handles, then this call SHOULD also use
+ channel-specific handles.</p>
+
+ <p>Anonymous members are exposed as channel-specific handles
+ with no owner.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="MemberIdentifiers" type="a{us}" tp:type="Handle_Identifier_Map"
+ access="read" tp:name-for-bindings="Member_Identifiers">
+ <tp:docstring>
+ The string identifiers for handles mentioned in
+ <tp:member-ref>CallMembers</tp:member-ref>, to
+ give clients the minimal information necessary to create contacts
+ without waiting for round-trips.
+ </tp:docstring>
+ </property>
+
+ <property name="InitialTransport" tp:name-for-bindings="Initial_Transport"
+ type="u" tp:type="Stream_Transport_Type" access="read"
+ tp:requestable="yes" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If set on a requested channel, this indicates the transport that
+ should be used for this call. Where not applicable, this property
+ is defined to be <tp:value-ref type="Stream_Transport_Type">Unknown</tp:value-ref>,
+ in particular, on CMs with hardware streaming.</p>
+
+ <tp:rationale>
+ When implementing a voip gateway one wants the outgoing leg of the
+ gatewayed to have the same transport as the incoming leg. This
+ property allows the gateway to request a Call with the right
+ transport from the CM.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialAudio" tp:name-for-bindings="Initial_Audio"
+ type="b" access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If set to True in a channel request that will create a new channel,
+ the connection manager should immediately attempt to establish an
+ audio stream to the remote contact, making it unnecessary for the
+ client to call <tp:dbus-ref
+ namespace="ofdT.Channel.Type.Call1">AddContent</tp:dbus-ref>.</p>
+
+ <p>If this property, or InitialVideo, is passed to EnsureChannel
+ (as opposed to CreateChannel), the connection manager SHOULD ignore
+ these properties when checking whether it can return an existing
+ channel as suitable; these properties only become significant when
+ the connection manager has decided to create a new channel.</p>
+
+ <p>If True on a requested channel, this indicates that the audio
+ stream has already been requested and the client does not need to
+ call RequestStreams, although it MAY still do so.</p>
+
+ <p>If True on an unrequested (incoming) channel, this indicates that
+ the remote contact initially requested an audio stream; this does
+ not imply that that audio stream is still active (as indicated by
+ <tp:dbus-ref namespace="ofdT.Channel.Type.Call1"
+ >Contents</tp:dbus-ref>).</p>
+
+ <p>The name of this new content can be decided by using the
+ <tp:member-ref>InitialAudioName</tp:member-ref> property.</p>
+
+ <p>Connection managers that support the <tp:dbus-ref
+ namespace="ofdT.Connection.Interface">ContactCapabilities</tp:dbus-ref>
+ interface SHOULD represent the capabilities of receiving audio
+ and/or video calls by including a channel class in
+ a contact's capabilities with ChannelType = Call
+ in the fixed properties dictionary, and InitialAudio and/or
+ InitialVideo in the allowed properties list. Clients wishing to
+ discover whether a particular contact is likely to be able to
+ receive audio and/or video calls SHOULD use this information.</p>
+
+ <tp:rationale>
+ <p>Not all clients support video calls, and it would also be
+ possible (although unlikely) to have a client which could only
+ stream video, not audio.</p>
+ </tp:rationale>
+
+ <p>Clients that are willing to receive audio and/or video calls
+ SHOULD include the following among their channel classes if
+ calling <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.ContactCapabilities">UpdateCapabilities</tp:dbus-ref>
+ (clients of a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatcher</tp:dbus-ref>
+ SHOULD instead arrange for the ChannelDispatcher to do this,
+ by including the filters in their <tp:dbus-ref
+ namespace="ofdT.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ properties):</p>
+
+ <ul>
+ <li>{ ChannelType = Call }</li>
+ <li>{ ChannelType = Call, InitialAudio = True }
+ if receiving calls with audio is supported</li>
+ <li>{ ChannelType = Call, InitialVideo = True }
+ if receiving calls with video is supported</li>
+ </ul>
+
+ <tp:rationale>
+ <p>Connection managers for protocols with capability discovery,
+ like XMPP, need this information to advertise the appropriate
+ capabilities for their protocol.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialVideo" tp:name-for-bindings="Initial_Video"
+ type="b" access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same as <tp:member-ref>InitialAudio</tp:member-ref>, but for
+ a video stream. This property is immutable (cannot change).</p>
+
+ <p>In particular, note that if this property is False, this does not
+ imply that an active video stream has not been added, only that no
+ video stream was active at the time the channel appeared.</p>
+
+ <p>This property is the correct way to discover whether connection
+ managers, contacts etc. support video calls; it appears in
+ capabilities structures in the same way as InitialAudio.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialAudioName" tp:name-for-bindings="Initial_Audio_Name"
+ type="s" access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tp:member-ref>InitialAudio</tp:member-ref> is set to
+ True, then this property will name the intial audio content
+ with the value of this property.</p>
+
+ <tp:rationale>
+ <p>Content names are meant to be significant, but if no name
+ can be given to initial audio content, then its name cannot
+ be meaningful or even localized.</p>
+ </tp:rationale>
+
+ <p>If this property is empty or missing from the channel
+ request and InitialAudio is True, then the CM must come up
+ with a sensible for the content, such as "audio".</p>
+
+ <p>If the protocol has no concept of stream names then this
+ property will not show up in the allowed properties list of
+ the Requestable Channel Classes for call channels.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialVideoName" tp:name-for-bindings="Initial_Video_Name"
+ type="s" access="read" tp:immutable="yes" tp:requestable="yes">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same as
+ <tp:member-ref>InitialAudioName</tp:member-ref>, but for a
+ video stream created by setting
+ <tp:member-ref>InitialVideo</tp:member-ref> to True. This
+ property is immutable and so cannot change.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="MutableContents" tp:name-for-bindings="Mutable_Contents"
+ type="b" access="read" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If True, a stream of a different content type can be added
+ after the Channel has been requested </p>
+
+ <p>If this property is missing, clients SHOULD assume that it is False,
+ and thus that the channel's streams cannot be changed once the call
+ has started.</p>
+
+ <p>If this property isn't present in the "allowed" set in any of the
+ Call entries contact capabilities, then user interfaces MAY choose to
+ show a separate "call" option for each class of call.</p>
+
+ <tp:rationale>
+ <p>For example, once an audio-only Google Talk call has started,
+ it is not possible to add a video stream; both audio and video
+ must be requested at the start of the call if video is desired.
+ User interfaces may use this pseudo-capability as a hint to
+ display separate "Audio call" and "Video call" buttons, rather
+ than a single "Call1" button with the option to add and remove
+ video once the call has started for contacts without this flag.
+ </p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <tp:hct name="audio">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This client supports audio calls.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="video">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This client supports video calls.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="gtalk-p2p">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="ofdT.Call1.Stream.Interface.Media">Transport</tp:dbus-ref>
+ property is <tp:value-ref type="Stream_Transport_Type">GTalk_P2P</tp:value-ref>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="ice">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="ofdT.Call1.Stream.Interface.Media">Transport</tp:dbus-ref>
+ property is <tp:value-ref type="Stream_Transport_Type">ICE</tp:value-ref>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="wlm-2009">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="ofdT.Call1.Stream.Interface.Media">Transport</tp:dbus-ref>
+ property is <tp:value-ref type="Stream_Transport_Type">WLM_2009</tp:value-ref>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="shm">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client can implement streaming for streams whose <tp:dbus-ref
+ namespace="ofdT.Call1.Stream.Interface.Media">Transport</tp:dbus-ref>
+ property is <tp:value-ref type="Stream_Transport_Type">SHM</tp:value-ref>.</p>
+ </tp:docstring>
+ </tp:hct>
+
+ <tp:hct name="video/h264" is-family="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The client supports media streaming with H264 (etc.).</p>
+
+ <p>This handler capability token is a one of a family
+ of similar tokens: for any other audio or video codec whose MIME
+ type is audio/<em>subtype</em> or video/<em>subtype</em>, a handler
+ capability token of this form may exist (the subtype MUST appear
+ in lower case in this context). Clients MAY support more
+ codecs than they explicitly advertise support for; clients SHOULD
+ explicitly advertise support for their preferred codec(s), and
+ for codecs like H264 that are, in practice, significant in codec
+ negotiation.</p>
+
+ <tp:rationale>
+ <p>For instance, the XMPP capability used by the Google Video
+ Chat web client to determine whether a client is compatible
+ with it requires support for H264 video, so an XMPP
+ connection manager that supports this version of Jingle should
+ not advertise the Google Video Chat capability unless there
+ is at least one installed client that declares that it supports
+ <code>video/h264</code> on Call channels.</p>
+ </tp:rationale>
+
+ <p>For example, a client could advertise support for audio and video
+ calls using Speex, Theora and H264 by having five handler capability
+ tokens in its <tp:dbus-ref
+ namespace="ofdT.Client.Handler">Capabilities</tp:dbus-ref>
+ property:</p>
+
+ <ul>
+ <li><code>org.freedesktop.Telepathy.Channel.Type.Call1/audio</code></li>
+ <li><code>org.freedesktop.Telepathy.Channel.Type.Call1/audio/speex</code></li>
+ <li><code>org.freedesktop.Telepathy.Channel.Type.Call1/video</code></li>
+ <li><code>org.freedesktop.Telepathy.Channel.Type.Call1/video/theora</code></li>
+ <li><code>org.freedesktop.Telepathy.Channel.Type.Call1/video/h264</code></li>
+ </ul>
+
+ <p>Clients MAY have media signalling abilities without explicitly
+ supporting any particular codec, and connection managers SHOULD
+ support this usage.</p>
+
+ <tp:rationale>
+ <p>This is necessary to support gatewaying between two Telepathy
+ connections, in which case the available codecs might not be
+ known to the gatewaying process.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:hct>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Contact_List.xml b/spec/spec/Channel_Type_Contact_List.xml
new file mode 100644
index 000000000..348d0bd48
--- /dev/null
+++ b/spec/spec/Channel_Type_Contact_List.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Contact_List" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.ContactList">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.Group"/>
+ <tp:deprecated version="0.25.0">Replaced by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.ContactList</tp:dbus-ref>
+ </tp:deprecated>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for representing a list of people on the server which is
+ not used for communication. This is intended for use with the interface
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Group</tp:dbus-ref>
+ for managing buddy lists and privacy lists
+ on the server. This channel type has no methods because all of the
+ functionality it represents is available via the group interface.</p>
+
+ <p>There are currently two types of contact list:
+ HANDLE_TYPE_LIST is a &quot;magic&quot; server-defined list, and
+ HANDLE_TYPE_GROUP is a user-defined contact group.</p>
+
+ <p>For server-defined lists like the subscribe list, singleton instances
+ of this channel type should be created by the connection manager at
+ connection time if the list exists on the server, or may be requested
+ by using the appropriate handle. These handles can be obtained using
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestHandles</tp:dbus-ref>
+ with a <tp:type>Handle_Type</tp:type> of HANDLE_TYPE_LIST and one of the
+ following identifiers:</p>
+
+ <ul>
+ <li>subscribe - the group of contacts for whom you receive presence</li>
+ <li>publish - the group of contacts who may receive your presence</li>
+ <li>hide - a group of contacts who are on the publish list but are temporarily disallowed from receiving your presence</li>
+ <li>allow - a group of contacts who may send you messages</li>
+ <li>deny - a group of contacts who may not send you messages</li>
+ <li>stored - on protocols where the user's contacts are stored, this
+ contact list contains all stored contacts regardless of subscription
+ status.</li>
+ </ul>
+
+ <p>A contact can be in several server-defined lists. All lists are optional
+ to implement. If <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestHandles</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestChannel</tp:dbus-ref>
+ for a particular contact list raises an error, this indicates that the
+ connection manager makes no particular statement about the list's contents;
+ clients MUST NOT consider this to be fatal.</p>
+
+ <p>If a client wants to list all of a user's contacts, it is appropriate to
+ use the union of the subscribe, publish and stored lists, including the
+ local and remote pending members.</p>
+
+ <p>For example in XMPP, contacts who have the subscription type "none",
+ "from", "to" and "both" can be respectively in the lists:</p>
+
+ <ul>
+ <li>"none": stored</li>
+ <li>"from": stored and publish</li>
+ <li>"to": stored and subscribe</li>
+ <li>"both": stored, publish and subscribe</li>
+ </ul>
+
+ <p>These contact list channels may not be closed.</p>
+
+ <p>For user-defined contact groups, instances of this channel type should
+ be created by the connection manager at connection time for each group
+ that exists on the server. New, empty groups can be created by calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestHandles</tp:dbus-ref>
+ with a <tp:type>Handle_Type</tp:type> of HANDLE_TYPE_GROUP and with the
+ name set to the human-readable UTF-8 name of the group.</p>
+
+ <p>User-defined groups may be deleted by calling <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref> on the
+ channel, but only if
+ the group is already empty. Closing a channel to a non-empty group is
+ not allowed; its members must be set to the empty set first.</p>
+
+ <p>On some protocols (e.g. XMPP) empty groups are not represented on the
+ server, so disconnecting from the server and reconnecting might cause
+ empty groups to vanish.</p>
+ </tp:docstring>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Contact_Search.xml b/spec/spec/Channel_Type_Contact_Search.xml
new file mode 100644
index 000000000..98789ab40
--- /dev/null
+++ b/spec/spec/Channel_Type_Contact_Search.xml
@@ -0,0 +1,481 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Contact_Search" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2009 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.ContactSearch">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.19.10">
+ as stable API. Changes from draft 2:
+ <tp:type>Contact_Search_Result_Map</tp:type> keys are now identifiers
+ rather than handles; consequently, the values need not include
+ <tt>x-telepathy-identifier</tt>.
+ </tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for searching server-stored user directories. A new
+ channel should be requested by a client for each search attempt, and
+ closed when the search is completed or the required result has been
+ found.</p>
+
+ <p>Connections that support contact search channels SHOULD have an entry
+ in <tp:dbus-ref namespace='ofdT.Connection.Interface.Requests'
+ >RequestableChannelClasses</tp:dbus-ref> with the <tp:dbus-ref
+ namespace='ofdT.Channel'>ChannelType</tp:dbus-ref> fixed to this
+ interface, and no other fixed properties. That requestable
+ channel class MAY also have the Server and Limit properties in its
+ list of allowed properties, depending on the protocol.</p>
+
+ <tp:rationale>
+ <p>The requestable channel class would normally also have <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref> fixed to
+ <code>None</code>, but the initial implementation of ContactSearch
+ (in telepathy-gabble) didn't do this.</p>
+ </tp:rationale>
+
+ <p>All channels of this type should have <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>
+ <code>None</code> (and hence <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref> <code>0</code> and
+ <tp:dbus-ref namespace='ofdT.Channel'>TargetID</tp:dbus-ref>
+ <code>""</code>).</p>
+
+ <p>Requests for channels of this type need only
+ optionally specify the <tp:member-ref>Server</tp:member-ref> property
+ (if it is an allowed property in the connection's <tp:dbus-ref
+ namespace='ofdT.Connection.Interface.Requests'>RequestableChannelClasses</tp:dbus-ref>).</p>
+
+ <p>Before searching, the
+ <tp:member-ref>AvailableSearchKeys</tp:member-ref> property should be
+ inspected to determine the valid search keys which can be provided to
+ the <tp:member-ref>Search</tp:member-ref> method. A search request is
+ then started by providing some of these terms to the Search method, and
+ the <tp:member-ref>SearchState</tp:member-ref> will change from
+ <code>Not_Started</code> to <code>In_Progress</code>. As results are
+ returned by the server, the
+ <tp:member-ref>SearchResultReceived</tp:member-ref> signal is emitted
+ for each contact found; when the search is complete, the search state
+ will be set to <code>Completed</code>. If the search fails after Search
+ has been called, the state will change to <code>Failed</code>. A
+ running search can be cancelled by calling
+ <tp:member-ref>Stop</tp:member-ref>.</p>
+
+ <p>If the protocol supports limiting the number of results returned by a
+ search and subsequently requesting more results, after
+ <tp:member-ref>Limit</tp:member-ref> results have been received the
+ search state will be set to <code>More_Available</code>. Clients may
+ call <tp:member-ref>More</tp:member-ref> to request another
+ <tp:member-ref>Limit</tp:member-ref> results. If allowed by the
+ connection manager, clients may specify the "page size" by specifying
+ <tp:member-ref>Limit</tp:member-ref> when calling
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>.
+ </p>
+
+ <p>The client should call the channel's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref>
+ method when it is finished with the channel.</p>
+
+ <p>Each channel can only be used for a single search; a new channel
+ should be requested for each subsequent search. Connection managers
+ MUST support multiple ContactSearch channels being open at once (even
+ to the same server, if applicable).</p>
+
+ <p>It does not make sense to request this channel type using <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">EnsureChannel</tp:dbus-ref>;
+ clients SHOULD request channels of this type using
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>
+ instead.</p>
+
+ <tp:rationale>
+ <p>A contact search channel that is already in use for a different
+ search isn't useful.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:enum name="Channel_Contact_Search_State" type="u">
+ <tp:enumvalue suffix="Not_Started" value="0">
+ <tp:docstring>The search has not started</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="In_Progress" value="1">
+ <tp:docstring>The search is in progress</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="More_Available" value="2">
+ <tp:docstring>The search has paused, but more results can be retrieved
+ by calling <tp:member-ref>More</tp:member-ref>.</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Completed" value="3">
+ <tp:docstring>The search has been completed</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Failed" value="4">
+ <tp:docstring>The search has failed</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="SearchState" tp:name-for-bindings="Search_State"
+ access="read" type="u" tp:type="Channel_Contact_Search_State">
+ <tp:docstring>
+ The current state of this search channel object. Change notification
+ is via <tp:member-ref>SearchStateChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <signal name="SearchStateChanged"
+ tp:name-for-bindings="Search_State_Changed">
+ <arg name="State" type="u" tp:type="Channel_Contact_Search_State">
+ <tp:docstring>The new search state</tp:docstring>
+ </arg>
+ <arg name="Error" type="s" tp:type="DBus_Error_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ If the new state is <code>Failed</code>, the name of a D-Bus error
+ describing what went wrong. Otherwise, the empty string.
+ </tp:docstring>
+ </arg>
+ <arg name="Details" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about the state transition, which may
+ include the following well-known keys:</p>
+
+ <dl>
+ <dt>debug-message (s)</dt>
+ <dd>Debugging information on the change, corresponding to the
+ message part of a D-Bus error message, which SHOULD NOT be
+ displayed to users under normal circumstances</dd>
+ </dl>
+
+ <tp:rationale>
+ <p>This argument allows for future extensions. For instance,
+ if moving to state <code>Failed</code> because the server
+ rejected one of our search terms, we could define a key
+ that indicates which terms were invalid.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the <tp:member-ref>SearchState</tp:member-ref> property
+ changes. The implementation MUST NOT make transitions other than the
+ following:</p>
+
+ <ul>
+ <li><code>Not_Started</code> → <code>In_Progress</code></li>
+ <li><code>In_Progress</code> → <code>More_Available</code></li>
+ <li><code>More_Available</code> → <code>In_Progress</code></li>
+ <li><code>In_Progress</code> → <code>Completed</code></li>
+ <li><code>In_Progress</code> → <code>Failed</code></li>
+ </ul>
+ </tp:docstring>
+ </signal>
+
+ <tp:simple-type name="Contact_Search_Key" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Any of the following search keys, with the indicated result for
+ the search:</p>
+
+ <dl>
+ <dt>The empty string</dt>
+ <dd>Search for the search term in some implementation-dependent
+ set of fields, using an implementation-dependent algorithm
+ (e.g. searching for each word mentioned)
+ <tp:rationale>
+ The "one big search box" approach to searching, as is familiar
+ from Google. The Sametime plugin to Pidgin appears to search in
+ this way.
+ </tp:rationale>
+ </dd>
+
+ <dt>A <tp:type>VCard_Field</tp:type></dt>
+ <dd>Search for the search term in fields matching that name (for
+ instance, <code>nickname</code> would search nicknames, and
+ <code>tel</code> would search any available phone number,
+ regardless of its work/home/mobile/... status).</dd>
+
+ <dt>A <tp:type>VCard_Field</tp:type> followed by
+ "<code>;</code>" and a
+ <tp:type>VCard_Type_Parameter</tp:type> of the form
+ "<code>type=...</code>"</dt>
+ <dd>Search for the search term in fields of that name and type
+ only (for instance, <code>tel;type=mobile</code>).</dd>
+
+ <dt><code>x-telepathy-identifier</code></dt>
+ <dd>Search for contacts whose identifier in the IM protocol
+ matches the search term (e.g. contains it as a substring)
+ <tp:rationale>
+ Otherwise, starting a search by identifier would require the UI
+ to know the vCard field name corresponding to identifiers in
+ this protocol, which might be non-standard (like
+ <code>x-jabber</code>) or not exist at all.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>x-gender</code></dt>
+ <dd>For the search term "male" or "female", search only for contacts
+ listed as male or female, respectively. The results for other
+ search terms are undefined; it is likely that contacts with
+ unspecified gender will only be matched if this search key
+ is omitted from the request.
+ <tp:rationale>
+ Examples in XEP-0055 suggest this usage, and at least Gadu-Gadu
+ also supports limiting search results by gender.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>x-n-family</code></dt>
+ <dd>Search for the search term in contacts' family names
+ (the first component of the vCard field <code>n</code>).
+ <tp:rationale>
+ Gadu-Gadu and TOC seem to support this mode of searching.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>x-n-given</code></dt>
+ <dd>Search for the search term in contacts' given names
+ (the second component of the vCard field <code>n</code>).
+ <tp:rationale>
+ As for <code>x-n-family</code>.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>x-online</code></dt>
+ <dd>For the search term "yes", search only for contacts who are
+ currently online. The results for other search terms are undefined.
+ <tp:rationale>Gadu-Gadu appears to support this.</tp:rationale>
+ </dd>
+
+ <dt><code>x-adr-locality</code></dt>
+ <dd>Search for the search term as a locality or city (the fourth
+ component of the vCard field <code>adr</code>).
+ <tp:rationale>
+ Gadu-Gadu and TOC appear to support this.
+ </tp:rationale>
+ </dd>
+ </dl>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <property name="Limit" type="u" access="read" tp:name-for-bindings="Limit"
+ tp:immutable='yes' tp:requestable='sometimes'>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If supported by the protocol, the maximum number of results that
+ should be returned, where <code>0</code> represents no limit. If the
+ protocol does not support limiting results, this should be
+ <code>0</code>.</p>
+
+ <p>For example, if the terms passed to
+ <tp:member-ref>Search</tp:member-ref> match <i>Antonius</i>,
+ <i>Bridget</i> and <i>Charles</i> and this property is
+ <code>2</code>, the search service SHOULD only return <i>Antonius</i>
+ and <i>Bridget</i>.</p>
+
+ <p>This property SHOULD be requestable if and only if the protocol
+ supports specifying a limit; implementations SHOULD use
+ <code>0</code> as the default if possible, or a protocol-specific
+ sensible default otherwise.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="AvailableSearchKeys" type="as" access="read"
+ tp:name-for-bindings="Available_Search_Keys" tp:immutable='yes'>
+ <tp:docstring>
+ The set of search keys supported by this channel. Example values
+ include [""] (for protocols where several address fields are
+ implicitly searched) or ["x-n-given", "x-n-family", "nickname",
+ "email"] (for XMPP XEP-0055, without extensibility via Data Forms).
+
+ <tp:rationale>
+ It can be in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal for round-trip reduction.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="Contact_Search_Map">
+ <tp:docstring>A map from search keys to search terms.</tp:docstring>
+ <tp:member name="Key" type="s" tp:type="Contact_Search_Key">
+ <tp:docstring>
+ The search key to match against
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Term" type="s">
+ <tp:docstring>
+ The term or terms to be searched for in the search key; depending on
+ the protocol and the server implementation, this may be matched by
+ exact or approximate equality, substring matching, word matching
+ or any other matching algorithm
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <method name="Search" tp:name-for-bindings="Search">
+ <arg direction="in" name="Terms"
+ type="a{ss}" tp:type="Contact_Search_Map">
+ <tp:docstring>
+ A dictionary mapping search key names to the desired values
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Send a request to start a search for contacts on this connection. This
+ may only be called while the <tp:member-ref>SearchState</tp:member-ref>
+ is Not_Started; a valid search request will cause the
+ <tp:member-ref>SearchStateChanged</tp:member-ref> signal to be emitted
+ with the state In_Progress.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The <tp:member-ref>SearchState</tp:member-ref> is no longer
+ Not_Started, so this method is no longer available.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The search terms included something this connection manager cannot
+ search for.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="More" tp:name-for-bindings="More">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Request that a search in <tp:member-ref>SearchState</tp:member-ref>
+ <code>More_Available</code> move back to state <code>In_Progress</code>
+ and continue listing up to <tp:member-ref>Limit</tp:member-ref> more results.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The <tp:member-ref>SearchState</tp:member-ref> is not
+ <code>More_Available</code>.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Stop" tp:name-for-bindings="Stop">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Stop the current search. This may not be called while the
+ <tp:member-ref>SearchState</tp:member-ref> is Not_Started. If called
+ while the SearchState is In_Progress,
+ <tp:member-ref>SearchStateChanged</tp:member-ref> will be emitted,
+ with the state Failed and the error
+ <code>org.freedesktop.Telepathy.Error.<tp:error-ref>Cancelled</tp:error-ref></code>.</p>
+
+ <p>Calling this method on a search in state Completed or Failed
+ succeeds, but has no effect.</p>
+
+ <tp:rationale>
+ <p>Specifying Stop to succeed when the search has finished means that
+ clients who call Stop just before receiving
+ <tp:member-ref>SearchStateChanged</tp:member-ref> don't have to
+ handle a useless error.</p>
+ </tp:rationale>
+
+ <p>Depending on the protocol, the connection manager may not be
+ able to prevent the server from sending further results after this
+ method returns; if this is the case, it MUST ignore any further
+ results.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The <tp:member-ref>SearchState</tp:member-ref> is Not_Started, so
+ this method is not yet available.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:mapping name="Contact_Search_Result_Map">
+ <tp:docstring>A map from contact identifier to search result, emitted in
+ the <tp:member-ref>SearchResultReceived</tp:member-ref>
+ signal.</tp:docstring>
+
+ <tp:member name="Contact_Identifier" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The identifier of a contact matching the search terms.
+
+ <tp:rationale>
+ This is an identifier rather than a handle in case we make handles
+ immortal; see <a
+ href="https://bugs.freedesktop.org/show_bug.cgi?id=23155">fd.o#23155</a>
+ and <a
+ href="https://bugs.freedesktop.org/show_bug.cgi?id=13347#c5">fd.o#13347
+ comment 5</a>.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Info" type="a(sasas)" tp:type="Contact_Info_Field[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of fields representing information about this
+ contact, in the same format used in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">ContactInfo</tp:dbus-ref>
+ interface. It is possible that a separate call to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.ContactInfo">RequestContactInfo</tp:dbus-ref>
+ would return more information than this signal provides.</p>
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <signal name="SearchResultReceived"
+ tp:name-for-bindings="Search_Result_Received">
+ <arg name="Result" type="a{sa(sasas)}" tp:type="Contact_Search_Result_Map">
+ <tp:docstring>A mapping from contact identifier to an array of fields
+ representing information about this contact.</tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Emitted when a some search results are received from the server.
+ This signal can be fired arbitrarily many times so clients MUST NOT
+ assume they'll get only one signal.
+ </tp:docstring>
+ </signal>
+
+ <property name="Server" tp:name-for-bindings="Server"
+ type="s" access="read" tp:requestable='sometimes' tp:immutable='yes'>
+ <tp:docstring>
+ <p>For protocols which support searching for contacts on multiple
+ servers with different DNS names (like XMPP), the DNS name of the
+ server being searched by this channel, e.g.
+ "characters.shakespeare.lit". Otherwise, the empty string.</p>
+
+ <tp:rationale>
+ <p>XEP 0055 defines a mechanism for XMPP clients to search services
+ of their choice for contacts, such as users.jabber.org (the "Jabber
+ User Directory").</p>
+ </tp:rationale>
+
+ <p>This property SHOULD be requestable if and only if the
+ protocol supports querying multiple different servers;
+ implementations SHOULD use a sensible default if possible if this
+ property is not specified in a channel request.</p>
+
+ <tp:rationale>
+ <p>This allows a client to perform searches on a protocol it knows
+ nothing about without requiring the user to guess a valid server's
+ hostname.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_DBus_Tube.xml b/spec/spec/Channel_Type_DBus_Tube.xml
new file mode 100644
index 000000000..74e659514
--- /dev/null
+++ b/spec/spec/Channel_Type_DBus_Tube.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_DBus_Tube" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.DBusTube">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.Tube"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A D-Bus tube is an ordered reliable transport, for transporting D-Bus
+ traffic.</p>
+
+ <p>For each D-Bus tube, the connection manager listens on a D-Bus
+ server address, as detailed in the D-Bus specification. On this
+ address, it emulates a bus upon which each tube participant appears
+ as an endpoint.</p>
+
+ <p>The objects and interfaces which are expected to exist on the
+ emulated bus depend on the well-known name; typically, either the
+ participant who initiated the tube is expected to export the same
+ objects/interfaces that would be exported by a service of that name
+ on a bus, or all participants are expected to export those
+ objects/interfaces.</p>
+
+ <p>In a multi-user context (Handle_Type_Room) the tube behaves
+ like the D-Bus bus daemon, so participants can send each other
+ private messages, or can send broadcast messages which are
+ received by everyone in the tube (including themselves).
+ Each participant has a D-Bus unique name; connection managers
+ MUST prevent participants from sending messages with the wrong
+ sender unique name, and SHOULD attempt to avoid participants
+ receiving messages not intended for them.</p>
+
+ <p>In a 1-1 context (Handle_Type_Contact) the tube behaves like
+ a peer-to-peer D-Bus connection - arbitrary D-Bus messages with
+ any sender and/or destination can be sent by each participant,
+ and each participant receives all messages sent by the other
+ participant.</p>
+
+ </tp:docstring>
+
+ <method name="Offer" tp:name-for-bindings="Offer">
+ <tp:docstring>
+ Offers a D-Bus tube providing the service specified.
+ </tp:docstring>
+ <arg direction="in" name="parameters" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring>
+ The dictionary of arbitrary
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface.Tube">Parameters</tp:dbus-ref>
+ to send with the tube offer.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="access_control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The access control the connection manager applies to the D-Bus socket.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="address" type="s">
+ <tp:docstring>
+ The string describing the address of the private bus. The client
+ SHOULD NOT attempt to connect to the address until the tube is open.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact associated with this channel doesn't have tubes
+ capabilities.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Accept" tp:name-for-bindings="Accept">
+ <tp:docstring>
+ Accept a D-Bus tube that's in the "local pending" state. The
+ connection manager will attempt to open the tube. The tube remains in
+ the "local pending" state until the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Tube">TubeChannelStateChanged</tp:dbus-ref>
+ signal is emitted.
+ </tp:docstring>
+ <arg direction="in" name="access_control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The access control the connection manager applies to the D-Bus socket.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="address" type="s">
+ <tp:docstring>
+ The string describing the address of the private bus. The client
+ SHOULD NOT attempt to connect to the address until the tube is open.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="DBusNamesChanged" tp:name-for-bindings="DBus_Names_Changed">
+ <tp:docstring>
+ Emitted on a multi-user (i.e. Handle_Type_Room) D-Bus tube when a
+ participant opens or closes the tube. This provides change
+ notification for the <tp:member-ref>DBusNames</tp:member-ref> property.
+ </tp:docstring>
+ <arg name="Added" type="a{us}" tp:type="DBus_Tube_Participants">
+ <tp:docstring>
+ Array of handles and D-Bus names of new participants.
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ Array of handles of former participants.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="ServiceName" type="s" access="read"
+ tp:name-for-bindings="Service_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A string representing the service name that will be used over the
+ tube. It SHOULD be a well-known D-Bus service name, of the form
+ <tt>com.example.ServiceName</tt>.</p>
+ <p>When the tube is offered, the service name is transmitted to the
+ other end.</p>
+ <p>When requesting a channel with
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>,
+ this property MUST be included in the request.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="DBusNames" tp:name-for-bindings="DBus_Names"
+ access="read" type="a{us}" tp:type="DBus_Tube_Participants">
+ <tp:docstring>
+ For a multi-user (i.e. Handle_Type_Room) D-Bus tube, a mapping
+ between contact handles and their unique bus names on this tube.
+ For a peer-to-peer (i.e. Handle_Type_Contact) D-Bus tube, the empty
+ dictionary. Change notification is via
+ <tp:member-ref>DBusNamesChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <tp:mapping name="DBus_Tube_Participants">
+ <tp:docstring>Represents the participants in a multi-user D-Bus tube, as
+ used by the <tp:member-ref>DBusNames</tp:member-ref> property and the
+ <tp:member-ref>DBusNamesChanged</tp:member-ref> signal.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle">
+ <tp:docstring>
+ The handle of a participant in this D-Bus tube.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" tp:type="DBus_Unique_Name" name="Unique_Name">
+ <tp:docstring>
+ That participant's unique name.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="SupportedAccessControls" type="au"
+ tp:type="Socket_Access_Control[]" access="read"
+ tp:name-for-bindings="Supported_Access_Controls">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of the access control types that are supported with this channel.
+ Note that only Socket_Access_Control_Localhost and
+ Socket_Access_Control_Credentials can be used with D-Bus tubes.
+ Using Socket_Access_Control_Credentials is recommended.</p>
+
+ <tp:rationale>
+ <p>Socket_Access_Control_Credentials is easy to implement for a
+ D-Bus tube, because typical D-Bus library implementations like
+ libdbus and GDBus already have to support it to be able to
+ connect to the system or session bus, and usually enable it
+ by default; so there's typically no good reason to relax
+ access control to Localhost.</p>
+ </tp:rationale>
+
+ <p>When requesting a channel with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>,
+ this property MUST NOT be included in the request.</p>
+
+ </tp:docstring>
+ </property>
+
+ </interface>
+
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_File_Transfer.xml b/spec/spec/Channel_Type_File_Transfer.xml
new file mode 100644
index 000000000..f50b96344
--- /dev/null
+++ b/spec/spec/Channel_Type_File_Transfer.xml
@@ -0,0 +1,585 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_File_Transfer" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>
+ Copyright © 2008-2009 Collabora Limited
+ </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.FileTransfer">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:added version="0.17.18">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for transferring files. The
+ transmission of data between contacts is achieved by reading from
+ or writing to a socket. The type of the socket (local Unix, IPv4,
+ etc.) is decided on when the file transfer is offered or accepted.</p>
+
+ <p>A socket approach is used to make the transfer less dependent on both
+ client and connection manager knowing the same protocols. As an example,
+ when browsing an SMB share in a file manager, one selects "Send file"
+ and chooses a contact. Instead of passing a URL which would then require
+ the connection manager to connect to the SMB share itself, the client
+ passes a stream from which the connection manager reads, requiring no
+ further connection to the share. It also allows connection managers to
+ be more restricted in their access to the system, allowing tighter
+ security policies with eg SELinux, or more flexible deployments which
+ cross user or system boundaries.</p>
+
+ <p>The Telepathy client should connect to the socket or address that
+ the connection manager has set up and provided back to the clients
+ through the two methods.</p>
+
+ <ul><li>In order to send a file, one should request a FileTransfer
+ channel for a contact, including at least the mandatory properties
+ (<tp:member-ref>Filename</tp:member-ref>,
+ <tp:member-ref>Size</tp:member-ref> and <tp:member-ref>ContentType</tp:member-ref>).
+ Then, one should
+ call <tp:member-ref>ProvideFile</tp:member-ref> to configure the socket that
+ will be used to transfer the file.</li>
+
+ <li>In order to receive an incoming file transfer, one should call
+ <tp:member-ref>AcceptFile</tp:member-ref> and then wait until the state
+ changes to Open. When the receiver wants to resume a transfer, the Offset
+ argument should be should be set to a non-zero value when calling
+ <tp:member-ref>AcceptFile</tp:member-ref>.</li>
+
+ <li>Once the offset has been negotiated, the
+ <tp:member-ref>InitialOffsetDefined</tp:member-ref> signal
+ is emitted and the <tp:member-ref>InitialOffset</tp:member-ref> property
+ is defined. The <tp:member-ref>InitialOffsetDefined</tp:member-ref>
+ signal is emitted before channel becomes Open.
+ The receiver MUST check the value of
+ <tp:member-ref>InitialOffset</tp:member-ref> for a difference in offset
+ from the requested value in AcceptFile.</li>
+
+ <li>When the state changes to Open, Clients can start the transfer of the
+ file using the offset previously announced.
+ </li></ul>
+
+ <p>If something goes wrong with the transfer,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>
+ should be called on the channel.</p>
+
+ <p>The File channel type may be requested for handles of type
+ HANDLE_TYPE_CONTACT. If the channel is requested for any other
+ handle type then the behaviour is undefined.</p>
+
+ <p>Connection managers SHOULD NOT advertise support for file transfer to
+ other contacts unless it has been indicated by a call to
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities">UpdateCapabilities</tp:dbus-ref>.
+ </p>
+ <tp:rationale>
+ <p>People would send us files, and it would always fail. That would be silly.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <property name="State" type="u" tp:type="File_Transfer_State"
+ access="read" tp:name-for-bindings="State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The state of the file transfer as described by the
+ File_Transfer_State enum.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ContentType" type="s" access="read"
+ tp:name-for-bindings="Content_Type" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The file's MIME type. This cannot change once the channel has
+ been created.</p>
+
+ <p>This property is mandatory when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. Protocols which do not have a content-type property with file
+ transfers should set this value to application/octet-stream.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Filename" type="s" access="read"
+ tp:name-for-bindings="Filename" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the file on the sender's side. This is therefore given
+ as a suggested filename for the receiver. This cannot change
+ once the channel has been created.</p>
+
+ <p>This property should be the basename of the file being sent. For example,
+ if the sender sends the file /home/user/monkey.pdf then this property should
+ be set to monkey.pdf.</p>
+
+ <p>This property is mandatory when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. This property cannot be empty and MUST be set to a sensible value.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Size" type="t" access="read"
+ tp:name-for-bindings="Size" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The size of the file. If this property is set, then the file
+ transfer is guaranteed to be this size. This cannot change once
+ the channel has been created.</p>
+
+ <p>When you are creating a channel with this property, its value
+ MUST be accurate and in bytes. However, when receiving a file, this
+ property still MUST be in bytes but might not be entirely accurate
+ to the byte.</p>
+
+ <p>This property is mandatory when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. If this information isn't provided in the protocol, connection managers MUST set it
+ to UINT64_MAX.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ContentHashType" type="u" tp:type="File_Hash_Type"
+ access="read" tp:name-for-bindings="Content_Hash_Type" tp:immutable="yes"
+ tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The type of the <tp:member-ref>ContentHash</tp:member-ref> property.</p>
+
+ <p>This property is optional when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. However, if you wish to include the <tp:member-ref>ContentHash</tp:member-ref>
+ property you MUST also include this property. If you omit this property from a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method call then its value will be assumed to be File_Hash_Type_None.</p>
+
+ <p>For each supported hash type, implementations SHOULD include an entry
+ in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">RequestableChannelClasses</tp:dbus-ref>
+ with this property fixed to that hash type. If the protocol supports
+ offering a file without a content hash, implementations SHOULD list
+ this property in Allowed in a requestable channel class, mapping hash
+ types they don't understand to None.
+ </p>
+ </tp:docstring>
+ </property>
+
+ <property name="ContentHash" type="s" access="read"
+ tp:name-for-bindings="Content_Hash" tp:immutable="yes"
+ tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Hash of the contents of the file transfer, of type described
+ in the value of the <tp:member-ref>ContentHashType</tp:member-ref>
+ property.</p>
+
+ <p>This property is optional when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. Its value MUST correspond to the appropriate type of the
+ <tp:member-ref>ContentHashType</tp:member-ref> property. If the
+ ContentHashType property is not set, or set to File_Hash_Type_None,
+ then this property will not even be looked at.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Description" type="s" access="read"
+ tp:name-for-bindings="Description" tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Description of the file transfer. This cannot change once the
+ channel has been created.</p>
+
+ <p>This property is optional when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method. If this property was not provided by the remote party, connection managers MUST set it to
+ the empty string.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Date" type="x" access="read"
+ tp:type="Unix_Timestamp64" tp:name-for-bindings="Date" tp:immutable="yes"
+ tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The last modification time of the file being transferred. This
+ cannot change once the channel has been created</p>
+
+ <p>This property is optional when requesting the channel with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>
+ method.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="AvailableSocketTypes" type="a{uau}"
+ tp:type="Supported_Socket_Map" access="read"
+ tp:name-for-bindings="Available_Socket_Types"
+ tp:immutable="yes" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping from address types (members of Socket_Address_Type) to
+ arrays of access-control type (members of Socket_Access_Control)
+ that the connection manager supports for sockets with that
+ address type. For simplicity, if a CM supports offering a
+ particular type of file transfer, it is assumed to support accepting
+ it. Connection Managers MUST support at least Socket_Address_Type_IPv4.</p>
+
+ <p>A typical value for a host without IPv6 support:</p>
+
+ <pre>
+ {
+ Socket_Address_Type_IPv4:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Port,
+ Socket_Access_Control_Netmask],
+ Socket_Address_Type_Unix:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Credentials]
+ }
+ </pre>
+ </tp:docstring>
+ </property>
+
+ <property name="TransferredBytes" type="t" access="read"
+ tp:name-for-bindings="Transferred_Bytes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The number of bytes that have been transferred at the time of
+ requesting the property. This will be updated as the file transfer
+ continues.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialOffset" type="t" access="read"
+ tp:name-for-bindings="Initial_Offset" tp:requestable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The offset in bytes from where the file should be sent. This MUST
+ be respected by both the receiver and the sender after the state
+ becomes Open, but before any data is sent or received. Until the
+ <tp:member-ref>InitialOffsetDefined</tp:member-ref> signal
+ is emitted, this property is undefined.</p>
+
+ <p>Before setting the <tp:member-ref>State</tp:member-ref> property to
+ Open, the connection manager MUST set the InitialOffset property,
+ possibly to 0.</p>
+
+ <p>This property MUST NOT change after the state of the transfer has
+ changed to Open.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="URI" type="s" access="readwrite"
+ tp:name-for-bindings="URI" tp:immutable="sometimes" tp:requestable="yes">
+ <tp:added version="0.21.9"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>For outgoing file transfers, this requestable property allows the channel
+ requester to inform observers (and the handler, if it is not the requester
+ itself) of the URI of the file being transferred. Note that the
+ connection manager SHOULD NOT read this file directly; the handler
+ streams the file into the CM through the socket negotiated using
+ <tp:member-ref>ProvideFile</tp:member-ref>.</p>
+
+ <p>On outgoing file transfers, this property MUST NOT change after the channel
+ is requested.</p>
+
+ <p>For incoming file transfers, this property MAY be set by the channel
+ handler before calling <tp:member-ref>AcceptFile</tp:member-ref> to
+ inform observers where the incoming file will be saved. If set by an
+ approver, the handler MUST save the file to that location.
+ Setting this property once <tp:member-ref>AcceptFile</tp:member-ref>
+ has been called MUST fail. Once this property has been set
+ <tp:member-ref>URIDefined</tp:member-ref> is emitted.</p>
+
+ <p>If set, this URI SHOULD generally point to a file on the local system, as
+ defined by <a href='http://www.apps.ietf.org/rfc/rfc1738.html#sec-3.10'>
+ RFC 1738 §3.10</a>; that is, it should be of the form
+ <tt>file:///path/to/file</tt> or <tt>file://localhost/path/to/file</tt>.
+ For outgoing files, this URI MAY use a different scheme, such as
+ <tt>http:</tt>, if a remote resource is being transferred
+ to a contact.</p>
+
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="File_Transfer_State" type="u">
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ An invalid state type used as a null value. This value MUST NOT
+ appear in the State property.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Pending" value="1">
+ <tp:docstring>
+ The file transfer is waiting to be accepted/closed by the receiver.
+ The receiver has to call <tp:member-ref>AcceptFile</tp:member-ref>,
+ then wait for the state to change to Open and check the offset value.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Accepted" value="2">
+ <tp:docstring>
+ The receiver has accepted the transfer. The sender now has to
+ call <tp:member-ref>ProvideFile</tp:member-ref> to actually start the transfer.
+ The receiver should now wait for the state to change to Open
+ and check the offset value.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Open" value="3">
+ <tp:docstring>
+ The file transfer is open for traffic.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Completed" value="4">
+ <tp:docstring>
+ The file transfer has been completed successfully.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Cancelled" value="5">
+ <tp:docstring>
+ The file transfer has been cancelled.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="File_Transfer_State_Change_Reason" type="u">
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ No reason was specified.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Requested" value="1">
+ <tp:docstring>
+ The change in state was requested.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Local_Stopped" value="2">
+ <tp:docstring>
+ The file transfer was cancelled by the local user.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Remote_Stopped" value="3">
+ <tp:docstring>
+ The file transfer was cancelled by the remote user.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Local_Error" value="4">
+ <tp:docstring>
+ The file transfer was cancelled because of a local error.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Remote_Error" value="5">
+ <tp:docstring>
+ The file transfer was cancelled because of a remote error.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="File_Hash_Type" type="u">
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ No hash.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="MD5" value="1">
+ <tp:docstring>
+ MD5 digest as a string of 32 ASCII hex digits.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="SHA1" value="2">
+ <tp:docstring>
+ SHA1 digest as a string of ASCII hex digits.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="SHA256" value="3">
+ <tp:docstring>
+ SHA256 digest as a string of ASCII hex digits.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <method name="AcceptFile" tp:name-for-bindings="Accept_File">
+ <tp:docstring>
+ Accept a file transfer that's in the Pending state. The file
+ transfer's state becomes Accepted after this method is called.
+ At this point the client can connect to the socket. CM MUST emit
+ <tp:member-ref>InitialOffsetDefined</tp:member-ref> and change
+ the state to Open before writing to the socket.
+ Then <tp:member-ref>InitialOffset</tp:member-ref> should be respected in case
+ its value differs from the offset that was specified as an argument
+ to AcceptFile.
+ </tp:docstring>
+ <arg direction="in" name="Address_Type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of address the connection manager should listen on.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The type of access control the connection manager should apply to
+ the socket.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control_Param" type="v">
+ <tp:docstring>
+ A parameter for the access control type, to be interpreted as
+ specified in the documentation for the Socket_Access_Control enum.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Offset" type="t">
+ <tp:docstring>
+ The desired offset in bytes where the file transfer should start.
+ The offset is taken from the beginning of the file. Specifying an
+ offset of zero will start the transfer from the beginning of the
+ file. The offset that is actually given in the
+ <tp:member-ref>InitialOffset</tp:member-ref> property can differ
+ from this argument where the requested offset is not supported.
+ (For example, some protocols do not support offsets at all so
+ the InitialOffset property will always be 0.)
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address" type="v">
+ <tp:docstring>
+ The address on which the connection manager will listen for
+ connections for this file transfer.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The given address type or access-control mechanism is not supported.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:docstring>
+ Your address type, access control, access control parameter,
+ offset, or a combination of all four is invalid.
+ </tp:docstring>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The file transfer is not in the Pending state, there isn't
+ or there is a local error with acquiring a socket.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="ProvideFile" tp:name-for-bindings="Provide_File">
+ <tp:docstring>
+ Provide the file for an outgoing file transfer which has been offered.
+ Opens a socket that the client can use to provide a file to the connection manager.
+ The channel MUST have been requested, and will change state
+ to Open when this method is called if its state was Accepted.
+ </tp:docstring>
+ <arg direction="in" name="Address_Type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of address the connection manager should listen on.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The type of access control the connection manager should apply to
+ the socket.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control_Param" type="v">
+ <tp:docstring>
+ A parameter for the access control type, to be interpreted as
+ specified in the documentation for the Socket_Access_Control enum.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address" type="v">
+ <tp:docstring>
+ The address on which the connection manager will listen for
+ connections for this file transfer.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The given address type or access-control mechanism is not supported.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:docstring>
+ Your address type, access control, access control parameter, or
+ a combination of all three is invalid.
+ </tp:docstring>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ Channel is not an outgoing transfer, ProvideFile has already been called,
+ or there was a local error acquiring the socket.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="FileTransferStateChanged"
+ tp:name-for-bindings="File_Transfer_State_Changed">
+ <tp:docstring>
+ Emitted when the state of a file transfer changes.
+ </tp:docstring>
+ <arg name="State" type="u" tp:type="File_Transfer_State">
+ <tp:docstring>
+ The new state of the file transfer; see the File_Transfer_State enumeration.
+ </tp:docstring>
+ </arg>
+ <arg name="Reason" type="u" tp:type="File_Transfer_State_Change_Reason">
+ <tp:docstring>
+ The reason for the state change; see the File_Transfer_State_Change_Reason
+ enumeration.
+ The value will always be File_Transfer_State_Change_Reason_None, except
+ when changing state to cancelled.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="TransferredBytesChanged"
+ tp:name-for-bindings="Transferred_Bytes_Changed">
+ <tp:docstring>
+ Emitted when the number of transferred bytes changes. This will not be
+ signalled with every single byte change. Instead, the most frequent
+ this signal will be emitted is once a second. This should be
+ sufficient, and the <tp:member-ref>TransferredBytes</tp:member-ref>
+ property SHOULD NOT be polled.
+ </tp:docstring>
+ <arg name="Count" type="t">
+ <tp:docstring>
+ The number of already transferred bytes.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="InitialOffsetDefined"
+ tp:name-for-bindings="Initial_Offset_Defined">
+ <tp:docstring>
+ Emitted when the value of the <tp:member-ref>InitialOffset</tp:member-ref>
+ property has been negotiated. This signal MUST be emitted before the channel
+ becomes Open and clients have to use this offset when transferring the
+ file.
+ </tp:docstring>
+ <arg name="InitialOffset" type="t">
+ <tp:docstring>
+ The value of the <tp:member-ref>InitialOffset</tp:member-ref> property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="URIDefined"
+ tp:name-for-bindings="URI_Defined">
+ <tp:added version="0.21.9"/>
+ <tp:docstring>
+ Emitted when the value of the <tp:member-ref>URI</tp:member-ref>
+ property has been set. This signal MUST only be emitted on
+ incoming file transfers, and only if the handler sets the
+ <tp:member-ref>URI</tp:member-ref> property before
+ accepting the file.
+ </tp:docstring>
+ <arg name="URI" type="s">
+ <tp:docstring>
+ The value of the <tp:member-ref>URI</tp:member-ref> property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Room_List.xml b/spec/spec/Channel_Type_Room_List.xml
new file mode 100644
index 000000000..b2b886f14
--- /dev/null
+++ b/spec/spec/Channel_Type_Room_List.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Room_List" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2009 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.RoomList">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:struct name="Room_Info" array-name="Room_Info_List">
+ <tp:member type="u" tp:type="Room_Handle" name="Handle"/>
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type"/>
+ <tp:member type="a{sv}" tp:type="String_Variant_Map" name="Info"/>
+ </tp:struct>
+
+ <property name="Server" tp:name-for-bindings="Server"
+ type="s" access="read">
+ <tp:docstring>
+ <p>For protocols with a concept of chatrooms on multiple servers
+ with different DNS names (like XMPP), the DNS name of the server
+ whose rooms are listed by this channel, e.g. "conference.jabber.org".
+ Otherwise, the empty string.</p>
+
+ <p>This property cannot change during the lifetime of the channel.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="GetListingRooms" tp:name-for-bindings="Get_Listing_Rooms">
+ <arg direction="out" type="b" name="In_Progress">
+ <tp:docstring>
+ A boolean indicating if room listing is in progress
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Check to see if there is already a room list request in progress
+ on this channel.
+ </tp:docstring>
+ </method>
+
+ <signal name="GotRooms" tp:name-for-bindings="Got_Rooms">
+ <arg name="Rooms" type="a(usa{sv})" tp:type="Room_Info[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structs containing:
+ <ul>
+ <li>an integer room handle</li>
+ <li>a string representing the D-Bus interface name of the channel type</li>
+ <li>a dictionary mapping string keys to variant boxed information</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when information about rooms on the server becomes available.
+ The array contains the room handle (as can be passed to the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestChannel</tp:dbus-ref>
+ method with HANDLE_TYPE_ROOM), the channel
+ type, and a dictionary containing further information about the
+ room as available. The following well-known keys and types are
+ recommended for use where appropriate:</p>
+
+ <dl>
+ <dt>handle-name (s)</dt>
+ <dd>The identifier of the room (as would be returned by
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection">InspectHandles</tp:dbus-ref>)</dd>
+
+ <dt>name (s)</dt>
+ <dd>The human-readable name of the room if different from the handle</dd>
+
+ <dt>description (s)</dt>
+ <dd>A description of the room's overall purpose</dd>
+
+ <dt>subject (s)</dt>
+ <dd>The current subject of conversation in the room (as would
+ be returned by getting the string part of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Subject2"
+ >Subject</tp:dbus-ref> property)</dd>
+
+ <dt>members (u)</dt>
+ <dd>The number of members in the room</dd>
+
+ <dt>password (b)</dt>
+ <dd>True if the room requires a password to enter</dd>
+
+ <dt>invite-only (b)</dt>
+ <dd>True if you cannot join the room, but must be invited</dd>
+
+ <dt>room-id (s)</dt>
+ <dd>The human-readable identifier of a chat room (as would be
+ returned by getting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Room2"
+ >RoomName</tp:dbus-ref> property)</dd>
+
+ <dt>server (s)</dt>
+ <dd>The DNS name of the server hosting these channels (as would be
+ returned by getting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Room2"
+ >Server</tp:dbus-ref> property)</dd>
+ </dl>
+ </tp:docstring>
+ </signal>
+ <method name="ListRooms" tp:name-for-bindings="List_Rooms">
+ <tp:docstring>
+ Request the list of rooms from the server. The
+ <tp:member-ref>ListingRooms</tp:member-ref> (True) signal should be
+ emitted when this request is being processed,
+ <tp:member-ref>GotRooms</tp:member-ref> when any room information is
+ received, and <tp:member-ref>ListingRooms</tp:member-ref> (False) when
+ the request is complete.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+ <method name="StopListing" tp:name-for-bindings="Stop_Listing">
+ <tp:docstring>
+ Stop the room listing if it's in progress, but don't close the channel.
+ The <tp:member-ref>ListingRooms</tp:member-ref> (False) signal should
+ be emitted when the listing stops.
+ </tp:docstring>
+ </method>
+ <signal name="ListingRooms" tp:name-for-bindings="Listing_Rooms">
+ <arg name="Listing" type="b">
+ <tp:docstring>A boolean indicating if room listing is in progress</tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted to indicate whether or not room listing request is currently
+ in progress.
+ </tp:docstring>
+ </signal>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for listing named channels available on the server. Once the
+ <tp:member-ref>ListRooms</tp:member-ref> method is called, it emits signals for rooms present on the
+ server, until you <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref> this
+ channel. In some cases, it may not be possible
+ to stop the deluge of information from the server. This channel should be
+ closed when the room information is no longer being displayed, so that the
+ room handles can be freed.</p>
+
+ <p>This channel type may be implemented as a singleton on some protocols, so
+ clients should be prepared for the eventuality that they are given a
+ channel that is already in the middle of listing channels. The
+ <tp:member-ref>ListingRooms</tp:member-ref> signal, or
+ <tp:member-ref>GetListingRooms</tp:member-ref> method, can be used to check
+ this.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Server_Authentication.xml b/spec/spec/Channel_Type_Server_Authentication.xml
new file mode 100644
index 000000000..76599aa35
--- /dev/null
+++ b/spec/spec/Channel_Type_Server_Authentication.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Server_Authentication" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2010 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.ServerAuthentication">
+ <tp:added version="0.21.5">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The type for a channel representing an authentication step with the
+ server. The actual authentication functionality is implemented by
+ the additional interface named in
+ <tp:member-ref>AuthenticationMethod</tp:member-ref>,
+ such as <tp:dbus-ref namespace="ofdT"
+ >Channel.Interface.SASLAuthentication</tp:dbus-ref>.</p>
+
+ <p>Future authentication steps also supported by this channel type might
+ include solving a captcha and/or agreeing to an EULA or terms-of-use
+ document; each of these would be represented by a channel with this
+ type, but a different
+ <tp:member-ref>AuthenticationMethod</tp:member-ref>.</p>
+
+ <p>Channels of this type will normally be be signalled and dispatched
+ while the <tp:dbus-ref namespace="ofdT">Connection</tp:dbus-ref>
+ owning them is in the CONNECTING state. They MAY also appear on a
+ Connection in the CONNECTED state, for instance if periodic
+ re-authentication is required.</p>
+
+ <p>Normally, only one channel of this type will
+ exist on a given Connection; if there is more than one, the handler
+ must complete authentication with each of them in turn.</p>
+
+ <p>Channels of this type cannot be requested with methods such as
+ <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>.
+ They always have <tp:dbus-ref
+ namespace="ofdT.Channel">Requested</tp:dbus-ref> = False,
+ <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref> = None
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ = 0.</p>
+
+ <p>While it is CONNECTING, the Connection MUST NOT proceed with
+ connection, or signal
+ <tp:dbus-ref namespace="ofdT.Connection">StatusChanged</tp:dbus-ref>
+ to the CONNECTED state, until each channel of this type has either
+ been accepted as having a positive result (for instance, on SASL
+ channels this is done with the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.SASLAuthentication"
+ >AcceptSASL</tp:dbus-ref> method), or closed with the <tp:dbus-ref
+ namespace="ofdT.Channel">Close</tp:dbus-ref> method.</p>
+
+ <tp:rationale>
+ <p>ServerAuthentication channels normally represent the client
+ authenticating itself to the server, but can also be used for the
+ server to authenticate itself to the client (i.e. prove that it is
+ in fact the desired server and not an imposter). Until the
+ authentication handler has confirmed this, connection should not
+ continue.</p>
+ </tp:rationale>
+
+ <p>If a channel of this type is closed with the <tp:dbus-ref
+ namespace="ofdT.Channel">Close</tp:dbus-ref> method before
+ authentication has succeeded, this indicates that the Handler has
+ given up its attempts to authenticate or that no Handler is
+ available.</p>
+
+ <p>If this occurs, the connection manager MAY attempt to continue
+ connection (for instance, performing SASL authentication by using any
+ credentials passed to <tp:dbus-ref
+ namespace="ofdT.ConnectionManager">RequestConnection</tp:dbus-ref>,
+ for instance from the <tp:dbus-ref
+ namespace="ofdT">Account.Parameters</tp:dbus-ref>). If this fails
+ or has already been tried, the <tp:dbus-ref
+ namespace="ofdT">Connection</tp:dbus-ref> will
+ disconnect.</p>
+
+ <tp:rationale>
+ <p>In particular, the <tp:dbus-ref
+ namespace="ofdT">ChannelDispatcher</tp:dbus-ref> will close the
+ channel if it cannot find a handler.</p>
+ </tp:rationale>
+
+ <p>When the connection is done with the channel and it is no
+ longer needed, it is left open until either the connection state
+ turns to DISCONNECTED or the handler closes the channel. The
+ channel SHOULD NOT close itself once finished with.</p>
+ </tp:docstring>
+
+ <property name="AuthenticationMethod"
+ tp:name-for-bindings="Authentication_Method"
+ type="s" tp:type="DBus_Interface" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This property defines the method used for the authentication step
+ represented by this channel, which MUST be one of this channel's
+ <tp:dbus-ref namespace="ofdT.Channel">Interfaces</tp:dbus-ref>.</p>
+
+ <p>The initially-defined interface that can be used here is
+ <tp:dbus-ref namespace="ofdT"
+ >Channel.Interface.SASLAuthentication</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Server_TLS_Connection.xml b/spec/spec/Channel_Type_Server_TLS_Connection.xml
new file mode 100644
index 000000000..97efd1b36
--- /dev/null
+++ b/spec/spec/Channel_Type_Server_TLS_Connection.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Server_TLS_Connection"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2010 Collabora Limited </tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Channel.Type.ServerTLSConnection">
+ <tp:added version="0.19.13">(as stable API)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type that carries a TLS certificate between a server
+ and a client connecting to it.</p>
+ <p>Channels of this kind always have <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref> = False,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = None and <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ = 0, and cannot be requested with methods such as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>.
+ Also, they SHOULD be dispatched while the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ owning them is in the CONNECTING state.</p>
+ <p>In this case, handlers SHOULD accept or reject the certificate, using
+ the relevant methods on the provided object, or MAY just <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Close</tp:dbus-ref> the channel before doing so, to fall
+ back to a non-interactive verification process done inside the CM.</p>
+ <p>For example, channels of this kind can pop up while a client is
+ connecting to an XMPP server.</p>
+ </tp:docstring>
+
+ <property name="ServerCertificate" type="o" access="read"
+ tp:name-for-bindings="Server_Certificate"
+ tp:immutable='yeah'>
+ <tp:docstring>
+ <p>A <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Authentication">TLSCertificate</tp:dbus-ref>
+ containing the certificate chain as sent by the server,
+ and other relevant information.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Hostname" type="s" access="read"
+ tp:name-for-bindings="Hostname"
+ tp:immutable='sharks'>
+ <tp:added version="0.19.12"/>
+ <tp:docstring>
+ <p>The hostname or domain that the user expects to connect to. Clients
+ SHOULD use the <tp:member-ref>ReferenceIdentities</tp:member-ref>
+ property to verify the identity of the certificate. Clients MAY display
+ this hostname to the user as the expected identity. Clients SHOULD use
+ this property to lookup pinned certificates or other user preferences
+ for the connection.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ReferenceIdentities" type="as" access="read"
+ tp:name-for-bindings="Reference_Identities"
+ tp:immutable='plz'>
+ <tp:added version="0.21.10">
+ If this property is not present, clients SHOULD use the
+ <tp:member-ref>Hostname</tp:member-ref> property as the reference
+ identity to validate server certificates against.
+ </tp:added>
+
+ <tp:docstring>
+ <p>The identities of the server we expect
+ <tp:member-ref>ServerCertificate</tp:member-ref> to certify; clients
+ SHOULD verify that <tp:member-ref>ServerCertificate</tp:member-ref>
+ matches one of these identities when checking its validity.</p>
+
+ <p>This property MUST NOT be the empty list; it MUST
+ contain the value of the <tp:member-ref>Hostname</tp:member-ref>
+ property. All other identities included in this property MUST be derived from
+ explicit user input or choices, such as <tp:dbus-ref
+ namespace='ofdT.Account'>Parameters</tp:dbus-ref> passed to
+ <tp:dbus-ref
+ namespace='ofdT.ConnectionManager'>RequestConnection</tp:dbus-ref>.</p>
+
+ <tp:rationale>
+ <p>The primary use for this property is for XMPP services hosted by
+ <a href='http://www.google.com/apps/intl/en/business/gmail.html'>Google
+ Apps</a>. When connecting to Google Talk using an
+ <tt>@gmail.com</tt> JID, the server correctly presents a
+ certificate for <tt>gmail.com</tt>; however, for domains hosted via
+ Google Apps, a certificate for <tt>talk.google.com</tt> is
+ offered, due to unresolved technical limitations.</p>
+
+ <p>If the user has explicitly chosen to create a <q>Google Talk</q>
+ account, then trusting a certificate for <tt>talk.google.com</tt>
+ is reasonable. To handle this case, the connection manager may add
+ the values of any or all of the <tt>server</tt>,
+ <tt>fallback-server</tt> and <tt>extra-identities</tt> parameters;
+ the Google Talk account creation user interface may set these
+ parameters appropriately, or the user may set them for accounts
+ with other services.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Stream_Tube.xml b/spec/spec/Channel_Type_Stream_Tube.xml
new file mode 100644
index 000000000..63e7b2f50
--- /dev/null
+++ b/spec/spec/Channel_Type_Stream_Tube.xml
@@ -0,0 +1,292 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Stream_Tube" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.StreamTube">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.Tube"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A stream tube is a transport for ordered, reliable data transfer,
+ similar to SOCK_STREAM sockets.</p>
+
+ <p>When offering a stream tube, the initiating client creates a local
+ listening socket and offers it to the recipient client using the
+ <tp:member-ref>Offer</tp:member-ref> method. When a
+ recipient accepts a stream tube using the
+ <tp:member-ref>Accept</tp:member-ref> method, the
+ recipient's connection manager creates a new local listening socket.
+ Each time the recipient's client connects to this socket, the
+ initiator's connection manager proxies this connection to the
+ originally offered socket.</p>
+
+ </tp:docstring>
+
+ <method name="Offer" tp:name-for-bindings="Offer">
+ <tp:docstring>
+ Offer a stream tube exporting the local socket specified.
+ </tp:docstring>
+ <arg direction="in" name="address_type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of the listening address of the local service, as a member of
+ Socket_Address_Type.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="address" type="v">
+ <tp:docstring>
+ The listening address of the local service, as indicated by the
+ address_type.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="access_control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The access control the local service applies to the local socket,
+ specified so the connection manager can behave appropriately
+ when it connects.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="parameters" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring>
+ The dictionary of arbitrary
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface.Tube">Parameters</tp:dbus-ref>
+ to send with the tube offer.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact associated with this channel doesn't have tube
+ capabilities.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The connection manager doesn't support the given address type
+ or access-control type.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Accept" tp:name-for-bindings="Accept">
+ <tp:docstring>
+ Accept a stream tube that's in the "local pending" state. The
+ connection manager will attempt to open the tube. The tube remains in
+ the "local pending" state until the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Tube">TubeChannelStateChanged</tp:dbus-ref>
+ signal is emitted.
+ </tp:docstring>
+ <arg direction="in" name="address_type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of address the connection manager should listen on.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="access_control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The type of access control the connection manager should apply to
+ the socket.</p>
+
+ <p>Note that if you plan to establish more than one connection
+ through the tube, the Socket_Access_Control_Port access control
+ can't be used as you can't connect more than once from the same
+ port.</p>
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="access_control_param" type="v">
+ <tp:docstring>
+ A parameter for the access control type, to be interpreted as
+ specified in the documentation for the Socket_Access_Control enum.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="address" type="v">
+ <tp:docstring>
+ The address on which the connection manager will listen for
+ connections to this tube. The client should not attempt to connect
+ to the address until the tube is open.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The access_control_param is invalid with the given access_control.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The given address type or access-control mechanism is not supported.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="NewRemoteConnection"
+ tp:name-for-bindings="New_Remote_Connection">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted each time a participant opens a new connection to its
+ socket.</p>
+
+ <p>This signal is only fired on the offering side.</p>
+ </tp:docstring>
+ <arg name="Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the participant who opened the new connection
+ </tp:docstring>
+ </arg>
+ <arg name="Connection_Param" type="v">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A parameter which can be used by the listening process to identify
+ the connection. Note that this parameter has a meaningful value
+ only in the Socket_Access_Control_Port and
+ Socket_Access_Control_Credentials cases. If a different
+ Socket_Access_Control has been chosen when offering the tube, this
+ parameter should be ignored.</p>
+
+ <p>In the Socket_Access_Control_Port case, the variant
+ contains a struct Socket_Address_IPv4 (or Socket_Address_IPv6)
+ containing the address from which the CM is connected to the client
+ application.</p>
+
+ <p>In the Socket_Access_Control_Credentials case, the variant
+ contains the byte (D-Bus signature 'y') that has been sent with
+ the credentials.</p>
+ </tp:docstring>
+ </arg>
+ <arg name="Connection_ID" type="u" tp:type="Stream_Tube_Connection_ID">
+ <tp:docstring>
+ The unique ID associated with this connection. This ID will be used
+ to identifiy the connection when reporting errors with
+ <tp:member-ref>ConnectionClosed</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="NewLocalConnection"
+ tp:name-for-bindings="New_Local_Connection">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the tube application connects to the CM's socket.</p>
+
+ <p>This signal is only fired on the accepting side.</p>
+ </tp:docstring>
+ <arg name="Connection_ID" type="u" tp:type="Stream_Tube_Connection_ID">
+ <tp:docstring>
+ The unique ID associated with this connection. This ID will be used
+ to identifiy the connection when reporting errors with
+ <tp:member-ref>ConnectionClosed</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="ConnectionClosed"
+ tp:name-for-bindings="Connection_Closed"
+ tp:type="Stream_Tube_Connection_Closed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a connection has been closed.</p>
+ </tp:docstring>
+ <arg name="Connection_ID" type="u" tp:type="Stream_Tube_Connection_ID">
+ <tp:docstring>
+ The ID of the connection.
+ </tp:docstring>
+ </arg>
+ <arg name="Error" type="s" tp:type="DBus_Error_Name">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of a D-Bus error describing the error that occurred.</p>
+
+ <p>The following errors can be used:</p>
+ <ul>
+ <li><code>org.freedesktop.Telepathy.Error.Cancelled</code>:
+ user closed the socket or the tube.</li>
+ <li><code>org.freedesktop.Telepathy.Error.ConnectionLost</code>:
+ the bytestream relaying connection's data has been broken.</li>
+ <li><code>org.freedesktop.Telepathy.Error.ConnectionRefused</code>:
+ the tube offer refused the connection.</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <arg name="Message" type="s">
+ <tp:docstring>
+ A debug message.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Service" type="s" access="read"
+ tp:name-for-bindings="Service">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p> A string representing the service name that will be used over the
+ tube. It should be a well-known TCP service name as defined by
+ <a href="http://www.iana.org/assignments/port-numbers">
+ http://www.iana.org/assignments/port-numbers</a> or
+ <a href="http://www.dns-sd.org/ServiceTypes.html">
+ http://www.dns-sd.org/ServiceTypes.html</a>, for instance
+ "rsync" or "daap".</p>
+ <p>When the tube is offered, the service name is transmitted to the
+ other end.</p>
+ <p>When requesting a channel with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>,
+ this property MUST be included in the request.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="SupportedSocketTypes" type="a{uau}"
+ tp:type="Supported_Socket_Map" access="read"
+ tp:name-for-bindings="Supported_Socket_Types">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping from address types (members of Socket_Address_Type) to
+ arrays of access-control type (members of Socket_Access_Control)
+ that the connection manager supports for stream tubes with that
+ address type. For simplicity, if a CM supports offering a
+ particular type of tube, it is assumed to support accepting it.</p>
+
+ <p>A typical value for a host without IPv6 support:</p>
+
+ <pre>
+ {
+ Socket_Address_Type_IPv4:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Port,
+ Socket_Access_Control_Netmask],
+ Socket_Address_Type_Unix:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Credentials]
+ }
+ </pre>
+
+ <p>Connection Managers MUST support at least IPv4 with the localhost
+ access control.</p>
+
+ <p>When requesting a channel with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Requests.CreateChannel</tp:dbus-ref>,
+ this property MUST NOT be included in the request.</p>
+
+ </tp:docstring>
+ </property>
+
+ <tp:simple-type name="Stream_Tube_Connection_ID" type="u">
+ <tp:docstring>An identifier for a stream tube connection.
+ These are defined with the
+ <tp:member-ref>NewLocalConnection</tp:member-ref> or
+ <tp:member-ref>NewRemoteConnection</tp:member-ref> signals
+ and are used by <tp:member-ref>ConnectionClosed</tp:member-ref>
+ to identify the closed connection.
+ </tp:docstring>
+ </tp:simple-type>
+
+ </interface>
+
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Streamed_Media.xml b/spec/spec/Channel_Type_Streamed_Media.xml
new file mode 100644
index 000000000..aa2b90345
--- /dev/null
+++ b/spec/spec/Channel_Type_Streamed_Media.xml
@@ -0,0 +1,853 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Streamed_Media" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2009 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.StreamedMedia">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Channel.Interface.Group"/>
+
+ <tp:enum name="Media_Stream_Type" type="u"
+ array-name="Media_Stream_Type_List">
+ <tp:enumvalue suffix="Audio" value="0">
+ <tp:docstring>An audio stream</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Video" value="1">
+ <tp:docstring>A video stream</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Media_Stream_State" type="u">
+ <tp:enumvalue suffix="Disconnected" value="0">
+ <tp:docstring>The stream is disconnected.</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Connecting" value="1">
+ <tp:docstring>The stream is trying to connect.</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Connected" value="2">
+ <tp:docstring>The stream is connected.</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Media_Stream_Direction" type="u">
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>Media are not being sent or received</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Send" value="1">
+ <tp:docstring>Media are being sent, but not received</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Receive" value="2">
+ <tp:docstring>Media are being received, but not sent</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Bidirectional" value="3">
+ <tp:docstring>Media are being sent and received</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:flags name="Media_Stream_Pending_Send" value-prefix="Media_Stream_Pending" type="u">
+ <tp:flag suffix="Local_Send" value="1">
+ <tp:docstring>
+ The local user has been asked to send media by the remote user.
+ Call <tp:member-ref>RequestStreamDirection</tp:member-ref> to
+ indicate whether or not this is acceptable.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Remote_Send" value="2">
+ <tp:docstring>
+ The remote user has been asked to send media by the local user.
+ The <tp:member-ref>StreamDirectionChanged</tp:member-ref> signal
+ will be emitted when the remote user accepts or rejects this
+ change.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:struct name="Media_Stream_Info" array-name="Media_Stream_Info_List">
+ <tp:member type="u" tp:type="Stream_ID" name="Identifier"/>
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact"/>
+ <tp:member type="u" tp:type="Media_Stream_Type" name="Type"/>
+ <tp:member type="u" tp:type="Media_Stream_State" name="State"/>
+ <tp:member type="u" tp:type="Media_Stream_Direction" name="Direction"/>
+ <tp:member type="u" tp:type="Media_Stream_Pending_Send"
+ name="Pending_Send_Flags"/>
+ </tp:struct>
+
+ <tp:simple-type name="Stream_ID" type="u"
+ array-name="Stream_ID_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An unsigned integer identifying a stream within a channel.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <method name="ListStreams" tp:name-for-bindings="List_Streams">
+ <arg direction="out" type="a(uuuuuu)" tp:type="Media_Stream_Info[]"
+ name="Streams">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structs containing:
+ <ul>
+ <li>the stream identifier</li>
+ <li>the contact handle who the stream is with (or 0 if the stream
+ represents more than a single member)</li>
+ <li>the type of the stream</li>
+ <li>the current stream state</li>
+ <li>the current direction of the stream</li>
+ <li>the current pending send flags</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns an array of structs representing the streams currently active
+ within this channel. Each stream is identified by an unsigned integer
+ which is unique for each stream within the channel.
+ </tp:docstring>
+ </method>
+
+ <method name="RemoveStreams" tp:name-for-bindings="Remove_Streams">
+ <arg direction="in" name="Streams" type="au" tp:type="Stream_ID[]">
+ <tp:docstring>
+ An array of stream identifiers (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the given streams are removed. If all streams are
+ removed, the channel MAY close.</p>
+
+ <p>Clients SHOULD NOT attempt to terminate calls by removing all the
+ streams; instead, clients SHOULD terminate calls by removing the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Group.SelfHandle</tp:dbus-ref>
+ from the channel, using either
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembers</tp:dbus-ref>
+ or
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembersWithReason</tp:dbus-ref>.
+ </p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ A stream identifier is unknown
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestStreamDirection"
+ tp:name-for-bindings="Request_Stream_Direction">
+ <arg direction="in" name="Stream_ID" type="u">
+ <tp:docstring>
+ The stream identifier (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Stream_Direction" type="u" tp:type="Media_Stream_Direction">
+ <tp:docstring>
+ The desired stream direction (a value of MediaStreamDirection)
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request a change in the direction of an existing stream. In particular,
+ this might be useful to stop sending media of a particular type,
+ or inform the peer that you are no longer using media that is being
+ sent to you.</p>
+
+ <p>Depending on the protocol, streams which are no longer sending in
+ either direction should be removed and a
+ <tp:member-ref>StreamRemoved</tp:member-ref> signal emitted.
+ Some direction changes can be enforced locally (for example,
+ BIDIRECTIONAL -&gt; RECEIVE can be achieved by merely stopping sending),
+ others may not be possible on some protocols, and some need agreement
+ from the remote end. In this case, the MEDIA_STREAM_PENDING_REMOTE_SEND
+ flag will be set in the
+ <tp:member-ref>StreamDirectionChanged</tp:member-ref> signal, and the
+ signal
+ emitted again without the flag to indicate the resulting direction when
+ the remote end has accepted or rejected the change.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ A stream identifier is unknown
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The requested direction is not available on this stream
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestStreams" tp:name-for-bindings="Request_Streams">
+ <arg direction="in" name="Contact_Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ A contact handle with whom to establish the streams
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Types" type="au" tp:type="Media_Stream_Type[]">
+ <tp:docstring>
+ An array of stream types (values of MediaStreamType)
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a(uuuuuu)" tp:type="Media_Stream_Info[]"
+ name="Streams">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structs (in the same order as the given stream types)
+ containing:
+ <ul>
+ <li>the stream identifier</li>
+ <li>the contact handle who the stream is with (or 0 if the stream
+ represents more than a single member)</li>
+ <li>the type of the stream</li>
+ <li>the current stream state</li>
+ <li>the current direction of the stream</li>
+ <li>the current pending send flags</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that streams be established to exchange the given types of
+ media with the given member. In general this will try and establish a
+ bidirectional stream, but on some protocols it may not be possible to
+ indicate to the peer that you would like to receive media, so a
+ send-only stream will be created initially. In the cases where the
+ stream requires remote agreement (eg you wish to receive media from
+ them), the <tp:member-ref>StreamDirectionChanged</tp:member-ref> signal
+ will be emitted with the
+ MEDIA_STREAM_PENDING_REMOTE_SEND flag set, and the signal emitted again
+ with the flag cleared when the remote end has replied.</p>
+
+ <p>If streams of the requested types already exist, calling this
+ method results in the creation of additional streams. Accordingly,
+ clients wishing to have exactly one audio stream or exactly one
+ video stream SHOULD check for the current streams using
+ <tp:member-ref>ListStreams</tp:member-ref> before calling this
+ method.</p>
+ </tp:docstring>
+ <tp:changed version="0.17.2">
+ <p>It is valid to use a handle which is neither
+ a current nor pending member in this channel's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Group</tp:dbus-ref>
+ interface. If
+ so, that handle will be added to the remote-pending set only when
+ an attempt has actually been made to contact them. For further
+ call-state notification, use the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">CallState</tp:dbus-ref>
+ interface, if
+ supported. This usage was not allowed in spec versions below
+ 0.17.2.</p>
+ </tp:changed>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ A stream type given is invalid.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ A stream type given is not implemented by the connection manager.
+ Since 0.17.23, connection managers SHOULD raise this error
+ in preference to InvalidArgument.
+ <tp:rationale>
+ Connection managers can't know whether an unknown number
+ is a valid stream type that was introduced in a later spec
+ version.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ That contact's client does not implement one of the given stream
+ types. For this method, clients SHOULD consider this error and
+ NotCapable to be equivalent.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable">
+ <tp:docstring>
+ That contact's client does not implement one of the given stream
+ types. Since 0.17.23, connection managers SHOULD raise
+ this in preference to NotAvailable.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="StreamAdded" tp:name-for-bindings="Stream_Added">
+ <arg name="Stream_ID" type="u">
+ <tp:docstring>
+ The stream identifier (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <arg name="Contact_Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact handle who the stream is with (or 0 if it
+ represents more than a single member)
+ </tp:docstring>
+ </arg>
+ <arg name="Stream_Type" type="u" tp:type="Media_Stream_Type">
+ <tp:docstring>
+ The stream type (a value from MediaStreamType)
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a new stream has been added to this channel.
+ Clients SHOULD assume that the stream's
+ <tp:type>Media_Stream_State</tp:type> is initially Disconnected.</p>
+
+ <p>If a connection manager needs to represent the addition of a stream
+ whose state is already Connecting or Connected, it MUST do this
+ by emitting StreamAdded, closely followed by
+ <tp:member-ref>StreamStateChanged</tp:member-ref> indicating a
+ change to the appropriate state.</p>
+
+ <tp:rationale>
+ <p>Historically, it was not clear from the StreamAdded signal what
+ the state of the stream was. telepathy-spec 0.17.22
+ clarified this.</p>
+ </tp:rationale>
+
+ <p>Similarly, clients SHOULD assume that the initial
+ <tp:type>Media_Stream_Direction</tp:type> of a newly added stream
+ is Receive, and that the initial
+ <tp:type>Media_Stream_Pending_Send</tp:type> is
+ Pending_Local_Send.</p>
+
+ <p>If a connection manager needs to represent the addition of a stream
+ whose direction or pending-send differs from those initial values,
+ it MUST do so by emitting StreamAdded, closely followed by
+ <tp:member-ref>StreamDirectionChanged</tp:member-ref> indicating a
+ change to the appropriate direction and pending-send state.</p>
+
+ <tp:rationale>
+ <p>StreamAdded doesn't itself indicate the stream's direction; this
+ is unfortunate, but is preserved for compatibility.</p>
+
+ <p>This is the appropriate direction for streams added by a remote
+ contact on existing connection managers, and does not violate
+ user privacy by automatically sending audio or video (audio streams
+ start off muted, video streams start off not sending). For
+ streams added by the local user using the client receiving the
+ signal, the true direction can also be determined from the return
+ value of the <tp:member-ref>RequestStreams</tp:member-ref>
+ method.</p>
+
+ <p>Existing clients typically operate by maintaining a separate
+ idea of the directions that they would like the streams to have,
+ and enforcing these intended directions by calling
+ <tp:member-ref>RequestStreamDirection</tp:member-ref> whenever
+ needed.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+
+ <signal name="StreamDirectionChanged"
+ tp:name-for-bindings="Stream_Direction_Changed">
+ <arg name="Stream_ID" type="u">
+ <tp:docstring>
+ The stream identifier (as defined in <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <arg name="Stream_Direction" type="u" tp:type="Media_Stream_Direction">
+ <tp:docstring>
+ The new stream direction (as defined in ListStreams)
+ </tp:docstring>
+ </arg>
+ <arg name="Pending_Flags" type="u" tp:type="Media_Stream_Pending_Send">
+ <tp:docstring>
+ The new pending send flags (as defined in ListStreams)
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the direction or pending flags of a stream are
+ changed.</p>
+
+ <p>If the MEDIA_STREAM_PENDING_LOCAL_SEND flag is set, the remote user
+ has requested that we begin sending on this stream.
+ <tp:member-ref>RequestStreamDirection</tp:member-ref>
+ should be called to indicate whether or not this change is
+ acceptable.</p>
+
+ <tp:rationale>
+ <p>This allows for a MSN-style user interface, "Fred has asked you
+ to enable your webcam. (Accept | Reject)", if desired.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+
+ <signal name="StreamError" tp:name-for-bindings="Stream_Error">
+ <arg name="Stream_ID" type="u">
+ <tp:docstring>
+ The stream identifier (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <arg name="Error_Code" type="u" tp:type="Media_Stream_Error">
+ <tp:docstring>
+ A stream error number, one of the values of MediaStreamError
+ </tp:docstring>
+ </arg>
+ <arg name="Message" type="s">
+ <tp:docstring>
+ A string describing the error (for debugging purposes only)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a stream encounters an error.
+ </tp:docstring>
+ </signal>
+
+ <signal name="StreamRemoved" tp:name-for-bindings="Stream_Removed">
+ <arg name="Stream_ID" type="u">
+ <tp:docstring>
+ stream_id - the stream identifier (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a stream has been removed from this channel.
+ </tp:docstring>
+ </signal>
+
+ <signal name="StreamStateChanged"
+ tp:name-for-bindings="Stream_State_Changed">
+ <arg name="Stream_ID" type="u">
+ <tp:docstring>
+ The stream identifier (as defined in
+ <tp:member-ref>ListStreams</tp:member-ref>)
+ </tp:docstring>
+ </arg>
+ <arg name="Stream_State" type="u" tp:type="Media_Stream_State">
+ <tp:docstring>
+ The new stream state (as defined in ListStreams)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a member's stream's state changes.
+ </tp:docstring>
+ </signal>
+
+ <property name="InitialAudio" tp:name-for-bindings="Initial_Audio"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If set to true in a channel request that will create a new channel,
+ the connection manager should immediately attempt to establish an
+ audio stream to the remote contact, making it unnecessary for the
+ client to call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.StreamedMedia">RequestStreams</tp:dbus-ref>.</p>
+
+ <p>If this property, or InitialVideo, is passed to EnsureChannel
+ (as opposed to CreateChannel), the connection manager SHOULD ignore
+ these properties when checking whether it can return an existing
+ channel as suitable; these properties only become significant when
+ the connection manager has decided to create a new channel.</p>
+
+ <p>If true on a requested channel, this indicates that the audio
+ stream has already been requested and the client does not need to
+ call RequestStreams, although it MAY still do so.</p>
+
+ <p>If true on an unrequested (incoming) channel, this indicates that
+ the remote contact initially requested an audio stream; this does
+ not imply that that audio stream is still active (as indicated by
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.StreamedMedia">ListStreams</tp:dbus-ref>).</p>
+
+ <p>This property is immutable (cannot change), and therefore SHOULD
+ appear wherever immutable properties are reported, e.g. <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signals.</p>
+
+ <tp:rationale><p>This reduces D-Bus round trips.</p></tp:rationale>
+
+ <p>Connection managers capable of signalling audio calls to contacts
+ SHOULD include a channel class in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">RequestableChannelClasses</tp:dbus-ref>
+ with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>
+ = <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = Contact in the fixed properties dictionary, and InitialAudio
+ (and also InitialVideo, if applicable) in the allowed properties
+ list. Clients wishing to discover whether a connection manager
+ can signal audio and/or video calls SHOULD use this information.</p>
+
+ <tp:rationale>
+ <p>Not all protocols support signalling video calls, and it would be
+ possible (although unlikely) to have a protocol where only video,
+ and not audio, could be signalled.</p>
+ </tp:rationale>
+
+ <p>Connection managers that support the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">ContactCapabilities</tp:dbus-ref>
+ interface SHOULD represent the capabilities of receiving audio
+ and/or video calls by including a channel class in
+ a contact's capabilities with ChannelType = StreamedMedia
+ in the fixed properties dictionary, and InitialAudio and/or
+ InitialVideo in the allowed properties list. Clients wishing to
+ discover whether a particular contact is likely to be able to
+ receive audio and/or video calls SHOULD use this information.</p>
+
+ <tp:rationale>
+ <p>Not all clients support video calls, and it would also be
+ possible (although unlikely) to have a client which could only
+ stream video, not audio.</p>
+ </tp:rationale>
+
+ <p>Clients that are willing to receive audio and/or video calls
+ SHOULD include the following among their channel classes if
+ calling <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities">UpdateCapabilities</tp:dbus-ref>
+ (clients of a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatcher</tp:dbus-ref>
+ SHOULD instead arrange for the ChannelDispatcher to do this,
+ by including the filters in their <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ properties):</p>
+
+ <ul>
+ <li>{ ChannelType = StreamedMedia }</li>
+ <li>{ ChannelType = StreamedMedia, InitialAudio = true }
+ if receiving calls with audio is supported</li>
+ <li>{ ChannelType = StreamedMedia, InitialVideo = true }
+ if receiving calls with video is supported</li>
+ </ul>
+
+ <tp:rationale>
+ <p>Connection managers for protocols with capability discovery,
+ like XMPP, need this information to advertise the appropriate
+ capabilities for their protocol.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="InitialVideo" tp:name-for-bindings="Initial_Video"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same as <tp:member-ref>InitialAudio</tp:member-ref>, but for
+ a video stream. This property is immutable (cannot change).</p>
+
+ <p>In particular, note that if this property is false, this does not
+ imply that an active video stream has not been added, only that no
+ video stream was active at the time the channel appeared.</p>
+
+ <p>This property is the correct way to discover whether connection
+ managers, contacts etc. support video calls; it appears in
+ capabilities structures in the same way as InitialAudio.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ImmutableStreams" tp:name-for-bindings="Immutable_Streams"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tt>True</tt>, once streams have been requested for this channel
+ (either by setting <tp:member-ref>InitialAudio</tp:member-ref> or
+ <tp:member-ref>InitialVideo</tp:member-ref> when the channel is
+ requested, or by calling
+ <tp:member-ref>RequestStreams</tp:member-ref> on a channel with no
+ streams), a stream of a different content type cannot be added;
+ subsequent calls to <tp:member-ref>RequestStreams</tp:member-ref>
+ that attempt to do so will fail.</p>
+
+ <p>If this property is missing, clients SHOULD assume that it is false,
+ and thus that the channel's streams can be changed once the call has
+ started.</p>
+
+ <p>If this property is present in the "allowed" set in all of the
+ StreamedMedia entries in a contact's capabilities, then user
+ interfaces MAY choose to show a separate "call" option for each
+ class of call.</p>
+
+ <tp:rationale>
+ <p>For example, once an audio-only Google Talk call has started,
+ it is not possible to add a video stream; both audio and video
+ must be requested at the start of the call if video is desired.
+ User interfaces may use this pseudo-capability as a hint to
+ display separate "Audio call" and "Video call" buttons, rather
+ than a single "Call" button with the option to add and remove
+ video once the call has started for contacts without this flag.
+ </p>
+ </tp:rationale>
+
+ <p>This property is immutable, and therefore SHOULD be announced
+ in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>,
+ etc.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel that can send and receive streamed media such as audio or
+ video. Provides a number of methods for listing and requesting new
+ streams, and signals to indicate when streams have been added, removed
+ and changed status. The state of the call (ringing remotely, ringing
+ locally, answered, missed, etc.) are represented using the properties
+ and signals of the Group interface.</p>
+
+ <p>In general this should be used in conjunction with the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling</tp:dbus-ref>
+ interface to exchange connection candidates and codec choices with
+ whichever component is responsible for the streams. However, in certain
+ applications where no candidate exchange is necessary (eg the streams
+ are handled by specialised hardware which is controlled directly by the
+ connection manager), the signalling interface can be omitted and this
+ channel type used simply to control the streams.</p>
+
+ <h4>Outgoing calls</h4>
+
+ <p>To make an audio-only call to a contact <tt>foo@example.com</tt>,
+ clients should call:</p>
+
+ <blockquote>
+ <pre>
+<tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">CreateChannel</tp:dbus-ref>({
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>: <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>: Contact,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetID</tp:dbus-ref>: 'foo@example.com',
+ <tp:member-ref>InitialAudio</tp:member-ref>: True,
+)</pre></blockquote>
+
+ <p>As always, <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ may be used in place of TargetID if the contact's handle is already
+ known. To make an audio-and-video call, the client should also specify
+ <tp:member-ref>InitialVideo</tp:member-ref>. The connection manager
+ SHOULD return a channel whose immutable properties contain the local
+ user as the <tp:dbus-ref namespace='ofdT.Channel'>InitiatorHandle</tp:dbus-ref>,
+ the remote contact as the <tp:dbus-ref namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref namespace='ofdT.Channel'>Requested</tp:dbus-ref> = <code>True</code>
+ (indicating that the call is outgoing); the <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Group</tp:dbus-ref> interface should
+ initially have the local user in <tp:dbus-ref
+ namespace='ofdT.Channel.Interface.Group'>Members</tp:dbus-ref> and the remote
+ contact in <tp:dbus-ref
+ namespace='ofdT.Channel.Interface.Group'>RemotePendingMembers</tp:dbus-ref>, to
+ indicate that we are awaiting their response.</p>
+
+ <p>The contact answering the call is represented by the CM signalling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">MembersChanged</tp:dbus-ref>,
+ moving the remote contact to Members, with the remote contact as the
+ <var>Actor</var> and <var>Reason</var> <code>None</code>. The contact
+ rejecting the call is represented by both contacts being removed from
+ the group, with the remote contact as the <var>Actor</var> and
+ <var>Reason</var> set appropriately. The local user may hang up at any
+ time by calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembersWithReason</tp:dbus-ref>
+ to remove themself, with an appropriate reason; the CM SHOULD relay the
+ reason to the remote contact, and emit MembersChanged removing both
+ contacts from the group with the self handle as the <var>Actor</var>.</p>
+
+ <p>(In the past, several other patterns have been used to place outgoing
+ calls; see
+ <a href="http://telepathy.freedesktop.org/wiki/Requesting%20StreamedMedia%20channels">'Requesting StreamedMedia Channels' on the Telepathy wiki</a>
+ for the details.)</p>
+
+ <h4>Incoming calls</h4>
+
+ <p>Incoming calls' immutable properties should contain <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ = Contact, both <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref> and
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">InitiatorHandle</tp:dbus-ref>
+ set to the remote contact, <tp:dbus-ref
+ namespace='ofdT.Channel'>Requested</tp:dbus-ref> = <code>False</code>
+ (indicating that this is an incoming call), and appropriate values of
+ <tp:member-ref>InitialAudio</tp:member-ref> and
+ <tp:member-ref>InitialVideo</tp:member-ref>; the Group interface should
+ initially have the local user in <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.Group">LocalPendingMembers</tp:dbus-ref>
+ and the remote contact in <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.Group">Members</tp:dbus-ref>,
+ indicating that the contact is awaiting our response.</p>
+
+ <p>To accept the call, use <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">AddMembers</tp:dbus-ref>
+ to move the local user to the group's members. To reject the call, use
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembersWithReason</tp:dbus-ref>
+ to remove the local member from the group, with an appropriate reason.
+ If the remote user ends the call before it is answered, this is
+ represented by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">MembersChanged</tp:dbus-ref>
+ removing both parties from the group with the remote contact as the
+ <var>Actor</var>, and <var>Reason</var> set appropriately.</p>
+
+ <p>Note that the call may end with the self handle as the
+ <var>Actor</var> without the user having chosen to reject the call, as
+ indicated by the nature of the <var>Reason</var>. Specifically, some
+ local component may time out the call (indicating this with reason
+ <code>No_Answer</code>; for example, the CM may have forwarded the call
+ to another number, as configured using <tp:dbus-ref
+ namespace='ofdT.Connection.Interface'>Forwarding.DRAFT</tp:dbus-ref>),
+ or something may have gone wrong with the call
+ (indicated by reason <code>Error</code>). Such calls SHOULD be
+ considered missed, just as if the remote contact had hung up before the
+ local user answered the call.</p>
+
+ <tp:rationale>
+ <p>This is a bit awkward, but these are the best ways we can represent
+ these situations. It's important to document which calls should be
+ considered missed, to ensure that the user can be notified.</p>
+ </tp:rationale>
+
+ <p>When the local user accepts an incoming call, the connection manager
+ SHOULD change the direction of any streams with pending local send
+ to be sending, without altering whether those streams are
+ receiving.</p>
+
+ <tp:rationale>
+ <p>This matches existing practice, and means that a client
+ can answer incoming calls and get an unmuted microphone/activated
+ webcam without having to take additional action to accept the
+ stream directions.</p>
+
+ <p>It does, however, introduce a race condition: a client believing
+ that it is accepting an audio-only call by calling AddMembers
+ can inadvertantly accept an audio + video call (and hence activate
+ sending from a webcam without the user's permission) if a video
+ stream is added just before AddMembers is processed. This race
+ should be removed when this specification is revised.</p>
+ </tp:rationale>
+
+ <h4>During a call</h4>
+
+ <p>If <tp:member-ref>ImmutableStreams</tp:member-ref> is
+ <code>False</code>, new streams may be requested using
+ <tp:member-ref>RequestStreams</tp:member-ref> (to add video to an
+ audio-only call, for instance), and existing streams may be removed using
+ <tp:member-ref>RemoveStreams</tp:member-ref> (for example, to downgrade
+ an audio-video call to audio-only). The call may be ended by calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembers</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">RemoveMembersWithReason</tp:dbus-ref>; the call ending is signalled by the CM emitting <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">MembersChanged</tp:dbus-ref>,
+ removing both parties from the group.</p>
+
+ <h4>Handler filters</h4>
+
+ <p>For historical reasons, handlers must specify more than one filter if
+ they want to correctly advertise support for audio and/or video calls. If
+ they can handle channels using the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling</tp:dbus-ref>
+ interface, they should also advertise various
+ <tp:type>Handler_Capability_Token</tp:type>s to indicate which codecs and
+ transports they support. See <tp:member-ref>InitialAudio</tp:member-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling/video/h264</tp:dbus-ref>
+ for the gory details. In summary:</p>
+
+ <dl>
+ <dt>To advertise support for streamed media in general, include the
+ following filter in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>:</dt>
+ <dd><pre>
+{ '...Channel.ChannelType': '...Channel.Type.StreamedMedia' ,
+ '...Channel.TargetHandleType': Contact,
+}</pre></dd>
+
+ <dt>To advertise support for audio calls, also include the following
+ filter:</dt>
+ <dd><pre>
+{ '...Channel.ChannelType': '...Channel.Type.StreamedMedia' ,
+ '...Channel.TargetHandleType': Contact,
+ '...Channel.Type.StreamedMedia.InitialAudio': True,
+}</pre></dd>
+
+ <dt>To advertise support for video calls, also include the following
+ filter:</dt>
+ <dd><pre>
+{ '...Channel.ChannelType': '...Channel.Type.StreamedMedia' ,
+ '...Channel.TargetHandleType': Contact,
+ '...Channel.Type.StreamedMedia.InitialVideo': True,
+}</pre></dd>
+
+ <dt>If you use telepathy-farsight, and have H.264 support, you probably
+ want these <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">Capabilities</tp:dbus-ref>:</dt>
+ <dd><pre>
+[ "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/ice-udp",
+ "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/gtalk-p2p",
+ "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/h264",
+]</pre></dd>
+ </dl>
+ </tp:docstring>
+
+ <tp:flags name="Channel_Media_Capabilities" value-prefix="Channel_Media_Capability" type="u">
+ <tp:docstring>
+ The channel-type-specific capability flags used for
+ Channel.Type.StreamedMedia in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.Capabilities</tp:dbus-ref>
+ interface. See the <tp:member-ref>InitialAudio</tp:member-ref>
+ property for details of the mechanisms that will replace this.
+ </tp:docstring>
+ <tp:flag suffix="Audio" value="1">
+ <tp:docstring>
+ The handle is capable of using audio streams within a media channel.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Video" value="2">
+ <tp:docstring>
+ The handle is capable of using video streams within a media channel.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="NAT_Traversal_STUN" value="4">
+ <tp:docstring>
+ The handle is capable of performing STUN to traverse NATs.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="NAT_Traversal_GTalk_P2P" value="8">
+ <tp:docstring>
+ The handle is capable of establishing Google Talk peer-to-peer
+ connections (as implemented in libjingle 0.3) to traverse NATs.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="NAT_Traversal_ICE_UDP" value="16">
+ <tp:docstring>
+ The handle is capable of establishing ICE UDP peer-to-peer
+ connections (as defined by the IETF MMUSIC working group) to traverse
+ NATs.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Immutable_Streams" value="32">
+ <tp:docstring>
+ Channels whose target handle is this contact will have
+ <tp:member-ref>ImmutableStreams</tp:member-ref> = <tt>True</tt>.
+ </tp:docstring>
+ </tp:flag>
+
+ </tp:flags>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Text.xml b/spec/spec/Channel_Type_Text.xml
new file mode 100644
index 000000000..76123293c
--- /dev/null
+++ b/spec/spec/Channel_Type_Text.xml
@@ -0,0 +1,614 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Text" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2009 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.Text">
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:requires
+ interface="org.freedesktop.Telepathy.Channel.Interface.Messages"/>
+ <tp:changed version="0.21.5">The Messages interface is now
+ mandatory</tp:changed>
+ <tp:changed version="0.24.0">This interface used to have a bunch of
+ clunky <tp:dbus-ref
+ namespace='org.freedesktop'>Telepathy.Properties</tp:dbus-ref>. They have
+ been removed in favour of D-Bus properties on the <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Room2</tp:dbus-ref>, <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Subject2</tp:dbus-ref> and
+ <tp:dbus-ref namespace='ofdT.Channel.Interface'>RoomConfig1</tp:dbus-ref>
+ interfaces.</tp:changed>
+
+ <tp:simple-type name="Message_ID" type="u" array-name="Message_ID_List">
+ <tp:docstring>
+ A unique-per-channel identifier for an incoming message. These
+ SHOULD be allocated in a way that minimizes collisions (in particular,
+ message IDs SHOULD NOT be re-used until all of the 32-bit integer
+ space has already been used).
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:struct name="Pending_Text_Message" array-name="Pending_Text_Message_List">
+ <tp:deprecated version="0.21.5">New APIs should use
+ an array of <tp:type>Message_Part</tp:type> instead.</tp:deprecated>
+ <tp:docstring>A struct (message ID, timestamp in seconds since
+ 1970-01-01 00:00 UTC, sender's handle, message type, flags, text)
+ representing a pending text message, as returned by
+ <tp:member-ref>ListPendingMessages</tp:member-ref>. The arguments of
+ the <tp:member-ref>Received</tp:member-ref> signal also match this
+ struct's signature.</tp:docstring>
+ <tp:member type="u" tp:type="Message_ID" name="Identifier"/>
+ <tp:member type="u" tp:type="Unix_Timestamp" name="Unix_Timestamp"/>
+ <tp:member type="u" tp:type="Contact_Handle" name="Sender"/>
+ <tp:member type="u" tp:type="Channel_Text_Message_Type"
+ name="Message_Type"/>
+ <tp:member type="u" tp:type="Channel_Text_Message_Flags" name="Flags"/>
+ <tp:member type="s" name="Text"/>
+ </tp:struct>
+
+ <method name="AcknowledgePendingMessages"
+ tp:name-for-bindings="Acknowledge_Pending_Messages">
+ <arg direction="in" name="IDs" type="au" tp:type="Message_ID[]">
+ <tp:docstring>
+ The IDs of the messages to acknowledge
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the channel that you have handled messages by displaying them to
+ the user (or equivalent), so they can be removed from the pending queue.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ A given message ID was not found, so no action was taken
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetMessageTypes" tp:name-for-bindings="Get_Message_Types">
+ <tp:deprecated version="0.21.5">Consulting
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >MessageTypes</tp:dbus-ref> is preferred.
+ </tp:deprecated>
+ <arg direction="out" type="au" tp:type="Channel_Text_Message_Type[]"
+ name="Available_Types">
+ <tp:docstring>
+ An array of integer message types (ChannelTextMessageType)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Return an array indicating which types of message may be sent on this
+ channel.
+ </tp:docstring>
+ </method>
+
+ <method name="ListPendingMessages"
+ tp:name-for-bindings="List_Pending_Messages">
+ <tp:deprecated version="0.21.5">Consulting
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >PendingMessages</tp:dbus-ref> is preferred.
+ </tp:deprecated>
+ <arg direction="in" name="Clear" type="b">
+ <tp:docstring>
+ If true, behave as if
+ <tp:member-ref>AcknowledgePendingMessages</tp:member-ref> had also
+ been called.
+ </tp:docstring>
+ <tp:deprecated version="0.17.3">
+ Setting this to true is NOT RECOMMENDED for clients that
+ have some sort of persistent message storage - clients SHOULD only
+ acknowledge messages after they have actually stored them, which is
+ impossible if this flag is true.</tp:deprecated>
+ </arg>
+ <arg direction="out" type="a(uuuuus)" tp:type="Pending_Text_Message[]"
+ name="Pending_Messages">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structs representing the pending queue. Each contains:
+ <ul>
+ <li>a numeric identifier</li>
+ <li>a Unix timestamp indicating when the message was received</li>
+ <li>the contact handle for the contact who sent the message</li>
+ <li>the message type, taken from ChannelTextMessageType</li>
+ <li>the bitwise-OR of the message flags from ChannelTextMessageFlags</li>
+ <li>the text of the message</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ List the messages currently in the pending queue, and optionally
+ remove then all.
+ </tp:docstring>
+ </method>
+
+ <signal name="LostMessage" tp:name-for-bindings="Lost_Message">
+ <tp:deprecated version="0.21.5">In practice, this signal
+ was not emitted, and does not have useful semantics.</tp:deprecated>
+ <tp:docstring>
+ This signal is emitted to indicate that an incoming message was
+ not able to be stored and forwarded by the connection manager
+ due to lack of memory.
+ </tp:docstring>
+ </signal>
+
+ <signal name="Received" tp:name-for-bindings="Received">
+ <tp:deprecated version="0.21.5">The
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >MessageReceived</tp:dbus-ref> signal is more informative.
+ </tp:deprecated>
+ <arg name="ID" type="u">
+ <tp:docstring>
+ A numeric identifier for acknowledging the message
+ </tp:docstring>
+ </arg>
+ <arg name="Timestamp" type="u" tp:type="Unix_Timestamp">
+ <tp:docstring>
+ A Unix timestamp indicating when the message was received
+ </tp:docstring>
+ </arg>
+ <arg name="Sender" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the contact who sent the message
+ </tp:docstring>
+ </arg>
+ <arg name="Type" type="u" tp:type="Channel_Text_Message_Type">
+ <tp:docstring>
+ The type of the message (normal, action, notice, etc.)
+ </tp:docstring>
+ </arg>
+ <arg name="Flags" type="u" tp:type="Channel_Text_Message_Flags">
+ <tp:docstring>
+ A bitwise OR of the message flags
+ </tp:docstring>
+ </arg>
+ <arg name="Text" type="s">
+ <tp:docstring>
+ The text of the message
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signals that a message with the given id, timestamp, sender, type
+ and text has been received on this channel. Applications that catch
+ this signal and reliably inform the user of the message should
+ acknowledge that they have dealt with the message with the
+ <tp:member-ref>AcknowledgePendingMessages</tp:member-ref> method.
+ </tp:docstring>
+ </signal>
+
+ <method name="Send" tp:name-for-bindings="Send">
+ <tp:deprecated version="0.21.5">The
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >SendMessage</tp:dbus-ref> method is more flexible.
+ </tp:deprecated>
+ <arg direction="in" name="Type" type="u" tp:type="Channel_Text_Message_Type">
+ <tp:docstring>
+ An integer indicating the type of the message
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Text" type="s">
+ <tp:docstring>
+ The message to send
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that a message be sent on this channel. When the message has
+ been submitted for delivery, this method will return and the
+ <tp:member-ref>Sent</tp:member-ref> signal will be emitted. If the
+ message cannot be submitted for delivery, the method returns an error
+ and no signal is emitted.</p>
+
+ <p>This method SHOULD return before the Sent signal is
+ emitted.</p>
+
+ <tp:rationale>
+ <p>When a Text channel implements the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Messages</tp:dbus-ref>
+ interface, that "SHOULD" becomes a "MUST".</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Channel_Text_Send_Error" type="u">
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ An unknown error occurred
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Offline" value="1">
+ <tp:docstring>
+ The requested contact was offline
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Invalid_Contact" value="2">
+ <tp:docstring>
+ The requested contact is not valid
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Permission_Denied" value="3">
+ <tp:docstring>
+ The user does not have permission to speak on this channel
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Too_Long" value="4">
+ <tp:docstring>
+ The outgoing message was too long and was rejected by the server
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Not_Implemented" value="5">
+ <tp:docstring>
+ The channel doesn't support sending text messages to the requested
+ contact
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <signal name="SendError" tp:name-for-bindings="Send_Error">
+ <tp:deprecated version="0.21.5">Delivery reporting is now
+ provided by the <tp:dbus-ref namespace="ofdT.Channel.Interface"
+ >Messages</tp:dbus-ref> interface.
+ </tp:deprecated>
+ <arg name="Error" type="u" tp:type="Channel_Text_Send_Error">
+ <tp:docstring>
+ The error that occurred
+ </tp:docstring>
+ </arg>
+ <arg name="Timestamp" type="u" tp:type="Unix_Timestamp">
+ <tp:docstring>
+ The Unix timestamp indicating when the message was sent
+ </tp:docstring>
+ </arg>
+ <arg name="Type" type="u" tp:type="Channel_Text_Message_Type">
+ <tp:docstring>
+ The message type
+ </tp:docstring>
+ </arg>
+ <arg name="Text" type="s">
+ <tp:docstring>
+ The text of the message
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Signals that an outgoing message has failed to send. The error
+ will be one of the values from ChannelTextSendError.</p>
+
+ <p>This signal should only be emitted for messages for which
+ <tp:member-ref>Sent</tp:member-ref> has already been emitted and
+ <tp:member-ref>Send</tp:member-ref> has already returned success.</p>
+ </tp:docstring>
+ <tp:changed version="0.17.3">older spec versions claimed that SendError
+ was emitted <em>instead of</em> Sent, rather than <em>in addition
+ to</em> Sent. However, the 0.17.3+ semantics were what we'd always
+ actually implemented.</tp:changed>
+ </signal>
+
+ <signal name="Sent" tp:name-for-bindings="Sent">
+ <tp:deprecated version="0.21.5">The
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >MessageSent</tp:dbus-ref> signal is more informative.
+ </tp:deprecated>
+ <arg name="Timestamp" type="u" tp:type="Unix_Timestamp">
+ <tp:docstring>
+ Unix timestamp indicating when the message was sent
+ </tp:docstring>
+ </arg>
+ <arg name="Type" type="u" tp:type="Channel_Text_Message_Type">
+ <tp:docstring>
+ The message type (normal, action, notice, etc) from
+ ChannelTextMessageType
+ </tp:docstring>
+ </arg>
+ <arg name="Text" type="s">
+ <tp:docstring>
+ The text of the message. If the message was, or will be, altered
+ during transmission, this argument SHOULD reflect what other
+ contacts will receive rather than being a copy of the argument
+ to <tp:member-ref>Send</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Signals that a message has been submitted for sending.</p>
+ </tp:docstring>
+ </signal>
+
+ <tp:enum name="Channel_Text_Message_Type" type="u"
+ array-name="Channel_Text_Message_Type_List">
+ <tp:docstring>
+ The type of message.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Normal" value="0">
+ <tp:docstring>
+ An ordinary chat message. Unknown types SHOULD be treated like this.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Action" value="1">
+ <tp:docstring>
+ An action which might be presented to the user as
+ "* &lt;sender&gt; &lt;action&gt;", such as an IRC CTCP
+ ACTION (typically selected by the "/me" command). For example, the
+ text of the message might be "drinks more coffee".
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Notice" value="2">
+ <tp:docstring>
+ A one-off or automated message not necessarily expecting a reply
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Auto_Reply" value="3">
+ <tp:docstring>
+ An automatically-generated reply message.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Delivery_Report" value="4">
+ <tp:docstring>
+ A delivery report. This message type MUST NOT appear unless the
+ channel supports the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Messages</tp:dbus-ref>
+ interface; see <tp:type>Message_Part</tp:type> for the format that
+ delivery reports must take.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:flags name="Channel_Text_Message_Flags" value-prefix="Channel_Text_Message_Flag" type="u">
+ <tp:deprecated version="0.21.5">The
+ <tp:dbus-ref namespace="ofdT.Channel.Interface"
+ >Messages</tp:dbus-ref> interface has an extensible data structure
+ including separate booleans for most of these flags.
+ </tp:deprecated>
+ <tp:flag suffix="Truncated" value="1">
+ <tp:docstring>
+ The incoming message was truncated to a shorter length by the
+ server or the connection manager.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Non_Text_Content" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The incoming message contained non-text content which cannot be
+ represented by this interface, but has been signalled
+ in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">Messages</tp:dbus-ref>
+ interface.</p>
+
+ <p>Connection managers SHOULD only set this flag if the non-text
+ content appears to be relatively significant (exactly how
+ significant is up to the implementor). The intention is that
+ if this flag is set, clients using this interface SHOULD inform
+ the user that part of the message was not understood.</p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Scrollback" value="4">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The incoming message was part of a replay of message history.</p>
+
+ <tp:rationale>
+ <p>In XMPP multi-user chat, a few past messages are replayed
+ when you join a chatroom. A sufficiently capable IRC connection
+ manager could also set this flag on historical messages when
+ connected to a proxy like bip or irssi-proxy. The existence
+ of this flag allows loggers and UIs to use better heuristics
+ when eliminating duplicates (a simple implementation made
+ possible by this flag would be to avoid logging scrollback
+ at all).</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Rescued" value="8">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The incoming message has been seen in a previous channel during
+ the lifetime of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>, but
+ had not been acknowledged
+ when that channel closed, causing an identical channel (the
+ channel in which the message now appears) to open.</p>
+
+ <tp:rationale>
+ <p>This means that a logger (which should already have seen the
+ message in the previous channel) is able to recognise and ignore
+ these replayed messages.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A channel type for sending and receiving messages. This channel type
+ is primarily used for textual messages, but can also be used for
+ formatted text, text with "attachments", or binary messages on some
+ protocols.</p>
+
+ <p>Most of the methods and signals on this interface are deprecated,
+ since they only support plain-text messages with limited metadata.
+ See the mandatory <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Messages</tp:dbus-ref>
+ interface for the modern equivalents.</p>
+
+ <p>When a message is received, an identifier is assigned and a
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >MessageReceived</tp:dbus-ref> signal emitted, and the message
+ is placed in a pending queue represented by the
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >PendingMessages</tp:dbus-ref> property.
+ When the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ for a channel has handled the message by showing it to the user
+ (or equivalent), it should acknowledge the receipt of that message
+ using the <tp:member-ref>AcknowledgePendingMessages</tp:member-ref>
+ method, and the message will then be removed from the pending queue.
+ Numeric identifiers for received messages may be reused over the
+ lifetime of the channel.</p>
+
+ <p>Sending messages can be requested using the
+ <tp:dbus-ref namespace="ofdT.Channel.Interface.Messages"
+ >SendMessage</tp:dbus-ref> method, which will return
+ successfully when the message has been submitted for sending, or
+ return an error with no signal emission if there is an immediate
+ failure. If a message is submitted for sending but delivery of the
+ message later fails, this is indicated by a delivery report, which
+ is received in the same way as an incoming message.</p>
+
+ <p>Simple one-to-one chats (such as streams of private messages in
+ XMPP or IRC) should be represented by a Text channel whose
+ <tp:dbus-ref namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref>
+ is <tp:value-ref type="Handle_Type">Contact</tp:value-ref>. The
+ expected way to request such a channel is to set the <tp:dbus-ref
+ namespace='ofdT.Channel'>ChannelType</tp:dbus-ref>, <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>,
+ and either <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandle</tp:dbus-ref> or <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetID</tp:dbus-ref> in a call to
+ <tp:dbus-ref
+ namespace='ofdT.ChannelDispatcher'>EnsureChannel</tp:dbus-ref>.</p>
+
+ <p>Named chat rooms whose identity can be saved and used again later
+ (IRC channels, Jabber MUCs) are expected to be represented by Text
+ channels with <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref> =
+ <tp:value-ref type="Handle_Type">Room</tp:value-ref> and the
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">Group</tp:dbus-ref>
+ interface. In protocols where a chatroom can be used as a continuation
+ of one or more one-to-one chats, these channels should also have the
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">Conference</tp:dbus-ref>
+ interface.</p>
+
+ <p>Unnamed, transient chat rooms which cannot be rejoined by their
+ unique identifier (e.g. a conversation on MSN which has, or once had,
+ three or more participants) are expected to be represented by Text
+ channels with <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref> = <tp:value-ref
+ type="Handle_Type">None</tp:value-ref> (and hence <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandle</tp:dbus-ref> = 0),
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">Group</tp:dbus-ref>
+ interface, and optionally the
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">Conference</tp:dbus-ref>
+ interface.</p>
+
+ <p>On protocols like MSN where a conversation with a user is actually
+ just a nameless chat room starting with exactly two members, to which
+ more members can be invited, the initial one-to-one conversation
+ SHOULD be represented with <tp:dbus-ref
+ namespace="ofdT.Channel">TargetHandleType</tp:dbus-ref> =
+ <tp:value-ref type="Handle_Type">Contact</tp:value-ref>. If a third
+ participant
+ joins or is invited, this SHOULD be represented by signalling
+ a new <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Conference</tp:dbus-ref> channel
+ with the one-to-one channel in its <tp:dbus-ref
+ namespace="ofdT.Channel.Interface.Conference"
+ >InitialChannels</tp:dbus-ref>, migrating the underlying protocol
+ object from the one-to-one channel to the Conference channel,
+ and creating a new protocol-level conversation if the one-to-one
+ channel is re-used. See the Conference interface for more details.</p>
+
+ <tp:rationale>
+ <p>This keeps the presentation of all one-to-one conversations
+ uniform, and makes it easier to hand over a conversation from a
+ 1-1-specific UI to a more elaborate multi-user UI; while it does
+ require UIs to understand Conference to follow the
+ upgrade, UIs that will deal with XMPP need to understand Conference
+ anyway.</p>
+ </tp:rationale>
+
+ <p>If a channel of type Text is closed while it has pending messages,
+ the connection manager MUST allow this, but SHOULD open a new channel
+ to deliver those messages, signalling it as a new channel with the
+ <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal. The new channel should resemble the old channel, but have
+ <tp:dbus-ref namespace='ofdT.Channel'>Requested</tp:dbus-ref> = FALSE
+ regardless of its previous value; the <tp:dbus-ref
+ namespace='ofdT.Channel'>InitiatorHandle</tp:dbus-ref>
+ and <tp:dbus-ref namespace='ofdT.Channel'>InitiatorID</tp:dbus-ref>
+ should correspond to the sender of one of the pending
+ messages.</p>
+
+ <tp:rationale>
+ <p>In effect, this turns this situation, in which a client
+ is likely to lose messages:</p>
+
+ <ul>
+ <li>UI window is closed</li>
+ <li>message arrives</li>
+ <li>text channel emits Received</li>
+ <li>UI calls Close on text channel before it has seen the
+ Received signal</li>
+ <li>text channel emits Closed and closes</li>
+ </ul>
+
+ <p>into something nearly equivalent to this situation, which is
+ fine:</p>
+
+ <ul>
+ <li>UI window is closed</li>
+ <li>UI calls Close on text channel</li>
+ <li>text channel emits Closed and closes</li>
+ <li>message arrives</li>
+ <li>new text channel is created, connection emits NewChannels</li>
+ <li>(the same or a different) UI handles it</li>
+ </ul>
+
+ <p>Requested must be set to FALSE so the replacement channel
+ will be handled by something.</p>
+
+ <p>In practice, connection managers usually implement this by keeping
+ the same internal object that represented the old channel, adjusting
+ its properties, signalling that it was closed, then immediately
+ re-signalling it as a new channel.</p>
+ </tp:rationale>
+
+ <p>As a result, Text channels SHOULD implement <tp:dbus-ref
+ namespace="ofdT">Channel.Interface.Destroyable</tp:dbus-ref>.</p>
+
+ <tp:rationale>
+ <p>This "respawning" behaviour becomes problematic if there is no
+ suitable handler for Text channels, or if a particular message
+ repeatedly crashes the Text channel handler; a channel dispatcher
+ can't just Close() the channel in these situations, because
+ it will come back.</p>
+
+ <p>In these situations, the channel dispatcher needs a last-resort
+ way to destroy the channel and stop it respawning. It could either
+ acknowledge the messages itself, or use the Destroyable interface;
+ the Destroyable interface has the advantage that it's not
+ channel-type-dependent, so the channel dispatcher only has to
+ understand one extra interface, however many channel types
+ eventually need a distinction between Close and Destroy.</p>
+ </tp:rationale>
+
+ <p>Opaquely-named rejoinable chatrooms (such as Skype rooms) are
+ represented using the properties in the <tp:dbus-ref
+ namespace="ofdT.Channel.Interface">Room2</tp:dbus-ref>
+ interface. Instructions and examples of how to request
+ such channels are given in said interface's description.</p>
+
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Channel_Type_Tubes.xml b/spec/spec/Channel_Type_Tubes.xml
new file mode 100644
index 000000000..c0a973faa
--- /dev/null
+++ b/spec/spec/Channel_Type_Tubes.xml
@@ -0,0 +1,615 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Type_Tubes" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>
+ Copyright © 2007-2009 Collabora Limited
+ </tp:copyright>
+ <tp:license>
+ This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Channel.Type.Tubes">
+
+ <tp:deprecated version="0.17.25">Client implementations
+ SHOULD use <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamTube</tp:dbus-ref> and
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">DBusTube</tp:dbus-ref>
+ instead.</tp:deprecated>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A "tube" is a mechanism for arbitrary data transfer. Two types of
+ data transfer are currently specified: D-Bus messages, and streams of
+ bytes. Each tube has a service name, which is a string specifying the
+ kind of communication that takes place over it, and a dictionary of
+ arbitrary parameters. Tube parameters are commonly used for bootstrap
+ information such as usernames and passwords. Each tube is identified
+ by a locally unique identifier.</p>
+
+ <p>The Tubes channel type may be requested for handles of type
+ HANDLE_TYPE_CONTACT and HANDLE_TYPE_ROOM.</p>
+
+ <p>Stream tubes specify listening addresses using pairs of parameters
+ with signature 'u', 'v', where the integer 'u' is a member of
+ Socket_Address_Type and the v is dependent on the type of address.</p>
+ </tp:docstring>
+
+ <tp:simple-type name="Tube_ID" type="u">
+ <tp:docstring>An identifier for a tube. These are local to a Tubes
+ channel, and may not be assumed to be the same as the other
+ participants' idea of the tube identifier.</tp:docstring>
+ </tp:simple-type>
+
+ <tp:struct name="Tube_Info" array-name="Tube_Info_List">
+ <tp:docstring>A struct (tube ID, initiator handle, tube type,
+ service name, parameters, state) representing a tube, as returned
+ by ListTubes on the Tubes channel type.</tp:docstring>
+ <tp:member type="u" tp:type="Tube_ID" name="Identifier"/>
+ <tp:member type="u" tp:type="Contact_Handle" name="Initiator"/>
+ <tp:member type="u" tp:type="Tube_Type" name="Type"/>
+ <tp:member type="s" name="Service"/>
+ <tp:member type="a{sv}" tp:type="String_Variant_Map" name="Parameters"/>
+ <tp:member type="u" tp:type="Tube_State" name="State"/>
+ </tp:struct>
+
+ <tp:struct name="DBus_Tube_Member" array-name="DBus_Tube_Member_List">
+ <tp:docstring>Represents a participant in a multi-user D-Bus tube, as
+ returned by <tp:member-ref>GetDBusNames</tp:member-ref> and seen in the
+ <tp:member-ref>DBusNamesChanged</tp:member-ref> signal.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle">
+ <tp:docstring>
+ The handle of a participant in this D-Bus tube.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" tp:type="DBus_Unique_Name" name="Unique_Name">
+ <tp:docstring>
+ That participant's unique name.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:enum name="Tube_Type" type="u" array-name="Tube_Type_List">
+ <tp:enumvalue suffix="DBus" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The tube is D-Bus tube as described by the
+ org.freedesktop.Telepathy.Channel.Type.DBusTube interface.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Stream" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The tube is stream tube as described by the
+ org.freedesktop.Telepathy.Channel.Type.StreamTube interface.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Tube_State" type="u">
+ <tp:enumvalue suffix="Local_Pending" value="0">
+ <tp:docstring>
+ The tube is waiting to be accepted/closed locally.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Remote_Pending" value="1">
+ <tp:docstring>
+ The tube is waiting to be accepted/closed remotely.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Open" value="2">
+ <tp:docstring>
+ The tube is open for traffic.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:mapping name="Supported_Socket_Map">
+ <tp:docstring>The supported socket address and access-control types
+ for tubes. See GetAvailableStreamTubeTypes.</tp:docstring>
+ <tp:member name="Address_Type" type="u" tp:type="Socket_Address_Type"/>
+ <tp:member name="Access_Control" type="au"
+ tp:type="Socket_Access_Control[]"/>
+ </tp:mapping>
+
+ <method name="GetAvailableStreamTubeTypes"
+ tp:name-for-bindings="Get_Available_Stream_Tube_Types">
+ <tp:docstring>List the available address types and access-control types
+ for stream tubes.</tp:docstring>
+ <arg direction="out" type="a{uau}" tp:type="Supported_Socket_Map"
+ name="Available_Stream_Tube_Types">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping from address types (members of Socket_Address_Type) to
+ arrays of access-control type (members of Socket_Access_Control)
+ that the connection manager supports for stream tubes with that
+ address type. For simplicity, if a CM supports offering a
+ particular type of tube, it is assumed to support accepting it.</p>
+
+ <p>A typical value for a host without IPv6 support:</p>
+
+ <pre>
+ {
+ Socket_Address_Type_IPv4:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Port,
+ Socket_Access_Control_Netmask],
+ Socket_Address_Type_Unix:
+ [Socket_Access_Control_Localhost, Socket_Access_Control_Credentials]
+ }
+ </pre>
+
+ <p>If stream tubes are not supported, this will be an empty
+ dictionary.</p>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="GetAvailableTubeTypes"
+ tp:name-for-bindings="Get_Available_Tube_Types">
+ <arg direction="out" type="au" tp:type="Tube_Type[]"
+ name="Available_Tube_Types">
+ <tp:docstring>
+ An array of the available tube types, as defined by the Tube_Type
+ enum.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="ListTubes" tp:name-for-bindings="List_Tubes">
+ <arg direction="out" type="a(uuusa{sv}u)" tp:type="Tube_Info[]"
+ name="Tubes">
+ <tp:docstring>
+ Return an array of tuples, each representing a tube, with the
+ following members:
+
+ <ul>
+ <li>the tube's ID</li>
+ <li>the tube's initiator</li>
+ <li>the tube's type</li>
+ <li>the tube's service</li>
+ <li>the tube's parameters</li>
+ <li>the tube's state</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <!-- this tp:name-for-bindings is ugly, but compatible with
+ the code generation in telepathy-glib versions that did not use
+ tp:name-for-bindings -->
+ <method name="OfferDBusTube" tp:name-for-bindings="Offer_D_Bus_Tube">
+ <tp:docstring>
+ Offers a D-Bus tube providing the service specified.
+ </tp:docstring>
+ <arg direction="in" name="Service" type="s">
+ <tp:docstring>
+ A string representing the service name that will be used over the
+ tube.
+ It should be a well-known D-Bus service name, of the form
+ com.example.ServiceName.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Parameters" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring>
+ A dictionary of properties for the new tube; the allowable keys,
+ types and values are defined by the service. Connection managers
+ must support the value being any primitive (non-container)
+ D-Bus type, or a byte array 'ay'.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="u" tp:type="Tube_ID" name="Tube_ID">
+ <tp:docstring>
+ The ID of the new tube.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact associated with this channel doesn't have tubes
+ capabilities.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The connection manager doesn't support D-Bus tubes.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="OfferStreamTube" tp:name-for-bindings="Offer_Stream_Tube">
+ <tp:docstring>
+ Offer a stream tube exporting the local socket specified.
+ </tp:docstring>
+ <arg direction="in" name="Service" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ A string representing the service name that will be used over the
+ tube.
+ It should be a well-known TCP service name as defined by
+ <a href="http://www.iana.org/assignments/port-numbers">
+ http://www.iana.org/assignments/port-numbers</a> or
+ <a href="http://www.dns-sd.org/ServiceTypes.html">
+ http://www.dns-sd.org/ServiceTypes.html</a>, for instance
+ "rsync" or "daap".
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Parameters" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary of properties for the new tube; the allowable keys,
+ types and values are defined by the service. Connection managers
+ must support the value being any primitive (non-container)
+ D-Bus type, or a byte array 'ay'.</p>
+ <p>These should usually be the same key-value pairs specified for
+ use in the DNS-SD TXT record for that service.</p>
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Address_Type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of the listening address of the local service, as a member of
+ Socket_Address_Type.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Address" type="v">
+ <tp:docstring>
+ The listening address of the local service, as indicated by the
+ address_type.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The access control the local service applies to the local socket,
+ specified so the connection manager can behave appropriately
+ when it connects.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control_Param" type="v">
+ <tp:docstring>
+ A parameter for the access control type, to be interpreted as
+ specified in the documentation for the Socket_Access_Control enum.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="u" tp:type="Tube_ID" name="Tube_ID">
+ <tp:docstring>
+ The ID of the new tube.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact associated with this channel doesn't have tube
+ capabilities.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The connection manager doesn't support stream tubes, or
+ does not support the given address type or access-control type.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="NewTube" tp:name-for-bindings="New_Tube">
+ <tp:docstring>
+ Emitted when a tube is created.
+ </tp:docstring>
+ <arg name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the new tube.
+ </tp:docstring>
+ </arg>
+ <arg name="Initiator" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the contact who initiated the tube.
+ </tp:docstring>
+ </arg>
+ <arg name="Type" type="u" tp:type="Tube_Type">
+ <tp:docstring>
+ The tube type, as defined by the Tube_Type enum.
+ </tp:docstring>
+ </arg>
+ <arg name="Service" type="s">
+ <tp:docstring>
+ A string representing the service that will be used over the tube.
+ </tp:docstring>
+ </arg>
+ <arg name="Parameters" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring>
+ The new tube's properties.
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Tube_State">
+ <tp:docstring>
+ The new tube's state.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <!-- this tp:name-for-bindings is ugly, but compatible with
+ the code generation in telepathy-glib versions that did not use
+ tp:name-for-bindings -->
+ <method name="AcceptDBusTube" tp:name-for-bindings="Accept_D_Bus_Tube">
+ <tp:docstring>
+ Accept a D-Bus tube that's in the "local pending" state. The
+ connection manager will attempt to open the tube. The tube remains in
+ the "local pending" state until the TubeStateChanged signal is
+ emitted.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube to accept.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address" type="s">
+ <tp:docstring>
+ The string describing the address of the private bus. The client
+ should not attempt to connect to the address until the tube is open.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The given tube ID is invalid or does not refer to a D-Bus
+ tube.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AcceptStreamTube" tp:name-for-bindings="Accept_Stream_Tube">
+ <tp:docstring>
+ Accept a stream tube that's in the "local pending" state. The
+ connection manager will attempt to open the tube. The tube remains in
+ the "local pending" state until the TubeStateChanged signal is
+ emitted.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube to accept.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Address_Type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of address the connection manager should listen on.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control" type="u" tp:type="Socket_Access_Control">
+ <tp:docstring>
+ The type of access control the connection manager should apply to
+ the socket.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Access_Control_Param" type="v">
+ <tp:docstring>
+ A parameter for the access control type, to be interpreted as
+ specified in the documentation for the Socket_Access_Control enum.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address" type="v">
+ <tp:docstring>
+ The address on which the connection manager will listen for
+ connections to this tube. The client should not attempt to connect
+ to the address until the tube is open.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The given tube ID is invalid or does not refer to a stream
+ tube.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The given address type or access-control mechanism is not supported.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="TubeStateChanged" tp:name-for-bindings="Tube_State_Changed">
+ <tp:docstring>
+ Emitted when the state of a tube changes.
+ </tp:docstring>
+ <arg name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube that changed state.
+ </tp:docstring>
+ </arg>
+ <arg name="State" type="u" tp:type="Tube_State">
+ <tp:docstring>
+ The new state of the tube; see the Tube_State enumeration.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="CloseTube" tp:name-for-bindings="Close_Tube">
+ <tp:docstring>
+ Close a tube.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube to close.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument" />
+ </tp:possible-errors>
+ </method>
+
+ <signal name="TubeClosed" tp:name-for-bindings="Tube_Closed">
+ <tp:docstring>
+ Emitted when a tube has been closed. The ID of a closed tube is no
+ longer valid. The ID may later be reused for a new tube.
+ </tp:docstring>
+ <arg name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube that was closed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <!-- this tp:name-for-bindings is ugly, but compatible with
+ the code generation in telepathy-glib versions that did not use
+ tp:name-for-bindings -->
+ <method name="GetDBusTubeAddress"
+ tp:name-for-bindings="Get_D_Bus_Tube_Address">
+ <tp:docstring>
+ For a D-Bus tube, return a string describing the address of the
+ private bus.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube to get an address for.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="s" name="Address">
+ <tp:docstring>
+ The bus address.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The tube is not a D-Bus tube.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This tube is not in the "open" state.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <!-- this tp:name-for-bindings is ugly, but compatible with
+ the code generation in telepathy-glib versions that did not use
+ tp:name-for-bindings -->
+ <method name="GetDBusNames" tp:name-for-bindings="Get_D_Bus_Names">
+ <tp:docstring>
+ For a multi-user (i.e. Handle_Type_Room) D-Bus tube, obtain a mapping
+ between contact handles and their unique bus names on this tube.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube to get names for.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a(us)" tp:type="DBus_Tube_Member[]"
+ name="DBus_Names">
+ <tp:docstring>
+ An array of structures, each containing a contact handle and a D-Bus
+ bus name.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The tube is not a multi-user D-Bus tube.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This tube is not in the "open" state.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <!-- this tp:name-for-bindings is ugly, but compatible with
+ the code generation in telepathy-glib versions that did not use
+ tp:name-for-bindings -->
+ <signal name="DBusNamesChanged" tp:name-for-bindings="D_Bus_Names_Changed">
+ <tp:docstring>
+ Emitted on a multi-user (i.e. Handle_Type_Room) D-Bus tube when a
+ participant opens or closes the tube.
+ </tp:docstring>
+ <arg name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube whose names have changed.
+ </tp:docstring>
+ </arg>
+ <arg name="Added" type="a(us)" tp:type="DBus_Tube_Member[]">
+ <tp:docstring>
+ Array of handles and D-Bus names of new participants.
+ </tp:docstring>
+ </arg>
+ <arg name="Removed" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ Array of handles of former participants.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="GetStreamTubeSocketAddress"
+ tp:name-for-bindings="Get_Stream_Tube_Socket_Address">
+ <tp:docstring>
+ For a stream tube, obtain the address of the socket used to
+ communicate over this tube.
+ </tp:docstring>
+ <arg direction="in" name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the stream tube to get the socket for.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address_Type" type="u" tp:type="Socket_Address_Type">
+ <tp:docstring>
+ The type of the listening address of the socket, as a member of
+ Socket_Address_Type.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Address" type="v">
+ <tp:docstring>
+ The listening address of the socket, as indicated by the
+ address_type.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The tube is not a stream tube.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ This tube is not in the "open" state.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="StreamTubeNewConnection"
+ tp:name-for-bindings="Stream_Tube_New_Connection">
+ <tp:docstring>
+ Emitted on a stream tube when a participant opens a new connection
+ to its socket.
+ </tp:docstring>
+ <arg name="ID" type="u" tp:type="Tube_ID">
+ <tp:docstring>
+ The ID of the tube
+ </tp:docstring>
+ </arg>
+ <arg name="Handle" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the participant who opened the new connection
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client.xml b/spec/spec/Client.xml
new file mode 100644
index 000000000..19f691495
--- /dev/null
+++ b/spec/spec/Client.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" ?>
+<node name="/Client"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Telepathy clients use connection managers, the channel dispatcher
+ and optionally the account manager to provide useful
+ functionality.</p>
+
+ <p>User interface processes are the obvious example of Telepathy
+ clients, but they can provide other functionality, such as
+ address-book synchronization.</p>
+
+ <p>Every running or activatable process with a well-known
+ name of the form org.freedesktop.Telepathy.Client.<em>clientname</em>
+ should be probed by the channel dispatcher to discover its
+ capabilities. Each client is either an <em>observer</em>, an
+ <em>approver</em>, a <em>channel handler</em>, or some combination
+ of these.</p>
+
+ <tp:rationale>
+ <p>Activatable services (those with a D-Bus <code>.service</code>
+ file) must be supported so that we can run clients
+ in response to channel creation.</p>
+
+ <p>Non-activatable services (those that do not register a D-Bus
+ <code>.service</code> file for their well-known name, but do
+ request it at runtime) must be supported so that we can have
+ programs that process channels, but only if they are already
+ running - for instance, a full-screen media centre
+ application might do this.</p>
+ </tp:rationale>
+
+ <p>The client name, <em>clientname</em>, MUST be a non-empty string of
+ ASCII digits, letters, dots and/or underscores, starting with a
+ letter, and without sets of two consecutive dots or a dot
+ followed by a digit. For non-activatable services, it MAY contain a
+ part that is generated per instance at runtime.</p>
+
+ <tp:rationale>
+ <p>If each of a client Foo's instances should be able to manipulate
+ channels separately, the instance with unique name
+ <code>:1.25</code> might request a well-known name like
+ <code>org.freedesktop.Telepathy.Client.Foo._1._25</code>.</p>
+
+ <p>(Note that well-known bus-name components may not start with a
+ digit, so o.f.T.Client.Foo.1.25 would not be acceptable.)</p>
+ </tp:rationale>
+
+ <p>Each Client MUST export an object whose object path may be
+ determined by replacing '.' with '/' in the well-known name and
+ prepending '/'. This object represents its API as a Telepathy
+ client; the channel dispatcher will call its methods and read
+ its properties when appropriate.</p>
+
+ <p>As an optimization, activatable clients SHOULD install a file
+ <code><a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">$XDG_DATA_DIRS</a>/telepathy/clients/<em>clientname</em>.client</code>
+ containing a cached version of its immutable properties,
+ so that for most clients, the channel dispatcher can
+ just read a file to discover capabilities, instead of
+ having to service-activate the client immediately in order to fetch
+ its read-only properties. However, the D-Bus API is canonical, and
+ the channel dispatcher MUST support clients without such a file.</p>
+
+ <p>Non-activatable clients MAY install a <code>.client</code> file,
+ but there's not much point in them doing so.</p>
+
+ <p>The .client files MUST contain UTF-8 text with the same syntax
+ as
+ <a href="http://standards.freedesktop.org/desktop-entry-spec/latest/">Desktop
+ Entry files</a> (although the allowed groups, keys and values differ).
+ Every <code>.client</code> file MUST contain a group whose name is
+ the name of this interface.</p>
+
+ <p>The groups, keys and values in the <code>.client</code> file are
+ defined by individual interfaces. Each interface that can usefully
+ cache information in the <code>.client</code> file SHOULD correspond
+ to a group with the same name.</p>
+ </tp:docstring>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read" tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of the extra interfaces provided by this client.
+ This SHOULD include at least one of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Observer</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Approver</tp:dbus-ref> or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Handler</tp:dbus-ref>.</p>
+
+ <p>In the <code>.client</code> file, this is represented by key
+ "<code>Interfaces</code>" in the group named after this interface.
+ The value of the key is a list of interface names each followed by
+ a semicolon (so it always ends with a semicolon unless it is empty),
+ i.e. a key of type "strings" as described in the Desktop Entry
+ specification.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client_Approver.xml b/spec/spec/Client_Approver.xml
new file mode 100644
index 000000000..12cbc76ac
--- /dev/null
+++ b/spec/spec/Client_Approver.xml
@@ -0,0 +1,201 @@
+<?xml version="1.0" ?>
+<node name="/Client_Approver"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client.Approver">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Client"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Approvers are clients that notify the user that new channels have
+ been created by a contact, and allow the user to accept or reject
+ those channels. The new channels are represented by a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation</tp:dbus-ref>
+ object, which is passed to the
+ <tp:member-ref>AddDispatchOperation</tp:member-ref> method.</p>
+
+ <tp:rationale>
+ <p>For instance, Empathy's tray icon, or the answer/reject window
+ seen when a Maemo device receives a VoIP call, should be
+ Approvers.</p>
+ </tp:rationale>
+
+ <p>Approvers can also select which channel handler will be used for the
+ channel, for instance by offering the user a list of possible
+ handlers rather than just an accept/reject choice.
+ However, the Channel Dispatcher must be able to prioritize
+ possible handlers on its own using some reasonable heuristic,
+ probably based on user configuration.</p>
+
+ <p>It is possible (and useful) to have an approver and
+ a channel handler in the same process; this is particularly useful
+ if a channel handler wants to claim responsibility for particular
+ channels itself.</p>
+
+ <p>All approvers are notified simultaneously. For instance, in a
+ desktop system, there might be one approver that displays a
+ notification-area icon, one that is part of a contact list
+ window and highlights contacts there, and one that is part
+ of a full-screen media player.</p>
+
+ <p>Any approver can approve the handling of a channel dispatch operation
+ with a particular channel handler by calling the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">HandleWith</tp:dbus-ref>
+ method. Approvers can also attempt to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Claim</tp:dbus-ref>
+ channels; if this succeeds, the approver may handle the channels
+ itself (if it is also a Handler), or close the channels in order to
+ reject them.</p>
+
+ <p>At the D-Bus level, there is no "reject" operation: approvers wishing
+ to reject channels SHOULD call the Claim method, then (if it succeeds)
+ close the channels in any way they see fit.</p>
+
+ <p>The first approver to reply gets its decision acted on; any other
+ approvers that reply at approximately the same time will get a D-Bus
+ error, indicating that the channel has already been dealt with.</p>
+
+ <p>Approvers should usually prompt the user and ask for
+ confirmation, rather than dispatching the channel to a handler
+ straight away.</p>
+
+ <p>Non-interactive approvers can also be implemented as
+ <tp:dbus-ref namespace="ofdT.Client">Observer</tp:dbus-ref>s as
+ described in the interface description.</p>
+ </tp:docstring>
+
+ <property name="ApproverChannelFilter"
+ tp:name-for-bindings="Approver_Channel_Filter"
+ type="aa{sv}" access="read" tp:type="Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A specification of the channels in which this approver is
+ interested. The <tp:member-ref>AddDispatchOperation</tp:member-ref>
+ method should be called by the channel dispatcher whenever at least
+ one of the channels in a channel dispatch operation matches this
+ description.</p>
+
+ <p>This property works in exactly the same way as the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Observer.ObserverChannelFilter</tp:dbus-ref>
+ property. In particular, it cannot change while the approver process
+ continues to own the corresponding Client bus name.</p>
+
+ <p>In the .client file, it is represented in the
+ same way as ObserverChannelFilter, but the group has the same
+ name as this interface and the keys start with
+ ApproverChannelFilter instead of ObserverChannelFilter.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="AddDispatchOperation"
+ tp:name-for-bindings="Add_Dispatch_Operation">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by the channel dispatcher when a ChannelDispatchOperation
+ in which the approver has registered an interest is created,
+ or when the approver starts up while such channel dispatch
+ operations already exist.</p>
+
+ <p>The channel dispatcher SHOULD call this method on all approvers
+ at the same time. If an approver returns an error from this method,
+ the approver is assumed to be faulty.</p>
+
+ <p>If no approvers return from this method
+ successfully (including situations where there are no matching
+ approvers at all), the channel dispatcher SHOULD consider this
+ to be an error, and recover by dispatching the channel to the
+ most preferred handler.</p>
+
+ <tp:rationale>
+ Processes that aren't approvers (or don't at least ensure that there
+ is some approver) probably shouldn't be making connections
+ anyway, so there should always be at least one approver running.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Channels" direction="in"
+ type="a(oa{sv})" tp:type="Channel_Details[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The initial value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation.Channels</tp:dbus-ref>
+ property, containing the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s
+ to be dispatched and their properties.</p>
+
+ <tp:rationale>
+ <p>This can't be signalled to the approver through the Properties
+ parameter of this method, because Channels is not an immutable
+ property.</p>
+ </tp:rationale>
+
+ <p>This argument always contains all of the channels in the channel
+ dispatch operation, even if not all of them actually match
+ the <tp:member-ref>ApproverChannelFilter</tp:member-ref>.</p>
+
+ <tp:rationale>
+ <p>This seems the least bad way to handle such a situation;
+ see the discussion on
+ <a href="http://bugs.freedesktop.org/show_bug.cgi?id=21090">bug
+ #21090</a>.</p>
+ </tp:rationale>
+
+ <p>The actual channels to be dispatched may reduce as channels are
+ closed: this is signalled by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation.ChannelLost</tp:dbus-ref>.
+ </p>
+
+ <p>Approvers SHOULD connect to ChannelLost and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation.Finished</tp:dbus-ref>.
+ (if desired) before returning from AddDispatchOperation, since
+ those signals are guaranteed not to be emitted until after all
+ AddDispatchOperation calls have returned (with success or failure)
+ or timed out.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="DispatchOperation" type="o" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">ChannelDispatchOperation</tp:dbus-ref>
+ to be processed.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map" direction="in">
+ <tp:docstring>
+ <p>Properties of the channel dispatch operation. The keys MUST be
+ fully qualified D-Bus property names. This MUST NOT include
+ properties that could change, SHOULD include as many properties as
+ possible given that constraint, and MUST include at least the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Account</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Connection</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">PossibleHandlers</tp:dbus-ref>
+ properties.</p>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client_Handler.xml b/spec/spec/Client_Handler.xml
new file mode 100644
index 000000000..3a922e8cc
--- /dev/null
+++ b/spec/spec/Client_Handler.xml
@@ -0,0 +1,337 @@
+<?xml version="1.0" ?>
+<node name="/Client_Handler"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client.Handler">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Client"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Handlers are the user interface for a channel. They turn an abstract
+ Telepathy channel into something the user wants to see, like a text
+ message stream or an audio and/or video call.</p>
+
+ <p>For its entire lifetime, each channel on a connection known to the
+ channel dispatcher is either being processed by the channel dispatcher,
+ or being handled by precisely one Handler.</p>
+
+ <p>Because each channel is only handled by one Handler, handlers may
+ perform actions that only make sense to do once, such as acknowledging
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ messages, doing the actual streaming for <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ channels with the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling</tp:dbus-ref>
+ interface, or transferring the file in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">FileTransfer</tp:dbus-ref>
+ channels.</p>
+
+ <p>When a new incoming channel (one with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
+ = FALSE) is offered to
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref>s
+ by the channel dispatcher, it also offers the Approvers a list of all
+ the running or activatable handlers whose
+ <tp:member-ref>HandlerChannelFilter</tp:member-ref> property
+ (possibly as cached in the .client file) indicates that they
+ are able to handle the channel. The Approvers can choose one of
+ those channel handlers to handle the channel.</p>
+
+ <p>When a new outgoing channel (one with
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
+ = TRUE) appears, the channel dispatcher passes it to an appropriate
+ channel handler automatically.
+ </p>
+
+ </tp:docstring>
+
+ <property name="HandlerChannelFilter"
+ tp:name-for-bindings="Handler_Channel_Filter"
+ type="aa{sv}" access="read" tp:type="Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A specification of the channels that this channel handler can
+ deal with. It will be offered to approvers as a potential
+ channel handler for bundles that contain only suitable channels,
+ or for suitable channels that must be handled separately.</p>
+
+ <p>This property works in exactly the same way as the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Client.Observer.ObserverChannelFilter</tp:dbus-ref>
+ property. In particular, it cannot change while the handler process
+ continues to own the corresponding Client bus name.</p>
+
+ <p>In the .client file, it is represented in the
+ same way as ObserverChannelFilter, but the group has the same
+ name as this interface and the keys start with
+ HandlerChannelFilter instead of ObserverChannelFilter.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="BypassApproval" tp:name-for-bindings="Bypass_Approval"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, channels destined for this handler are automatically
+ handled, without invoking approvers.</p>
+
+ <tp:rationale>
+ <p>The intended usage is to allow a client handling one channel to
+ pick up closely related channels. Suppose a client capable of
+ handling both Text and StreamedMedia,
+ <code>org.freedesktop.Telepathy.Client.Empathy</code>, is
+ handling a StreamedMedia channel. That client can take a second
+ well-known bus name, say
+ <code>org.freedesktop.Telepathy.Client.Empathy._1._42.Bundle1</code>,
+ and configure an object at
+ <code>/org/freedesktop/Telepathy/Client/Empathy/_1/_42/Bundle1</code>
+ with BypassApproval = TRUE,
+ whose <tp:member-ref>HandlerChannelFilter</tp:member-ref>
+ matches closely related Text channels by their Bundle property.</p>
+ </tp:rationale>
+
+ <p>For service-activatable handlers, this property should be specified
+ in the handler's <tt>.client</tt> file as follows:</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client.Handler]
+BypassApproval=true
+</pre>
+ </tp:docstring>
+ </property>
+
+ <tp:simple-type name="Handler_Capability_Token" type="s"
+ array-name="Handler_Capability_Token_List">
+ <tp:docstring>
+ A <tp:type>DBus_Interface</tp:type>, followed by a slash '/' character
+ and an identifier for a capability defined by that interface. The
+ capability identifier SHOULD be in lower case. If an interface
+ references an external specification which is case-insensitive (such
+ as MIME), then names from that specification MUST be normalized to
+ lower-case before providing them to this Telepathy API, so that
+ implementations can safely rely on simple byte-by-byte comparison.
+
+ <tp:rationale>
+ These aren't D-Bus core Properties, and we want them to look visibly
+ different.
+ </tp:rationale>
+
+ <p>So far, all client capabilities are defined by the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface">MediaSignalling</tp:dbus-ref>
+ interface.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <property name="Capabilities" tp:name-for-bindings="Capabilities"
+ type="as" tp:type="Handler_Capability_Token[]" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The set of additional capabilities supported by this handler.
+ This describes things like support for streamed media codecs and
+ NAT traversal mechanisms: see the Contact Capabilities
+ interface for more details.</p>
+
+ <p>For handlers that have a <code>.client</code> file, the
+ channel dispatcher may discover this property from the
+ <code>org.freedesktop.Telepathy.Client.Handler.Capabilities</code>
+ group; for each capability, that group contains a key
+ whose name is the capability, with value <code>true</code>.
+ Keys with other values SHOULD NOT appear in this group.</p>
+
+ <p>For instance, the <code>.client</code> file for a streamed media
+ handler that supports ICE-UDP NAT traversal, Speex audio,
+ and Theora and H264 video might contain this group:</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client.Handler.Capabilities]
+org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/ice-udp=true
+org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/audio/speex=true
+org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/theora=true
+org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/h264=true
+</pre>
+
+ <p>Like the <tp:member-ref>HandlerChannelFilter</tp:member-ref>
+ property, this property cannot change while the Handler owns its
+ Client bus name. However, the <code>.client</code> file, if any,
+ can change (due to upgrades or installation of pluggable codecs),
+ and the capabilities really supported by the handler might not
+ exactly match what is cached in the <code>.client</code> file.</p>
+
+ <tp:rationale>
+ <p>The client file is installed statically and is intended to list
+ codecs etc. that the handler guarantees it can support (e.g. by
+ having a hard dependency on them), whereas the running handler
+ process might be able to find additional codecs.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="HandleChannels" tp:name-for-bindings="Handle_Channels">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by the channel dispatcher when this client should handle these
+ channels, or when this client should present channels that it is already
+ handling to the user (e.g. bring them into the foreground).</p>
+
+ <tp:rationale>
+ <p>Clients are expected to know what channels they're already handling,
+ and which channel object path corresponds to which window or tab.
+ This can easily be done using a hash table keyed by channels' object
+ paths.</p>
+ </tp:rationale>
+
+ <p>This method can raise any D-Bus error. If it does, the
+ handler is assumed to have failed or crashed, and the channel
+ dispatcher MUST recover in an implementation-specific way; it MAY
+ attempt to dispatch the channels to another handler, or close the
+ channels.</p>
+
+ <p>If closing the channels, it is RECOMMENDED that the channel
+ dispatcher attempts to close the channels using
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Close</tp:dbus-ref>,
+ but resorts to calling
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.Interface.Destroyable.Destroy</tp:dbus-ref>
+ (if available) or ignoring the channel (if not) if the same handler
+ repeatedly fails to handle channels.</p>
+
+ <p>After HandleChannels returns successfully, the client process is
+ considered to be responsible for the channel until it its unique
+ name disappears from the bus.</p>
+
+ <tp:rationale>
+ <p>If a process has multiple Client bus names - some temporary and
+ some long-lived - and drops one of the temporary bus names in order
+ to reduce the set of channels that it will handle, any channels
+ that it is already handling should remain unaffected.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Account" type="o" direction="in">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ with which the channels are associated. The
+ well-known bus name to use is that of the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">AccountManager</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Connection" type="o" direction="in">
+ <tp:docstring>
+ The Connection with which the channels are associated. The
+ well-known bus name to use can be derived from this object
+ path by removing the leading '/' and replacing all subsequent
+ '/' by '.'.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channels" type="a(oa{sv})" direction="in"
+ tp:type="Channel_Details[]">
+ <tp:docstring>
+ The channels and their immutable properties. Their well-known
+ bus name is the same as that of the Connection.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Requests_Satisfied" type="ao" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The requests satisfied by these channels.</p>
+
+ <tp:rationale>
+ <p>If the handler implements Requests, this tells it
+ that these channels match previous <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Interface.Requests">AddRequest</tp:dbus-ref>
+ calls that it may have received.</p>
+
+ <p>There can be more than one, if they were EnsureChannel
+ requests.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="User_Action_Time" type="t" direction="in">
+ <tp:docstring>
+ The time at which user action occurred, or 0 if this channel
+ is to be handled for some reason not involving user action.
+ Handlers SHOULD use this for focus-stealing prevention,
+ if applicable.
+ This property has the same semantic as <tp:type>User_Action_Timestamp</tp:type>
+ but is unsigned for historical reasons.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Handler_Info" type="a{sv}" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about these channels. Currently defined
+ keys are:</p>
+
+ <dl>
+ <dt><code>request-properties</code> - a{oa{sv}}</dt>
+ <dd>A map from <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ paths listed in <var>Requests_Satisfied</var> to
+ <tp:type>Qualified_Property_Value_Map</tp:type>s containing
+ namespaced immutable properties of each request.</dd>
+ </dl>
+
+ <p>When more keys are defined for this dictionary, all will be
+ optional; handlers MAY safely ignore any entry in this
+ dictionary.</p>
+ </tp:docstring>
+ </arg>
+
+ <!-- FIXME: invent a way to say "any error is possible" in spec markup -->
+ </method>
+
+ <property name="HandledChannels" tp:name-for-bindings="Handled_Channels"
+ type="ao" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of the channels that this process is currently handling.</p>
+
+ <p>There is no change notification.</p>
+
+ <tp:rationale>
+ <p>This property exists for state recovery - it makes it possible
+ for channel handling to survive a ChannelDispatcher crash.</p>
+
+ <p>If the channel dispatcher is automatically replaced, the
+ replacement can discover all Handlers by looking for the Client
+ well-known bus names, and discover which channels they are
+ currently handling. Once this has been done, all unhandled
+ channels can be re-dispatched, and the only issue visible to
+ the user is that unhandled channels that they have already
+ approved might be sent back to Approvers.</p>
+ </tp:rationale>
+
+ <p>The value of this property SHOULD be the same for all Client
+ instances that share a unique bus name, and SHOULD include all
+ channels that are being handled, even if they were conceptually
+ handled by a different Client instance.</p>
+
+ <tp:rationale>
+ <p>Otherwise, when a process released a temporary Client name,
+ channels that it handled because of that Client name would no
+ longer be state-recoverable.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client_Handler_Future.xml b/spec/spec/Client_Handler_Future.xml
new file mode 100644
index 000000000..4c1a8b761
--- /dev/null
+++ b/spec/spec/Client_Handler_Future.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" ?>
+<node name="/Client_Handler_Future"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client.Handler.FUTURE"
+ tp:causes-havoc="a staging area for future Handler functionality">
+ <tp:requires interface="org.freedesktop.Telepathy.Client.Handler"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface contains functionality which we intend to incorporate
+ into the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ interface in future. It should be considered to
+ be conceptually part of the core Handler interface, but without
+ API or ABI guarantees.</p>
+ </tp:docstring>
+
+ <property name="BypassObservers" tp:name-for-bindings="Bypass_Observers"
+ type="b" access="read">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, channels destined for this handler are not passed to
+ observers for observing.</p>
+
+ <tp:rationale>
+ <p>This is useful in use-cases where the handler doesn't want anyone
+ observing the channel - for example, because channels it handles
+ shouldn't be logged.</p>
+ </tp:rationale>
+
+ <p>For service-activatable handlers, this property should be specified
+ in the handler's <tt>.client</tt> file as follows:</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client.Handler]
+BypassObservers=true
+</pre>
+ </tp:docstring>
+ </property>
+
+ <property name="RelatedConferencesBypassApproval"
+ tp:name-for-bindings="Related_Conferences_Bypass_Approval"
+ type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, channels destined for this handler that have the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+ >Conference</tp:dbus-ref> interface, with a channel that
+ was previously handled by the same client process in their
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface.Conference"
+ >InitialChannels</tp:dbus-ref> property, should bypass the
+ approval stage. In effect, this is a weaker form of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Client.Handler"
+ >BypassApproval</tp:dbus-ref>.</p>
+
+ <tp:rationale>
+ <p>It would be reasonable for a user interface to accept
+ invitations to continuations of an existing channel automatically,
+ or not; this is a matter of UI policy.</p>
+
+ <p>It's somewhat complex for an Approver to keep track of which
+ channels are being handled by a particular Handler, but
+ the Channel Dispatcher already has to track this, so it's
+ useful for the channel dispatcher to assist here.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client_Interface_Requests.xml b/spec/spec/Client_Interface_Requests.xml
new file mode 100644
index 000000000..3cecfce49
--- /dev/null
+++ b/spec/spec/Client_Interface_Requests.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" ?>
+<node name="/Client_Interface_Requests"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client.Interface.Requests">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Client"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Client.Handler"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface can be implemented by a Handler to be notified about
+ requests for channels that it is likely to be asked to handle.</p>
+ </tp:docstring>
+
+ <method name="AddRequest" tp:name-for-bindings="Add_Request">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by the ChannelDispatcher to indicate that channels have been
+ requested, and that if the request is successful, they will probably
+ be handled by this Handler. The ChannelDispatcher SHOULD only
+ call this method on one handler per request.</p>
+
+ <tp:rationale>
+ <p>This allows the UI to start preparing to handle the channels
+ in advance (e.g. render a window with an "in progress" message),
+ improving perceived responsiveness.</p>
+
+ <p>The use of "probably" is because you can't necessarily tell from
+ a channel request which handler will handle particular channels.
+ A reasonable heuristic would be to match the request against the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>,
+ and respect the preferred handler (if any).</p>
+ </tp:rationale>
+
+ <p>If the request succeeds and is given to the expected Handler,
+ the Requests_Satisfied parameter to
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ can be used to match the channel to a previous AddRequest call.</p>
+
+ <tp:rationale>
+ <p>This lets the UI direct the channels to the window that it
+ already opened.</p>
+ </tp:rationale>
+
+ <p>If the request fails, the expected handler is notified by the
+ channel dispatcher calling its
+ <tp:member-ref>RemoveRequest</tp:member-ref> method.</p>
+
+ <tp:rationale>
+ <p>This lets the UI close the window or display the error.</p>
+ </tp:rationale>
+
+ <p>The channel dispatcher SHOULD remember which handler was notified,
+ and if the channel request succeeds, it SHOULD dispatch the channels
+ to the expected handler, unless the channels do not match that
+ handler's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>.
+ If the channels are not dispatched to the expected handler, the
+ handler that was expected is notified by the channel dispatcher
+ calling its <tp:member-ref>RemoveRequest</tp:member-ref> method
+ with the NotYours error.</p>
+
+ <tp:rationale>
+ <p>Expected handling is for the UI to close the window it
+ previously opened.</p>
+ </tp:rationale>
+
+ <p>Handlers SHOULD NOT return an error from this method; errors
+ returned from this method SHOULD NOT alter the channel dispatcher's
+ behaviour.</p>
+
+ <tp:rationale>
+ <p>Calls to this method are merely a notification.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Request" type="o" direction="in">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ object, which MUST have been returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatcher">CreateChannel</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatcher">EnsureChannel</tp:dbus-ref>
+ before this method is called.
+
+ <tp:rationale>
+ See those methods for the rationale of this ordering.
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map" direction="in">
+ <tp:docstring>
+ <p>Some of the properties of the ChannelRequest. To avoid race
+ conditions, this dictionary MUST NOT include properties whose
+ values could subsequently change. It SHOULD include as many
+ properties as possible, given that constraint.</p>
+
+ <p>In particular, the properties <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelRequest">Requests</tp:dbus-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelRequest">UserActionTime</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelRequest">Account</tp:dbus-ref>
+ MUST be included, and <tp:dbus-ref
+ namespace="ofdT.ChannelRequest">Hints</tp:dbus-ref>
+ MUST be included if implemented.</p>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="RemoveRequest"
+ tp:name-for-bindings="Remove_Request">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by the ChannelDispatcher to indicate that a request
+ previously passed to <tp:member-ref>AddRequest</tp:member-ref>
+ has failed and should be disregarded.</p>
+
+ <p>Handlers SHOULD NOT return an error from this method; errors
+ returned from this method SHOULD NOT alter the channel dispatcher's
+ behaviour.</p>
+
+ <tp:rationale>
+ <p>Calls to this method are merely a notification.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Request" type="o" direction="in">
+ <tp:docstring>
+ The request that failed.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Error" type="s" tp:type="DBus_Error_Name" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the D-Bus error with which the request failed.</p>
+
+ <p>If this is <code>org.freedesktop.Telepathy.Error.NotYours</code>,
+ this indicates that the request succeeded, but all the resulting
+ channels were given to some other handler.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Message" type="s" direction="in">
+ <tp:docstring>
+ Any message supplied with the D-Bus error.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Client_Observer.xml b/spec/spec/Client_Observer.xml
new file mode 100644
index 000000000..b42b3b1df
--- /dev/null
+++ b/spec/spec/Client_Observer.xml
@@ -0,0 +1,447 @@
+<?xml version="1.0" ?>
+<node name="/Client_Observer"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2008-2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2008-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Client.Observer">
+ <tp:added version="0.17.26">(as a stable interface)</tp:added>
+
+ <tp:requires interface="org.freedesktop.Telepathy.Client"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Observers monitor the creation of new channels. This
+ functionality can be used for things like message logging.
+ All observers are notified simultaneously.</p>
+
+ <p>Observers SHOULD NOT modify the state of a channel except
+ via user interaction.</p>
+
+ <tp:rationale>
+ <p>We want Observer UIs for file transfer channels (a progress
+ bar for the transfer) to be able to have a Cancel button.</p>
+ </tp:rationale>
+
+ <p>Observers MUST NOT carry out actions that exactly one process
+ must take responsibility for (e.g. acknowledging Text
+ messages, or carrying out the actual transfer in a file transfer
+ channel).</p>
+
+ <tp:rationale>
+ <p>Since arbitrarily many observers can be activated for
+ each channel, it would not make sense for observers to do things
+ that can only be done by one process (acknowledging
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ messages, carrying out streaming for
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">StreamedMedia</tp:dbus-ref>
+ channels, doing the actual data transfer for file transfers,
+ setting up the out-of-band connection for Tubes). The
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
+ is responsible for such tasks.</p>
+
+ <p>Handlers MAY, of course, delegate responsibility for these
+ tasks to other processes (including those run as observers),
+ but this MUST be done explicitly via a request from the Handler
+ to the Observer.</p>
+ </tp:rationale>
+
+ <p>Whenever a collection of new channels is signalled, the channel
+ dispatcher will notify all running or activatable observers whose
+ <tp:member-ref>ObserverChannelFilter</tp:member-ref> property
+ (possibly as cached in the .client file) indicates that they are
+ interested in some of the channels.</p>
+
+ <p>Observers are activated for all channels in which they have
+ registered an interest - incoming, outgoing or automatically created -
+ although of course the ObserverChannelFilter property can be set
+ to filter on the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Requested</tp:dbus-ref>
+ property.</p>
+
+ <p>Because it might take time for an observer to become ready (for
+ instance, a Text logger needs to wait until pending messages have been
+ downloaded), the channel dispatcher must wait (up to some timeout) for
+ all observers to return from
+ <tp:member-ref>ObserveChannels</tp:member-ref> before letting anything
+ destructive happen. Destructive things (e.g. acknowledging messages)
+ are defined to be done by handlers, therefore HandleWith and Claim
+ aren't allowed to succeed until all observers are ready.</p>
+
+ <p>Non-interactive approvers (for instance, to shoot down spam
+ IM channels before the tray icon blinks at the user, or to grab
+ a SASL channel before the user is prompted for a password) can
+ be implemented as observers by following these steps:</p>
+
+ <ol>
+ <li><tp:member-ref>ObserveChannels</tp:member-ref>() is called
+ on the observer.</li>
+ <li>The observer calls <tp:dbus-ref
+ namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>()
+ on the CDO.</li>
+ <li>The observer then returns from
+ <tp:member-ref>ObserveChannels</tp:member-ref>().</li>
+ <li><tp:dbus-ref
+ namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>
+ will return successfully if the channels were successfully
+ claimed, or failure if someone else got there first.</li>
+ </ol>
+
+ <p>Non-interactive approvers implemented as observers SHOULD
+ also set <tp:member-ref>DelayApprovers</tp:member-ref> to TRUE
+ so that other Approvers are not called on until all observers
+ return from <tp:member-ref>ObserveChannels</tp:member-ref>.
+ This gives non-interactive approvers a chance to claim the
+ channels before Approvers are called.</p>
+ </tp:docstring>
+
+ <property name="ObserverChannelFilter"
+ tp:name-for-bindings="Observer_Channel_Filter"
+ type="aa{sv}" access="read" tp:type="Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A specification of the channels in which this observer is
+ interested. The <tp:member-ref>ObserveChannels</tp:member-ref> method
+ should be called by the channel dispatcher whenever any of the new
+ channels in a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal match this description.</p>
+
+ <p>Only certain D-Bus types have useful semantics for matching like this,
+ so only certain types are allowed:</p>
+
+ <dl>
+ <dt>Integers of all sizes, including byte (y, n, q, i, u, x, t)</dt>
+ <dd>Matched by numeric value, regardless of type (e.g. 42 as a
+ 16-bit signed integer 'n' is considered equal to 42 as a 32-bit
+ unsigned integer 'u')</dd>
+
+ <dt>Booleans (b)</dt>
+ <dd>Matched by equality in the obvious way; not considered equal to any
+ other type</dd>
+
+ <dt>Strings (s)</dt>
+ <dd>Matched by equality in the obvious way; not considered equal to any
+ other type</dd>
+
+ <dt>Object paths (o)</dt>
+ <dd>Matched by equality in the obvious way; not considered equal to any
+ other type</dd>
+
+ </dl>
+
+ <p>This property never changes while the observer process owns its
+ Client bus name. For activatable processes, the filter can change
+ due to an upgrade - the channel dispatcher SHOULD observe changes to
+ .client files using a mechanism like inotify.</p>
+
+ <tp:rationale>
+ <p>Not allowing this property to change is a simplification,
+ particularly for activatable processes (we reject the possibility
+ that a process with a .client file, when activated, has a filter
+ that differs from what its .client file said).</p>
+
+ <p>If an Observer wants to add extra channels to its list of
+ interests at runtime, it can register an additional Client bus name
+ (for instance, the org.freedesktop.Telepathy.Client.Empathy process
+ with unique name :1.42 could additionally register
+ org.freedesktop.Telepathy.Client.Empathy._1_42) with additional
+ filters. To remove those filters, it can release the bus name;
+ it could even re-claim the bus name immediately, with different
+ filters.</p>
+
+ <p>The same principle is applied to Approvers and Handlers.</p>
+ </tp:rationale>
+
+ <p>For observers that have a .client file, the channel dispatcher
+ may discover this property from keys of the form
+ "<code><em>propertyname</em> <em>type</em></code>",
+ in groups in the .client file whose name is the name of this
+ interface followed by <code>.ObserverChannelFilter</code>,
+ a space and an ASCII decimal number starting from 0.</p>
+
+ <p>Values in the .client file are encoded in exactly the same way as
+ the <code>default-<em>p</em></code> keys in .manager files, as
+ described in the <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >ConnectionManager</tp:dbus-ref> interface (but note that not all
+ types supported in .manager files can appear in .client files).</p>
+
+ <p>For instance, a .client file for an observer that is only interested
+ in Text channels, with CONTACT or ROOM handles, that were requested by
+ a local client:</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client]
+Interfaces=org.freedesktop.Telepathy.Client.Observer;
+
+[org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 0]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+org.freedesktop.Telepathy.Channel.Requested b=true
+
+[org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 1]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=2
+org.freedesktop.Telepathy.Channel.Requested b=true
+</pre>
+
+ </tp:docstring>
+ </property>
+
+ <property name="Recover" tp:name-for-bindings="Recover" type="b"
+ access="read">
+ <tp:added version="0.19.4">
+ When using telepathy-mission-control, version 5.4.0 or later is
+ needed for this property to be useful.
+ </tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, upon the startup of this observer, <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Observer">ObserveChannels</tp:dbus-ref>
+ will be called for every already existing channel matching
+ its <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Observer">ObserverChannelFilter</tp:dbus-ref></p>
+
+ <p>When an activatable client having this property disappears from the
+ bus and there are channels matching its ObserverChannelFilter,
+ ObserveChannels will be called immediately to reactivate it
+ again. Such clients should specify this property in their
+ <tt>.client</tt> file as follows:</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client.Observer]
+Recover=true
+</pre>
+
+ <tp:rationale>
+ <p>This means that if an activatable Observer crashes, it will
+ be restarted as soon as possible; while there is an unavoidable
+ possibility that it will miss some events during this process
+ (particularly <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ messages), this window of event loss is kept to a minimum.</p>
+
+ <p>Non-activatable observers can't take advantage of this
+ mechanism, but setting this property on a non-activatable
+ observer does allow it to "catch up" on channels that are
+ currently active at the time that it starts up.</p>
+ </tp:rationale>
+
+ <p>When the ObserveChannels method is called due to observer recovery,
+ the <var>Observer_Info</var> dictionary will contain one extra item
+ mapping the key <code>"recovering"</code> to <code>True</code>.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="ObserveChannels" tp:name-for-bindings="Observe_Channels">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Called by the channel dispatcher when channels in which the
+ observer has registered an interest are announced in a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests">NewChannels</tp:dbus-ref>
+ signal.</p>
+
+ <p>If the same NewChannels signal announces some channels that match
+ the filter, and some that do not, then only a subset of the channels
+ (those that do match the filter) are passed to this method.</p>
+
+ <p>If the channel dispatcher will split up the channels from a single
+ NewChannels signal and dispatch them separately (for instance
+ because no installed Handler can handle all of them), it will call
+ ObserveChannels several times.</p>
+
+ <p>The observer MUST NOT return from this method call until it is ready
+ for a handler for the channel to run (which may change the channel's
+ state).</p>
+
+ <tp:rationale>
+ <p>The channel dispatcher must wait for observers to start up,
+ to avoid the following race: text channel logger (observer) gets
+ ObserveChannels, text channel handler gets
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandleChannels</tp:dbus-ref>
+ channel handler starts up faster and acknowledges messages,
+ logger never sees those messages.</p>
+ </tp:rationale>
+
+ <p>The channel dispatcher SHOULD NOT change its behaviour based on
+ whether this method succeeds or fails: there are no defined D-Bus
+ errors for this method, and if it fails, this only indicates that
+ an Observer is somehow broken.</p>
+
+ <tp:rationale>
+ <p>The expected error response in the channel dispatcher is to
+ log a warning, and otherwise continue as though this method
+ had succeeded.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Account" type="o" direction="in">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Account</tp:dbus-ref>
+ with which the channels are associated. The
+ well-known bus name to use is that of the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">AccountManager</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Connection" type="o" direction="in">
+ <tp:docstring>
+ The
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ with which the channels are associated. The
+ well-known bus name to use can be derived from this object
+ path by removing the leading '/' and replacing all subsequent
+ '/' by '.'.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channels" type="a(oa{sv})" tp:type="Channel_Details[]"
+ direction="in">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s
+ and their properties. Their well-known bus names are all the same as
+ that of the Connection.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Dispatch_Operation" type="o" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The path to the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatchOperation</tp:dbus-ref>
+ for these channels, or the special value '/' if there is no
+ ChannelDispatchOperation (because the channels were requested, not
+ incoming).</p>
+
+ <p>If the Observer calls <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Claim</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">HandleWith</tp:dbus-ref>
+ on the dispatch operation, it MUST be careful to avoid deadlock,
+ since these methods cannot return until the Observer has returned
+ from <tp:member-ref>ObserveChannels</tp:member-ref>.</p>
+
+ <tp:rationale>
+ <p>This allows an Observer to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ChannelDispatchOperation">Claim</tp:dbus-ref>
+ a set of channels without having to match up calls to this method
+ with calls to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Approver">AddDispatchOperation</tp:dbus-ref>.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Requests_Satisfied" type="ao" direction="in">
+ <tp:docstring>
+ The <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>s
+ satisfied by these channels.
+
+ <tp:rationale>
+ If the same process is an Observer and a Handler, it can be useful
+ to be given this information as soon as possible (it will also
+ be passed to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client">Handler.HandleChannels</tp:dbus-ref>).
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Observer_Info" type="a{sv}" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about these channels. Currently defined
+ keys are:</p>
+
+ <dl>
+ <dt><code>recovering</code> - b</dt>
+ <dd><code>True</code> if ObserveChannels was called for an existing
+ channel (due to the <tp:member-ref>Recover</tp:member-ref>
+ property being <code>True</code>); <code>False</code> or omitted
+ otherwise.
+
+ <tp:rationale>
+ This allows observers to distinguish between new channels (the normal
+ case), and existing channels that were given to the observer in order
+ to catch up on previous events (perhaps after a previous instance of
+ the same observer crashed).
+ </tp:rationale>
+ </dd>
+
+ <dt><code>request-properties</code> - a{oa{sv}}</dt>
+ <dd>A map from <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelRequest</tp:dbus-ref>
+ paths listed in <var>Requests_Satisfied</var> to
+ <tp:type>Qualified_Property_Value_Map</tp:type>s containing
+ namespaced immutable properties of each request.</dd>
+ </dl>
+
+ <p>All defined keys for this dictionary are optional;
+ observers MAY safely ignore any entry in this dictionary.</p>
+ </tp:docstring>
+ </arg>
+
+ </method>
+
+ <property name="DelayApprovers" type="b" access="read"
+ tp:name-for-bindings="Delay_Approvers">
+ <tp:added version="0.21.11"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, the channel dispatcher will wait for
+ <tp:member-ref>ObserveChannels</tp:member-ref> to return
+ before calling <tp:dbus-ref
+ namespace="ofdT.Client">Approver.AddDispatchOperation</tp:dbus-ref>
+ on appropriate Approvers.</p>
+
+ <p>This property SHOULD be false unless there is a reason
+ why a channel should not be given to approvers. An example
+ of this is if an Observer is also a Handler and wants to
+ <tp:dbus-ref
+ namespace="ofdT.ChannelDispatchOperation">Claim</tp:dbus-ref>
+ a channel so that it becomes its handler and doesn't want
+ any approver to be called, this property should be true.</p>
+
+ <p>Observers and Approvers should be called at the same time
+ in normal operation (with this property set to false) to
+ improve responsiveness. For example, if an incoming call
+ appears, the approver should get the channel as fast as
+ possible to show a dialog, but if an approver has to make
+ round-trips to set itself up, then the approval of the
+ channel is delayed. As a result, it is recommended for this
+ property to remain false unless absolutely necessary.</p>
+
+ <p>For service-activatable clients, this property should be
+ specified in the observer's <tt>.client</tt> file as
+ follows:</p>
+
+ <p>If this property is not implemented (telepathy-mission-control
+ 5.7.5 and older), the channel dispatcher SHOULD consider it as
+ being false.</p>
+
+<pre>
+[org.freedesktop.Telepathy.Client.Observer]
+DelayApprovers=true
+</pre>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection.xml b/spec/spec/Connection.xml
new file mode 100644
index 000000000..6a560fc30
--- /dev/null
+++ b/spec/spec/Connection.xml
@@ -0,0 +1,1311 @@
+<?xml version="1.0" ?>
+<node name="/Connection"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ >
+ <tp:copyright>Copyright (C) 2005-2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright (C) 2005-2009 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright (C) 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.Requests"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.Contacts"/>
+
+ <tp:struct name="Channel_Info" array-name="Channel_Info_List">
+ <tp:deprecated version="0.17.23"/>
+ <tp:docstring>A struct representing a channel, as returned by
+ ListChannels on the Connection interface.</tp:docstring>
+ <tp:member type="o" name="Channel">
+ <tp:docstring>The object path of the channel, which is on the
+ same bus name as the connection</tp:docstring>
+ </tp:member>
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type">
+ <tp:docstring>The channel's type</tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Handle_Type" name="Handle_Type">
+ <tp:docstring>The type of the handle that the channel communicates
+ with, or Handle_Type_None if there is no associated
+ handle</tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Handle" name="Handle">
+ <tp:docstring>The handle that the channel communicates with,
+ or 0 if there is no associated handle</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="Connect" tp:name-for-bindings="Connect">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the connection be established. This will be done
+ asynchronously and errors will be returned by emitting
+ <tp:member-ref>StatusChanged</tp:member-ref> signals.</p>
+
+ <p>Calling this method on a Connection that is already connecting
+ or connected is allowed, and has no effect.</p>
+ </tp:docstring>
+ </method>
+
+ <method name="Disconnect" tp:name-for-bindings="Disconnect">
+ <tp:docstring>
+ Request that the connection be closed. This closes the connection if
+ it's not already in DISCONNECTED state, and destroys the connection
+ object.
+ </tp:docstring>
+ </method>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ access="read" type="as" tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The set of optional interfaces supported by this connection.
+ Before the connection status changes to CONNECTED,
+ this property may change at any time, but it is guaranteed that
+ interfaces will only be added, not removed. After the connection
+ status changes to CONNECTED, this property cannot
+ change further.</p>
+
+ <p>There is no explicit change notification; reasonable behaviour
+ for a client would be to retrieve the interfaces list once
+ initially, and once more when it becomes CONNECTED.</p>
+
+ <tp:rationale>
+ <p>In some connection managers, certain capabilities of a connection
+ are known to be implemented for all connections (e.g. support
+ for SimplePresence), and some interfaces (like SimplePresence) can
+ even be used before connecting. Other capabilities may
+ or may not exist, depending on server functionality; by the time
+ the connection goes CONNECTED, the connection manager is expected
+ to have evaluated the server's functionality and enabled any extra
+ interfaces for the remainder of the Connection's lifetime.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:added version="0.19.2">Clients SHOULD fall back
+ to calling <tp:member-ref>GetInterfaces</tp:member-ref> if this
+ property is not supported.</tp:added>
+ </property>
+
+ <method name="GetInterfaces" tp:name-for-bindings="Get_Interfaces">
+ <arg direction="out" type="as" tp:type="DBus_Interface[]"
+ name="Interfaces">
+ <tp:docstring>
+ The value of the <tp:member-ref>Interfaces</tp:member-ref> property
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Returns the set of optional interfaces supported by this
+ connection. See <tp:member-ref>Interfaces</tp:member-ref> for more
+ details.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected">
+ <tp:docstring>
+ Before version 0.17.8 calling GetInterfaces while
+ on a connection that is not yet CONNECTED wasn't allowed. If a
+ CM returns this error, its list of interfaces should be regarded
+ as empty until it becomes CONNECTED.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetProtocol" tp:name-for-bindings="Get_Protocol">
+ <arg direction="out" type="s" tp:type="Protocol" name="Protocol">
+ <tp:docstring>
+ A string identifier for the protocol
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Get the protocol this connection is using.
+ </tp:docstring>
+ </method>
+
+ <signal name="SelfHandleChanged"
+ tp:name-for-bindings="Self_Handle_Changed">
+ <tp:docstring>
+ Emitted whenever the <tp:member-ref>SelfHandle</tp:member-ref> property
+ changes. If the connection
+ is not yet in the CONNECTED state, this signal is not guaranteed
+ to be emitted.
+ </tp:docstring>
+ <tp:added version="0.17.10">Clients MAY assume that if the
+ SelfHandle property exists, this signal will be emitted when
+ necessary.</tp:added>
+
+ <arg type="u" tp:type="Contact_Handle" name="Self_Handle">
+ <tp:docstring>
+ The new value of the SelfHandle property.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="SelfHandle" tp:name-for-bindings="Self_Handle"
+ type="u" tp:type="Contact_Handle" access="read">
+ <tp:docstring>
+ The handle which represents the user on this connection, which will
+ remain valid for the lifetime of this connection, or until a change
+ in the user's identifier is signalled by the
+ <tp:member-ref>SelfHandleChanged</tp:member-ref> signal.
+ If the connection is not yet in the CONNECTED state, the value of
+ this property MAY be zero.
+ </tp:docstring>
+ <tp:added version="0.17.10">For compatibility with older
+ versions, clients should fall back to calling the
+ <tp:member-ref>GetSelfHandle</tp:member-ref>
+ method.</tp:added>
+ </property>
+
+ <method name="GetSelfHandle" tp:name-for-bindings="Get_Self_Handle">
+ <arg direction="out" type="u" tp:type="Contact_Handle"
+ name="Self_Handle">
+ <tp:docstring>
+ The value of the <tp:member-ref>SelfHandle</tp:member-ref> property
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Returns the value of the SelfHandle property. Change notification
+ is via the SelfHandleChanged signal.
+ </tp:docstring>
+ <tp:deprecated version="0.17.10">Use GetAll to get the
+ SelfHandle property (and all other Connection properties)
+ instead.</tp:deprecated>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="Status" tp:name-for-bindings="Status"
+ access="read" type="u" tp:type="Connection_Status">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The current status of the connection. Change notification is via
+ the <tp:member-ref>StatusChanged</tp:member-ref> signal.</p>
+
+ <p>If retrieval of property succeeds and yields the value Disconnected,
+ this indicates that the connection has not yet been established.
+ If connection has been attempted and failed, the Connection object
+ SHOULD be removed from the bus entirely, meaning that retrieval of
+ this property SHOULD fail.</p>
+ </tp:docstring>
+ <tp:added version="0.19.2">Clients SHOULD fall back
+ to calling <tp:member-ref>GetStatus</tp:member-ref> if this
+ property is not supported.</tp:added>
+ </property>
+
+ <method name="GetStatus" tp:name-for-bindings="Get_Status">
+ <arg direction="out" type="u" tp:type="Connection_Status"
+ name="Status">
+ <tp:docstring>
+ The value of the <tp:member-ref>Status</tp:member-ref> property
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Get the current status as defined in the
+ <tp:member-ref>StatusChanged</tp:member-ref> signal.
+ </tp:docstring>
+ </method>
+
+ <method name="HoldHandles" tp:name-for-bindings="Hold_Handles">
+ <tp:changed version="0.21.6">If
+ <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ this method no longer does anything.</tp:changed>
+ <arg direction="in" name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ The type of handle to be held
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Handles" type="au" tp:type="Handle[]">
+ <tp:docstring>
+ A array of integer handles to hold
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ which SHOULD always be the case in this version of telepathy-spec,
+ this method does nothing and returns successfully, unless
+ the given handle type or any of the given handles is invalid.</p>
+
+ <p>In older connection managers, this method
+ notifies the connection manger that your client is holding a copy
+ of handles which may not be in use in any existing channel or
+ list, and were not obtained by using the
+ <tp:member-ref>RequestHandles</tp:member-ref> method. For
+ example, a handle observed in an emitted signal, or displayed
+ somewhere in the UI that is not associated with a channel. The
+ connection manager must not deallocate a handle where any clients
+ have used this method to indicate it is in use until the
+ <tp:member-ref>ReleaseHandles</tp:member-ref>
+ method is called, or the clients disappear from the bus.</p>
+
+ <p>Note that HoldHandles is idempotent - calling it multiple times
+ is equivalent to calling it once. If a handle is "referenced" by
+ several components which share a D-Bus unique name, the client
+ should perform reference counting internally, and only call
+ ReleaseHandles when none of the cooperating components need the
+ handle any longer.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The handle type is invalid
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ One of the given handles is not valid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="InspectHandles" tp:name-for-bindings="Inspect_Handles">
+ <arg direction="in" name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ The type of handle to be inspected
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Handles" type="au" tp:type="Handle[]">
+ <tp:docstring>
+ An array of integer handles of this type
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="as" name="Identifiers">
+ <tp:docstring>
+ An array of identifiers corresponding to the given handles, in the same order.
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Return a string representation for a number of handles of a given
+ type.
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The handle type is invalid
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ One of the given handles is not valid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="ListChannels" tp:name-for-bindings="List_Channels">
+ <tp:deprecated version="0.17.23">Use the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Requests.Channels</tp:dbus-ref>
+ property instead.
+ </tp:deprecated>
+
+ <arg direction="out" type="a(osuu)" tp:type="Channel_Info[]"
+ name="Channel_Info">
+ <tp:docstring>
+ An array of structs representing channels.
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ List all the channels which currently exist on this connection.
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="NewChannel" tp:name-for-bindings="New_Channel">
+ <tp:deprecated version="0.17.23">Connection managers MUST still
+ emit this signal, but clients SHOULD listen for the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Requests.NewChannels</tp:dbus-ref>
+ signal instead.
+ </tp:deprecated>
+
+ <arg name="Object_Path" type="o">
+ <tp:docstring>
+ A D-Bus object path for the channel object on this service
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channel_Type" type="s" tp:type="DBus_Interface">
+ <tp:docstring>
+ A D-Bus interface name representing the channel type
+ </tp:docstring>
+ </arg>
+
+ <arg name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ An integer representing the type of handle this channel
+ communicates with, or Handle_Type_None if no handle is specified
+ </tp:docstring>
+ </arg>
+
+ <arg name="Handle" type="u" tp:type="Handle">
+ <tp:docstring>
+ A handle indicating the specific contact, room or list this
+ channel communicates with, or zero if no handle is specified
+ </tp:docstring>
+ </arg>
+
+ <arg name="Suppress_Handler" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, the channel was requested by a client that intends to
+ present it to the user itself (i.e. it passed suppress_handler=TRUE
+ to the <tp:member-ref>RequestChannel</tp:member-ref> method), so no
+ other handler should be
+ launched. Clients MAY assume that channels where this is true
+ were created by a user request.</p>
+
+ <p>If false, either the channel was created due to incoming
+ information from the service, or the channel was requested by
+ a local client that does not intend to handle the channel itself
+ (this usage is deprecated).</p>
+
+ <p>Clients MUST NOT assume that only incoming channels will have
+ this flag set to false.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Emitted when a new Channel object is created, either through user
+ request or incoming information from the service.
+ </tp:docstring>
+ </signal>
+
+ <method name="ReleaseHandles" tp:name-for-bindings="Release_Handles">
+ <tp:changed version="0.21.6">If
+ <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ this method no longer does anything.</tp:changed>
+ <arg direction="in" name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ An integer handle type (as defined in RequestHandle)
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Handles" type="au" tp:type="Handle[]">
+ <tp:docstring>
+ An array of integer handles being held by the client
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ <p>If <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ which SHOULD always be the case in this version of telepathy-spec,
+ this method does nothing and returns successfully, unless
+ the given handle type or any of the given handles is invalid.</p>
+
+ <p>In older connection managers, this method
+ explicitly notifies the connection manager that your client is no
+ longer holding any references to the given handles, and that they
+ may be deallocated if they are not held by any other clients or
+ referenced by any existing channels. See
+ <tp:member-ref>HoldHandles</tp:member-ref> for notes.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The handle type is invalid
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ One of the given handles is not valid
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestChannel" tp:name-for-bindings="Request_Channel">
+ <tp:deprecated version="0.17.23">Use
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Requests.CreateChannel</tp:dbus-ref>
+ or <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Requests.EnsureChannel</tp:dbus-ref>
+ instead. Connection managers MAY implement RequestChannel by
+ raising NotImplemented, or implement fewer types of channel via
+ this API.</tp:deprecated>
+
+ <arg direction="in" name="Type" type="s" tp:type="DBus_Interface">
+ <tp:docstring>
+ A D-Bus interface name representing base channel type
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ An integer representing the handle type, or Handle_Type_None if
+ no handle is specified
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Handle" type="u" tp:type="Handle">
+ <tp:docstring>
+ A nonzero integer handle representing a contact, room, list etc.
+ according to handle_type, or zero if the handle_type is
+ Handle_Type_None
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Suppress_Handler" type="b">
+ <tp:docstring>
+ <p>Clients SHOULD always set this to true.</p>
+
+ <tp:rationale>
+ <p>The historical meaning was that clients that did not
+ intend to take responsibility for displaying the channel to
+ the user could set this to FALSE, in which case the channel
+ dispatcher would launch an appropriate channel handler.</p>
+
+ <p>However, clients whose functionality relies on having a
+ working channel dispatcher should obtain that functionality by
+ calling methods on the channel dispatcher, so that they will
+ get an appropriate error if the channel dispatcher is missing
+ or not working.</p>
+
+ <p>The channel dispatcher itself should set this to true too,
+ so that it will ignore the
+ <tp:member-ref>NewChannel</tp:member-ref> signal that results
+ from the creation of the channel. It can then dispatch the
+ channel returned from this method to an
+ appropriate handler.</p>
+
+ <p>So, there is no sensible use-case for setting this to false,
+ and setting it to false can result in unhandled channels (in
+ the case where clients assume that a channel dispatcher is
+ present, but it isn't).</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="o" name="Object_Path">
+ <tp:docstring>
+ The D-Bus object path for the channel created or retrieved
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request a channel satisfying the specified type and communicating
+ with the contact, room, list etc. indicated by the given
+ handle_type and handle. The handle_type and handle may both be
+ zero to request the creation of a new, empty channel, which may
+ or may not be possible, depending on the protocol and channel
+ type.</p>
+
+ <p>On success, the returned channel will always be of the requested
+ type (i.e. implement the requested channel-type interface).</p>
+
+ <p>If a new, empty channel is requested, on success the returned
+ channel will always be an "anonymous" channel for which the type
+ and handle are both zero.</p>
+
+ <p>If a channel to a contact, room etc. is requested, on success, the
+ returned channel may either be a new or existing channel to
+ the requested entity (i.e. its
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandleType</tp:dbus-ref>
+ and <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">TargetHandle</tp:dbus-ref>
+ properties are the
+ requested handle type and handle), or a newly created "anonymous"
+ channel associated with the requested handle in some
+ implementation-specific way.</p>
+
+ <p>For example, for a contact handle, the returned channel
+ might be "anonymous", but implement the groups interface and have
+ the requested contact already present among the members.</p>
+
+ <p>If the request cannot be satisfied, an error is raised and no
+ channel is created.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Unknown channel type
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ The given handle does not exist or cannot be created
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The requested channel type cannot be created with the given handle
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable">
+ <tp:docstring>
+ The requested channel cannot be created because contact doesn't
+ have the required capabilities.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Banned"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Full"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.InviteOnly"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Handle_Type" type="u">
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ A "null" handle type used to indicate the absence of a handle.
+ When a handle type and a handle appear as a pair, if the handle
+ type is zero, the handle must also be zero.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Contact" value="1">
+ <tp:docstring>
+ A contact
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Room" value="2">
+ <tp:docstring>
+ A chat room
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="List" value="3">
+ <tp:deprecated version="0.25.0">Replaced by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.ContactList</tp:dbus-ref>
+ </tp:deprecated>
+ <tp:docstring>
+ A server-generated contact list (see Channel.Interface.Group)
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Group" value="4">
+ <tp:deprecated version="0.25.0">Replaced by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.ContactList</tp:dbus-ref>
+ </tp:deprecated>
+ <tp:docstring>
+ A user-defined contact list (see Channel.Interface.Group)
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:simple-type name="Handle" type="u" array-name="Handle_List">
+ <tp:docstring>An unsigned 32-bit integer representing a
+ handle</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="Contact_Handle" type="u"
+ array-name="Contact_Handle_List">
+ <tp:docstring>An unsigned 32-bit integer representing a handle of type
+ Handle_Type_Contact</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="Room_Handle" type="u"
+ array-name="Room_Handle_List">
+ <tp:docstring>An unsigned 32-bit integer representing a handle of type
+ Handle_Type_Room</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="List_Handle" type="u"
+ array-name="List_Handle_List">
+ <tp:deprecated version="0.25.0">Replaced by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.ContactList</tp:dbus-ref>
+ </tp:deprecated>
+ <tp:docstring>An unsigned 32-bit integer representing a handle of type
+ Handle_Type_List</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="Group_Handle" type="u"
+ array-name="Group_Handle_List">
+ <tp:deprecated version="0.25.0">Replaced by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.Interface.ContactList</tp:dbus-ref>
+ </tp:deprecated>
+ <tp:docstring>An unsigned 32-bit integer representing a handle of type
+ Handle_Type_Group</tp:docstring>
+ </tp:simple-type>
+
+ <method name="RequestHandles" tp:name-for-bindings="Request_Handles">
+ <tp:changed version="0.21.6">If
+ <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ this method no longer has its reference-counting effect.</tp:changed>
+ <arg direction="in" name="Handle_Type" type="u" tp:type="Handle_Type">
+ <tp:docstring>
+ The type of handle required
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Identifiers" type="as">
+ <tp:docstring>
+ An array of identifiers of entities to request handles for
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="au" tp:type="Handle[]"
+ name="Handles">
+ <tp:docstring>
+ An array of integer handle numbers in the same order as the given identifiers.
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request several handles from the connection manager which represent a
+ number of contacts, rooms or server-stored lists on the service.</p>
+
+ <p>If <tp:member-ref>HasImmortalHandles</tp:member-ref> is true,
+ which SHOULD always be the case in this version of telepathy-spec,
+ the handles remain valid until the connection disconnects.</p>
+
+ <p>The implementation of this method in older connection managers
+ must record that these handles are in use by the
+ client who invokes this method, and must not deallocate the handles
+ until the client disconnects from the bus or calls the
+ <tp:member-ref>ReleaseHandles</tp:member-ref>
+ method. Where the identifier refers to an entity that already has a
+ handle in this connection manager, this handle should be returned
+ instead. The handle number 0 must not be returned by the connection
+ manager.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ The given identifier does not identify a valid entity of the given
+ type.
+
+ <tp:rationale>
+ For instance, an XMPP connection would raise this error for
+ identifiers with type Handle_Type_Room that do not contain
+ exactly one '@' character, that contain spaces, and so on.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The given handle type is not valid, or is not implemented on this
+ connection.
+
+ <tp:rationale>
+ For instance, a connection to a protocol that doesn't have
+ chat rooms would raise this error for room handles, and all CMs
+ would raise this error for Handle_Type_None.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Connection_Status" plural="Connection_Statuses" type="u">
+ <tp:enumvalue suffix="Connected" value="0">
+ <tp:docstring>
+ The connection is fully connected and all methods are available.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Connecting" value="1">
+ <tp:docstring>
+ <tp:member-ref>Connect</tp:member-ref> has been called but the
+ connection has not yet been established. Some methods may fail
+ until the connection has been established.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Disconnected" value="2">
+ <tp:docstring>
+ If this is retrieved from <tp:member-ref>GetStatus</tp:member-ref> or
+ <tp:member-ref>Status</tp:member-ref>, it indicates that connection
+ has not yet been attempted. If seen in a
+ <tp:member-ref>StatusChanged</tp:member-ref> signal, it indicates
+ that the connection has failed; the Connection object SHOULD be
+ removed from D-Bus immediately, and all subsequent method calls
+ SHOULD fail.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Connection_Status_Reason" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A reason why the status of the connection changed. Apart from
+ Requested, the values of this enumeration only make sense as
+ reasons why the status changed to Disconnected.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None_Specified" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There is no reason set for this state change. Unknown status
+ reasons SHOULD be treated like this reason.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.<tp:error-ref>Disconnected</tp:error-ref></code>.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Requested" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The change is in response to a user request. Changes to the
+ Connecting or Connected status SHOULD always indicate this reason;
+ changes to the Disconnected status SHOULD indicate this reason
+ if and only if the disconnection was requested by the user.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cancelled</code>.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Network_Error" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There was an error sending or receiving on the network socket.</p>
+
+ <p>When the status changes from Connecting to Disconnected for this
+ reason, the equivalent D-Bus error is either
+ <code>org.freedesktop.Telepathy.Error.NetworkError</code>,
+ <code>org.freedesktop.Telepathy.Error.ConnectionRefused</code>,
+ <code>org.freedesktop.Telepathy.Error.ConnectionFailed</code>
+ or some more specific error.</p>
+
+ <p>When the status changes from Connected to Disconnected for this
+ reason, the equivalent D-Bus error is either
+ <code>org.freedesktop.Telepathy.Error.NetworkError</code>,
+ <code>org.freedesktop.Telepathy.Error.ConnectionLost</code>
+ or some more specific error.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Authentication_Failed" value="3">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The username or password was invalid.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.AuthenticationFailed</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Encryption_Error" value="4">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There was an error negotiating SSL on this connection, or
+ encryption was unavailable and require-encryption was set when the
+ connection was created.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.EncryptionNotAvailable</code>
+ if encryption was not available at all, or
+ <code>org.freedesktop.Telepathy.Error.EncryptionError</code>
+ if encryption failed.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Name_In_Use" value="5">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>In general, this reason indicates that the requested account
+ name or other identification could not be used due to conflict
+ with another connection. It can be divided into three cases:</p>
+
+ <ul>
+ <li>If the status change is from Connecting to Disconnected
+ and the 'register' parameter to RequestConnection was present
+ and true, the requested account could not be created on the
+ server because it already exists.
+ The equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.RegistrationExists</code>.
+ </li>
+
+ <li>If the status change is from Connecting to Disconnected
+ but the 'register' parameter is absent or false, the connection
+ manager could not connect to the specified account because
+ a connection to that account already exists.
+ The equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.AlreadyConnected</code>.
+
+ <tp:rationale>
+ In some protocols, like XMPP (when connecting with the same
+ JID and resource as an existing connection), the existing
+ connection "wins" and the new one fails to connect.
+ </tp:rationale>
+ </li>
+
+ <li>If the status change is from Connected to Disconnected,
+ the existing connection was automatically disconnected because
+ a new connection to the same account (perhaps from a different
+ client or location) was established.
+ The equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.ConnectionReplaced</code>.
+
+ <tp:rationale>
+ In some protocols, like MSNP (when connecting twice with the
+ same Passport), the new connection "wins" and the
+ existing one is automatically disconnected.
+ </tp:rationale>
+ </li>
+ </ul>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Not_Provided" value="6">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server did not provide a SSL certificate.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.NotProvided</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Untrusted" value="7">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate is signed by an untrusted certifying
+ authority. This error SHOULD NOT be used to represent a self-signed
+ certificate: use the more specific Cert_Self_Signed reason for
+ that.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.Untrusted</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Expired" value="8">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate has expired.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.Expired</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Not_Activated" value="9">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate is not yet valid.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.NotActivated</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Hostname_Mismatch" value="10">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate did not match its hostname.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.HostnameMismatch</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Fingerprint_Mismatch" value="11">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate does not have the expected
+ fingerprint.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.FingerprintMismatch</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Self_Signed" value="12">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate is self-signed.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.SelfSigned</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Other_Error" value="13">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>There was some other error validating the server's SSL
+ certificate.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.Invalid</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Revoked" value="14">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate has been revoked.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.Revoked</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Insecure" value="15">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The server's SSL certificate uses an insecure algorithm,
+ or is cryptographically weak.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.Insecure</code>.
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Cert_Limit_Exceeded" value="16">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The length in bytes of the server certificate, or the depth of the
+ sever certificate chain exceed the limits imposed by the crypto
+ library.</p>
+
+ <p>When disconnected for this reason, the equivalent D-Bus error is
+ <code>org.freedesktop.Telepathy.Error.Cert.LimitExceeded</code>
+ </p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <signal name="ConnectionError" tp:name-for-bindings="Connection_Error">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when an error occurs that renders this connection unusable.
+ </p>
+
+ <p>Whenever this signal is emitted, it MUST immediately be followed by
+ a <tp:member-ref>StatusChanged</tp:member-ref> signal with status
+ Connection_Status_Disconnected and an appropriate reason
+ code.</p>
+
+ <p>Connection managers SHOULD emit this signal on disconnection, but
+ need not do so. Clients MUST support connection managers that emit
+ StatusChanged(Disconnected, ...) without first emitting
+ ConnectionError.</p>
+
+ <tp:rationale>
+ <p>This signal provides additional information about the reason
+ for disconnection. The reason for connection is always
+ straightforward - it was requested - so it does not need further
+ explanation. However, on errors, it can be useful to provide
+ additional information.</p>
+
+ <p>The <tp:type>Connection_Status_Reason</tp:type> is not given
+ here, since it will be signalled in
+ <tp:member-ref>StatusChanged</tp:member-ref>. A reasonable client
+ implementation would be to store the information given by this
+ signal until StatusChanged is received, at which point the
+ information given by this signal can be used to supplement the
+ StatusChanged signal.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Error" type="s" tp:type="DBus_Error_Name">
+ <tp:docstring>
+ The name of a D-Bus error describing the error that occurred,
+ which may correspond to a
+ <tp:type>Connection_Status_Reason</tp:type>, or may be a more
+ specific Telepathy error
+ (such as
+ <code>org.freedesktop.Telepathy.Error.ConnectionRefused</code>
+ for Connection_Status_Reason_Network_Error)
+ or a protocol-specific or connection-manager-specific error in a
+ suitable namespace.
+
+ <tp:rationale>
+ For instance, a SIP connection manager could signal
+ "402 Payment Required" as an error in a
+ connection-manager-specific namespace, or a link-local
+ XMPP implementation that used Avahi could provide the error
+ given to it by the avahi-daemon.
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Details" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional information about the error, which may include
+ the following well-known keys:</p>
+
+ <dl>
+ <dt>debug-message (s)</dt>
+ <dd>Debugging information on the change, corresponding to the
+ message part of a D-Bus error message, which SHOULD NOT be
+ displayed to users under normal circumstances</dd>
+
+ <dt>server-message (s)</dt>
+ <dd>A human-readable message from the server explaining what
+ happened. This may be in the user's native language, or in the
+ server operator's native language, or even in Lojban.</dd>
+
+ <dt>user-requested (b), expected-hostname (s), certificate-hostname (s)</dt>
+ <dd>The same details defined in <tp:type>TLS_Certificate_Rejection</tp:type>.</dd>
+ </dl>
+
+ </tp:docstring>
+ </arg>
+
+ </signal>
+
+ <signal name="StatusChanged" tp:name-for-bindings="Status_Changed">
+ <arg name="Status" type="u" tp:type="Connection_Status">
+ <tp:docstring>
+ An integer indicating the new status, as defined by ConnectionStatus
+ </tp:docstring>
+ </arg>
+
+ <arg name="Reason" type="u" tp:type="Connection_Status_Reason">
+ <tp:docstring>
+ An integer indicating the reason for the status change, as defined
+ by ConnectionStatusReason
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Emitted when the status of the connection changes. All states and
+ reasons have numerical values, as defined in ConnectionStatus
+ and ConnectionStatusReason.
+ </tp:docstring>
+ </signal>
+
+ <tp:contact-attribute name="contact-id" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same string that would be returned by
+ <tp:member-ref>InspectHandles</tp:member-ref>. As a special case,
+ this is always present in the result of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Contacts">GetContactAttributes</tp:dbus-ref>,
+ whether it was explicitly requested or not.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <method name="AddClientInterest" tp:name-for-bindings="Add_Client_Interest">
+ <tp:added version="0.21.3"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Register a client's interest in notifications related to one or
+ more interfaces.</p>
+
+ <p>Groups of notifications are identified by a token which is either
+ a D-Bus interface name, or a string that starts with a D-Bus
+ interface name. The meaning of each token is given by that D-Bus
+ interface, which MUST define it in its documentation.</p>
+
+ <tp:rationale>
+ <p>Initially, all interests are in entire interface, but allowing
+ other strings allows subscription to part of an interface; for
+ instance, an interest in ...MailNotification/count could track
+ the number of messages without caring about their detailed
+ content.</p>
+ </tp:rationale>
+
+ <p>For each token with which this method interacts, the
+ Connection tracks an "interest count" (like a reference count) for
+ each unique bus name that has called this method. When a client
+ calls this method, for each token, the interest count for its
+ unique bus name is incremented; when
+ <tp:member-ref>RemoveClientInterest</tp:member-ref> is called,
+ all interest counts for that unique bus name are decremented.
+ If the unique bus name leaves the bus (for instance, if the
+ client crashes or exits), all interest counts for that unique bus
+ name are set to zero.</p>
+
+ <p>The Connection can then use these reference counts to
+ avoid subscribing to protocol-level notifications unless at least
+ one client has a non-zero interest count for the relevant
+ token.</p>
+
+ <tp:rationale>
+ <p>This method exists to reduce memory and network overhead when
+ there is no active subscription.</p>
+
+ <p>One situation where this is useful is <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface"
+ >Location</tp:dbus-ref>: on XMPP, location updates are received
+ over PEP. If the Connection advertises the
+ <code>geoloc+notify</code> capability, it will be sent location
+ updates for all contacts. To avoid consuming resources for this,
+ the connection should avoid advertising that capability until
+ a client has expressed an interest in contacts' locations.</p>
+
+ <p>Another example of a protocol that benefits from this method is
+ the Google XMPP Mail Notification extension, which can be used
+ to implement <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface"
+ >MailNotification</tp:dbus-ref>. In this protocol, the CM
+ receives a notification that something has changed, but to get
+ more information, the CM must request this information. Knowing
+ that nobody is currently interested in this information, the CM
+ can avoid generating useless network traffic. Similarly, the CM
+ may free the list of unread messages to reduce memory overhead.</p>
+ </tp:rationale>
+
+ <p>If this method is called for an interface that might require
+ protocol-level subscription, but the connection cannot set up
+ that subscription yet (for instance because the
+ <tp:member-ref>Status</tp:member-ref> is not Connected yet), the
+ Connection MUST remember the client's interest, and attempt to
+ subscribe to the appropriate protocol feature when this becomes
+ possible.</p>
+
+ <p>Clients MAY ignore any errors raised by this method; it is intended
+ to be called with the reply ignored.</p>
+
+ <tp:rationale>
+ <p>The only reason it could fail is if it's unimplemented, in which
+ case the only thing the client can usefully do is to proceed as if
+ it had succeeded.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Tokens" type="as" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interfaces or parts of interfaces in which to register an
+ interest, represented by either a
+ <tp:type>DBus_Interface</tp:type>, or a string prefixed with a
+ <tp:type>DBus_Interface</tp:type>.</p>
+
+ <p>If the Connection does not support one of these tokens, this
+ is not considered to be an error; the unsupported token is
+ simply ignored.</p>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="RemoveClientInterest"
+ tp:name-for-bindings="Remove_Client_Interest">
+ <tp:added version="0.21.3"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Release an interest registered using
+ <tp:member-ref>AddClientInterest</tp:member-ref>. See that
+ method's documentation for details.</p>
+
+ <p>Clients MAY ignore any errors raised by this method; it is intended
+ to be called with the reply ignored.</p>
+
+ <tp:rationale>
+ <p>The only reasons it could fail are if it's unimplemented, or if
+ the client's reference-counting is wrong and it has tried to
+ remove a client interest that it did not add. In both cases,
+ there's nothing the client could do about it.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Tokens" type="as" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interfaces or parts of interfaces that were previously passed to
+ <tp:member-ref>AddClientInterest</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <property name="HasImmortalHandles"
+ tp:name-for-bindings="Has_Immortal_Handles"
+ access="read" type="b">
+ <tp:added version="0.21.6"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if handles last for the whole lifetime of the Connection.
+ This SHOULD be the case in all connection managers, but clients
+ MUST interoperate with older connection managers
+ (which reference-count handles).</p>
+ </tp:docstring>
+ </property>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This models a connection to a single user account on a communication
+ service. Its basic capability is to provide the facility to request and
+ receive channels of differing types (such as text channels or streaming
+ media channels) which are used to carry out further communication.</p>
+
+ <p>In order to allow Connection objects to be discovered by new clients,
+ the object path and well-known bus name MUST be of the form
+ <code>/org/freedesktop/Telepathy/Connection/cmname/proto/account</code>
+ and
+ <code>org.freedesktop.Telepathy.Connection.cmname.proto.account</code>
+ where:</p>
+
+ <ul>
+ <li><em>cmname</em> is the same
+ <tp:type>Connection_Manager_Name</tp:type> that appears
+ in the connection manager's object path and well-known bus name</li>
+ <li><em>proto</em> is the <tp:type>Protocol</tp:type> name as seen in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.ConnectionManager">ListProtocols</tp:dbus-ref>,
+ but with "-" replaced with "_" to get a valid
+ object path/bus name</li>
+ <li><em>account</em> is some non-empty sequence of ASCII letters,
+ digits and underscores not starting with a digit</li>
+ </ul>
+
+ <p><em>account</em> SHOULD be formed such that any valid distinct
+ connection instance on this protocol has a distinct name. This
+ might be formed by including the server name followed by the user
+ name (escaped via some suitable mechanism like telepathy-glib's
+ tp_escape_as_identifier() function to preserve uniqueness); on
+ protocols where connecting multiple times is permissable, a
+ per-connection identifier might be necessary to ensure
+ uniqueness.</p>
+
+ <p>Clients MAY parse the object path to determine the connection
+ manager name and the protocol, but MUST NOT attempt to parse the
+ <em>account</em> part. Connection managers MAY use any unique string
+ for this part.</p>
+
+ <p>As well as the methods and signatures below, arbitrary interfaces may be
+ provided by the Connection object to represent extra connection-wide
+ functionality, such as the Connection.Interface.SimplePresence for
+ receiving and
+ reporting presence information, and Connection.Interface.Aliasing for
+ connections where contacts may set and change an alias for themselves.
+ These interfaces can be discovered using the
+ <tp:member-ref>GetInterfaces</tp:member-ref> method.</p>
+
+ <p>Contacts, rooms, and server-stored lists (such as subscribed contacts,
+ block lists, or allow lists) on a service are all represented by
+ immutable <em>handles</em>, which are unsigned non-zero integers which are
+ valid only for the lifetime of the connection object, and are used
+ throughout the protocol where these entities are represented, allowing
+ simple testing of equality within clients.</p>
+
+ <p>Zero as a handle value is sometimes used as a "null" value to mean
+ the absence of a contact, room, etc.</p>
+
+ <p>Handles have per-type uniqueness, meaning that
+ every (handle type, handle number) tuple is guaranteed to be unique within
+ a connection and that a handle alone (without its type) is meaningless or
+ ambiguous. Connection manager implementations should reference count these
+ handles to determine if they are in use either by any active clients or any
+ open channels, and may deallocate them when this ceases to be true. Clients
+ may request handles of a given type and identifier with the
+ <tp:member-ref>RequestHandles</tp:member-ref> method, inspect the entity
+ identifier with the <tp:member-ref>InspectHandles</tp:member-ref>
+ method, keep handles from being released with
+ <tp:member-ref>HoldHandles</tp:member-ref>, and notify that they are no
+ longer storing handles with
+ <tp:member-ref>ReleaseHandles</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <tp:changed version="0.17.10">Previously, the account part of
+ Connection bus names/object paths was allowed to have more than one
+ component (i.e. contain dots or slashes), resulting in Connection
+ bus names and object paths with more than 7 components. We now restrict
+ Connection bus names/object paths to have exactly 7
+ components.</tp:changed>
+
+ <tp:changed version="0.17.23">The Requests and Contacts interfaces
+ are now mandatory. Their functionality will be merged into the main
+ Connection interface at some point in future.</tp:changed>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Future.xml b/spec/spec/Connection_Future.xml
new file mode 100644
index 000000000..6b5291efd
--- /dev/null
+++ b/spec/spec/Connection_Future.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" ?>
+<node name="/Connection_FUTURE"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ >
+ <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.FUTURE"
+ tp:causes-havoc='experimental'>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <method name="EnsureSidecar" tp:name-for-bindings="Ensure_Sidecar">
+ <tp:added version="0.19.0">(as a draft)</tp:added>
+
+ <arg direction="in" name="Main_Interface" type="s"
+ tp:type="DBus_Interface">
+ <tp:docstring>
+ The "primary" interface implemented by an object attached
+ to a connection. For example, a Gabble plugin implementing
+ fine-grained control of XEP-0016 privacy lists might expose an object
+ implementing <tt>com.example.PrivacyLists</tt>.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Path" type="o">
+ <tp:docstring>The object path of the sidecar, exported by the same bus
+ name as the Connection to which it is attached.</tp:docstring>
+ </arg>
+ <arg direction="out" name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring>Immutable properties of the sidecar.</tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request an object with a particular interface providing additional
+ connection-specific functionality, together with its immutable
+ properties. These will often be implemented by plug-ins to the
+ connection managers; for example, support for an XMPP XEP for which
+ no generic Telepathy interface exists might be implemented by a
+ Gabble plugin exposing a sidecar with a particular interface.</p>
+
+ <p>This method may be called at any point during the lifetime of a
+ connection, even before its <tp:type>Connection_Status</tp:type>
+ changes to Connected. It MAY take a long time to
+ return—perhaps it needs to wait for a connection to be established
+ and for all the services supported by the server to be discovered
+ before determining whether necessary server-side support is
+ available—so callers SHOULD override the default method timeout (25
+ seconds) with a much higher value (perhaps even MAX_INT32, meaning
+ “no timeout” in recent versions of libdbus).</p>
+
+ <tp:rationale>
+ <p>There is an implicit assumption that any connection
+ manager plugin will only want to export one “primary” object per
+ feature it implements, since there is a one-to-one mapping between
+ interface and object. This is reasonable since Sidecars are
+ (intended to be) analogous to extra interfaces on the connection,
+ providing once-per-connection shared functionality; it also makes
+ client code straightforward (look up the interface you care about
+ in a dictionary, build a proxy object from the value). More
+ “plural” plugins are likely to want to implement new types of
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>
+ instead.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The requested sidecar is not implemented by this connection manager,
+ or a necessary server-side component does not exist. (FIXME: split
+ these two errors out? Then again, once we list the guaranteed and
+ possible sidecars on a Protocol object, clients can tell the
+ difference themselves, because they shouldn't be calling this in the
+ first case.)
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy">
+ <tp:docstring>
+ A server-side component needed by the requested sidecar reported it
+ is currently too busy, or did not respond for some
+ implementation-defined time. The caller may wish to try again later.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.Cancelled">
+ <tp:docstring>
+ The connection was disconnected while the sidecar was being set up.
+ </tp:docstring>
+ </tp:error>
+ </method>
+
+ </interface>
+</node>
diff --git a/spec/spec/Connection_Interface_Addressing.xml b/spec/spec/Connection_Interface_Addressing.xml
new file mode 100644
index 000000000..fe3783c2e
--- /dev/null
+++ b/spec/spec/Connection_Interface_Addressing.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Addressing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2010 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Addressing1"
+ tp:causes-havoc="experimental">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.Contacts"/>
+ <tp:added version="0.19.12">(as draft)</tp:added>
+ <tp:changed version="0.25.1">Both methods now return two dictionaries.</tp:changed>
+ <tp:changed version="0.25.UNRELEASED">Replaced DRAFT with a version number
+ (still keeping the causes-havoc annotation)</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface deals with the multiple address types that can
+ refer to the same contact, such as vCard fields and URIs.</p>
+
+ <p>It can be used to retrieve contacts with a specific addresses
+ through <tp:member-ref>GetContactsByVCardField</tp:member-ref> and
+ <tp:member-ref>GetContactsByURI</tp:member-ref>, as well as
+ defining the various addressing methods for a given contact
+ through this interface's contact attributes.</p>
+ </tp:docstring>
+
+ <method name="GetContactsByVCardField"
+ tp:name-for-bindings="Get_Contacts_By_VCard_Field">
+ <arg direction="in" name="Field" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The vCard field of the addresses we are requesting. The
+ field name SHOULD be in lower case. Supported
+ fields can be found in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Protocol.Interface.Addressing">AddressableVCardFields</tp:dbus-ref>.</p>
+
+ <p>The <code>url</code> vCard field MUST NOT appear here; see
+ <tp:member-ref>GetContactsByURI</tp:member-ref> instead.</p>
+
+ <tp:rationale>
+ <p>In practice, protocols have a limited set of URI
+ schemes that make sense to resolve as a contact.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Addresses" type="as">
+ <tp:docstring>
+ The addresses to get contact handles for. The address types
+ should match the given vCard field.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Interfaces" type="as"
+ tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of strings indicating which D-Bus interfaces the calling
+ process is interested in. All supported attributes from these
+ interfaces, whose values can be obtained without additional network
+ activity, will be in the reply.</p>
+
+ <p>Attributes from this interface and from
+ <tp:dbus-ref>org.freedesktop.Telepathy.Connection</tp:dbus-ref>
+ are always returned, and need not be requested
+ explicitly.</p>
+
+ <p>The behavior of this parameter is similar to the same
+ parameter in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Contacts.GetContactAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{su}" name="Requested"
+ tp:type="Addressing_Normalization_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping from requested vCard addresses to the corresponding
+ contact handles.</p>
+
+ <p>Requested addresses that are not valid or understood for this protocol
+ MUST be omitted from the mapping.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{ua{sv}}" name="Attributes"
+ tp:type="Contact_Attributes_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary mapping the contact handles to contact attributes.
+ If any of the requested addresses are in fact invalid, they are
+ simply omitted from this mapping. If contact attributes are not
+ immediately known, the behaviour is defined by the interface;
+ the attribute should either be omitted from the result or
+ replaced with a default value.</p>
+
+ <p>Requested addresses that are not valid or understood for this protocol
+ MUST be omitted from the mapping.</p>
+
+ <p>Each contact's attributes will always include at least the
+ identifier that would be obtained by inspecting the handle
+ (<code>org.freedesktop.Telepathy.Connection/contact-id</code>).
+ </p>
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request contacts and retrieve their attributes using a given field
+ in their vCards.</p>
+
+ <p>The connection manager should record that these handles are in
+ use by the client who invokes this method, and must not
+ deallocate the handles until the client disconnects from the
+ bus or calls the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.ReleaseHandles</tp:dbus-ref>
+ method.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetContactsByURI"
+ tp:name-for-bindings="Get_Contacts_By_URI">
+ <arg direction="in" name="URIs" type="as">
+ <tp:docstring>
+ The URI addresses to get contact handles for. Supported
+ schemes can be found in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Protocol.Interface.Addressing">AddressableURISchemes</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Interfaces" type="as"
+ tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of strings indicating which D-Bus interfaces the calling
+ process is interested in. All supported attributes from these
+ interfaces, whose values can be obtained without additional network
+ activity, will be in the reply.</p>
+
+ <p>Attributes from this interface and from
+ <tp:dbus-ref>org.freedesktop.Telepathy.Connection</tp:dbus-ref>
+ are always returned, and need not be requested
+ explicitly.</p>
+
+ <p>The behavior of this parameter is similar to the same
+ parameter in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Contacts.GetContactAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{su}" name="Requested"
+ tp:type="Addressing_Normalization_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping of requested URIs to the corresponding contact handles.</p>
+
+ <p>Requested URIs that are not valid or understood for this protocol
+ MUST be omitted from the mapping.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{ua{sv}}" name="Attributes"
+ tp:type="Contact_Attributes_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary mapping the contact handles to contact attributes.
+ If any of the requested addresses are in fact invalid, they are
+ simply omitted from this mapping. If contact attributes are not
+ immediately known, the behaviour is defined by the interface;
+ the attribute should either be omitted from the result or
+ replaced with a default value.</p>
+
+ <p>Requested URIs that are not valid or understood for this protocol
+ MUST be omitted from the mapping.</p>
+
+ <p>Each contact's attributes will always include at least the
+ identifier that would be obtained by inspecting the handle
+ (<code>org.freedesktop.Telepathy.Connection/contact-id</code>).
+ </p>
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request contacts and retrieve their attributes using URI addresses.</p>
+
+ <p>The connection manager should record that these handles are in
+ use by the client who invokes this method, and must not
+ deallocate the handles until the client disconnects from the
+ bus or calls the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.ReleaseHandles</tp:dbus-ref>
+ method.</p>
+ </tp:docstring>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:mapping name="VCard_Field_Address_Map" array-name="">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A mapping of vCard fields and addresses that repreent
+ the given contact.</p>
+ </tp:docstring>
+ <tp:member type="s" name="VCard_Field"/>
+ <tp:member type="s" name="Address"/>
+ </tp:mapping>
+
+ <tp:contact-attribute name="addresses" type="a{ss}"
+ tp:type="VCard_Field_Address_Map">
+ <tp:docstring>
+ The various vCard addresses that identify this contact.
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:contact-attribute name="uris" type="as">
+ <tp:docstring>
+ The various URI addresses that identify this contact.
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:mapping name="Addressing_Normalization_Map">
+ <tp:docstring>
+ A map from URIs/vCard addresses to the corresponding handle.
+ </tp:docstring>
+ <tp:added version="0.25.1"/>
+
+ <tp:member type="s" name="Requested_String">
+ <tp:docstring>
+ The URI or vCard address that has been requested by
+ <tp:member-ref>GetContactsByVCardField</tp:member-ref> or
+ <tp:member-ref>GetContactsByURI</tp:member-ref>.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Handle" tp:type="Contact_Handle">
+ <tp:docstring>
+ A nonzero handle.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Aliasing.xml b/spec/spec/Connection_Interface_Aliasing.xml
new file mode 100644
index 000000000..967577135
--- /dev/null
+++ b/spec/spec/Connection_Interface_Aliasing.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Aliasing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Aliasing">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:mapping name="Alias_Map" array-name="">
+ <tp:docstring>A dictionary whose keys are contact handles and whose
+ values are aliases.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="s" name="Alias"/>
+ </tp:mapping>
+
+ <tp:struct name="Alias_Pair" array-name="Alias_Pair_List">
+ <tp:docstring>
+ A pair (contact handle, alias) as seen in the
+ <tp:member-ref>AliasesChanged</tp:member-ref> signal.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="s" name="Alias"/>
+ </tp:struct>
+
+ <signal name="AliasesChanged" tp:name-for-bindings="Aliases_Changed">
+ <arg name="Aliases" type="a(us)" tp:type="Alias_Pair[]">
+ <!-- FIXME: if we break API, this could be an Alias_Map, a{us} -->
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array containing structs of:
+ <ul>
+ <li>the handle representing the contact</li>
+ <li>the new alias</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when a contact's alias (or that of the user) is changed.
+ </tp:docstring>
+ </signal>
+ <tp:flags name="Connection_Alias_Flags" value-prefix="Connection_Alias_Flag" type="u">
+ <tp:flag suffix="User_Set" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The aliases of contacts on this connection may be changed by the
+ user of the service, not just by the contacts themselves. This is
+ the case on Jabber, for instance.</p>
+ <p>It is possible that aliases can be changed by the contacts too -
+ which alias takes precedence is not defined by this
+ specification, and depends on the server and/or connection manager
+ implementation.</p>
+ <p>This flag only applies to the aliases of "globally valid" contact
+ handles. At this time, clients should not expect to be able to
+ change the aliases corresponding to any channel-specific
+ handles. If this becomes possible in future, a new flag will
+ be defined.</p>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+ <method name="GetAliasFlags" tp:name-for-bindings="Get_Alias_Flags">
+ <arg direction="out" type="u" tp:type="Connection_Alias_Flags"
+ name="Alias_Flags">
+ <tp:docstring>
+ An integer with a bitwise OR of flags from ConnectionAliasFlags
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Return a bitwise OR of flags detailing the behaviour of aliases on this
+ connection.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+ <method name="RequestAliases" tp:name-for-bindings="Request_Aliases">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="as" name="Aliases">
+ <tp:docstring>
+ A list of aliases in the same order as the contact handles
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request the value of several contacts' aliases at once.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+ <method name="GetAliases" tp:name-for-bindings="Get_Aliases">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a{us}" tp:type="Alias_Map" name="Aliases">
+ <tp:docstring>
+ A dictionary mapping contact handles to aliases
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request the value of several contacts' aliases at once. This SHOULD
+ only return cached aliases, falling back on the contact identifier
+ (i.e. the string corresponding to the handle) if none is present. Also
+ if there was no cached alias, a request SHOULD be started of which the
+ result is later signalled by
+ <tp:member-ref>AliasesChanged</tp:member-ref>.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+ <method name="SetAliases" tp:name-for-bindings="Set_Aliases">
+ <arg direction="in" name="Aliases" type="a{us}" tp:type="Alias_Map">
+ <tp:docstring>
+ A dictionary mapping integer handles of contacts
+ to strings of the new alias to set.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that the alias of the given contact be changed. Success will be
+ indicated by emitting an <tp:member-ref>AliasesChanged</tp:member-ref>
+ signal. On connections where the CONNECTION_ALIAS_FLAG_USER_SET flag is
+ not set, this method will only ever succeed if the contact is the
+ user's own handle (as returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.GetSelfHandle</tp:dbus-ref>).
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:contact-attribute name="alias" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same string that would be returned by
+ <tp:member-ref>GetAliases</tp:member-ref>
+ (always present with some value, possibly the
+ same as Connection/contact-id, if information from the
+ Aliasing interface was requested)
+ </p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface on connections to support protocols where contacts have an
+ alias which they can change at will. Provides a method for the user to set
+ their own alias, and a signal which should be emitted when a contact's
+ alias is changed or first discovered.</p>
+
+ <p>On connections where the user is allowed to set aliases for contacts and
+ store them on the server, the <tp:member-ref>GetAliasFlags</tp:member-ref>
+ method will have the CONNECTION_ALIAS_FLAG_USER_SET flag set, and the
+ <tp:member-ref>SetAliases</tp:member-ref> method may be called on contact
+ handles other than the user themselves.</p>
+
+ <p>Aliases are intended to be used as the main displayed name for the
+ contact, where available.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Anonymity.xml b/spec/spec/Connection_Interface_Anonymity.xml
new file mode 100644
index 000000000..704263cb9
--- /dev/null
+++ b/spec/spec/Connection_Interface_Anonymity.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Anonymity"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Anonymity">
+ <tp:added version="0.19.7">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface to support anonymity settings on a per-connection basis.
+ This defines what personal identifying information a remote contact
+ may or may not see. For example, GSM might use this for CLIR, while
+ SIP might use this for privacy service requests.</p>
+ </tp:docstring>
+
+ <tp:flags name="Anonymity_Mode_Flags" value-prefix="Anonymity_Mode" type="u">
+ <tp:docstring>
+ <p>Flags for the various types of anonymity modes. These modes are solely to
+ inform the CM of the desired anonymous settings. It is up to the
+ CM to determine whether the anonymity modes should be handled within
+ the CM itself, or whether the network that a CM might be talking to
+ should be enforcing anonymity.</p>
+
+ <p>CMs MAY support only a subset of these modes, and specific
+ connections MAY support none at all.</p>
+ </tp:docstring>
+
+ <tp:flag value="1" suffix="Client_Info">
+ <tp:docstring>
+ <p>Obscure any information that provides user identification,
+ user-agent identification or personal details. Examples of this
+ information might be GSM CallerID, SIP from address, various
+ informational email headers, etc.</p>
+
+ <p>The CM should scrub/replace any of this information before
+ passing messages or data onto the network. Note that a CM which
+ has the option of obscuring the information at the CM or privacy
+ service level would choose both (anonymity services are opaque
+ to clients of this interface).</p>
+
+ <p>Clients SHOULD NOT set both Client_Info and Show_Client_Info modes.
+ If they are set, the CM MUST respect Client_Info and ignore
+ Show_Client_Info.</p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag value="2" suffix="Show_Client_Info">
+ <tp:docstring>
+ <p>Explicitly request showing of client information. In connection
+ context, this can be used to override service default. In channel
+ context, this overrides connection anonymity modes.</p>
+
+ <tp:rationale>
+ <p>In GSM, it's possible to have CLIR enabled by default, and
+ explicitly suppress CLIR for a single phone call.</p>
+ </tp:rationale>
+
+ <p>Clients SHOULD NOT set both Client_Info and Show_Client_Info modes.
+ If they are set, the CM MUST respect Client_Info and ignore
+ Show_Client_Info. The CM MAY set both Client_Info and Show_Client_Info
+ in <tp:member-ref>SupportedAnonymityModes</tp:member-ref> to indicate
+ its support for explicitly hiding and publicising client information.
+ </p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag value="4" suffix="Network_Info">
+ <tp:docstring>
+ <p>Obscure any originating IP address information, contact URIs,
+ and anonymize all traffic involved with sending/receiving any
+ media streams or call content.
+ Examples of this include the "headers" portions of
+ <a href="http://www.rfc-editor.org/rfc/rfc3323.txt">RFC 3323</a> as
+ well as the History-Info (described in
+ <a href="http://www.rfc-editor.org/rfc/rfc4244.txt">RFC 4244</a>)
+ for a SIP CM.</p>
+
+ <p>This SHOULD have the effect of hiding address information from
+ the remote contact (ie, the contact cannot know what IP address
+ the session is originated from). Obviously the network still needs
+ to be able to route information between contacts, so this provides
+ no guarantees of what can be seen by intermediaries.</p>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <property name="SupportedAnonymityModes" type="u" access="read"
+ tp:type="Anonymity_Mode_Flags" tp:name-for-bindings="Supported_Anonymity_Modes">
+ <tp:docstring>
+ The anonymity modes supported by the CM for this connection. Once
+ Connection.Status has moved to Connected, this property MUST NOT change.
+ </tp:docstring>
+ </property>
+
+ <property name="AnonymityMandatory" type="b" access="readwrite"
+ tp:name-for-bindings="Anonymity_Mandatory"
+ tp:is-connection-parameter='yeah'>
+ <tp:docstring>
+ <p>This specifies whether or not the anonymity settings MUST be respected
+ by the CM and any intermediaries between the local and remote contacts.
+ If this is set to true but anonymity settings cannot be followed, then
+ the session MUST be denied with a
+ <code>org.freedesktop.Telepathy.Error.<tp:error-ref>WouldBreakAnonymity</tp:error-ref></code>
+ error.
+ Any client that sets <tp:member-ref>AnonymityModes</tp:member-ref>
+ SHOULD also set this property first (rather than accepting the CM's
+ default value).</p>
+ </tp:docstring>
+ </property>
+
+ <property name="AnonymityModes" type="u" tp:type="Anonymity_Mode_Flags"
+ access="readwrite" tp:name-for-bindings="Anonymity_Modes"
+ tp:is-connection-parameter='yeah'>
+ <tp:docstring>
+ <p>The currently enabled anonymity modes for the connection. Setting
+ has the effect of requesting new modes for the connection, and may
+ raise an error if the unsupported modes are set. Successfully changing
+ the modes will result in emission of
+ <tp:member-ref>AnonymityModesChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ An unsupported mode was supplied. Supported modes are specified
+ in the SupportedAnonymityModes property, and this should be
+ checked prior to setting AnonymityModes.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </property>
+
+ <signal name="AnonymityModesChanged"
+ tp:name-for-bindings="Anonymity_Modes_Changed">
+ <tp:docstring>
+ Emitted when the anonymity mode has changed.
+ </tp:docstring>
+
+ <arg name="Modes" type="u" tp:type="Anonymity_Mode_Flags">
+ <tp:docstring>
+ The new anonymity modes for this connection.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Avatars.xml b/spec/spec/Connection_Interface_Avatars.xml
new file mode 100644
index 000000000..3b9290e1d
--- /dev/null
+++ b/spec/spec/Connection_Interface_Avatars.xml
@@ -0,0 +1,516 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Avatars" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2005-2008 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright (C) 2005-2008 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright (C) 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Avatars">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:simple-type name="Avatar_Token" type="s"
+ array-name="Avatar_Token_List">
+ <tp:changed version="0.17.16">strengthened uniqueness requirements
+ so (CM name, protocol, token) is unique; previously only
+ (our Account, remote contact identifier, token) was required to be
+ unique</tp:changed>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An opaque token chosen by the connection manager, representing
+ a particular avatar.</p>
+
+ <tp:rationale>
+ <p>Because avatars can be relatively large images, most protocols
+ provide a way to detect whether an old avatar is still valid,
+ or whether an avatar has changed, without pushing the actual
+ avatar data to all clients.</p>
+ </tp:rationale>
+
+ <p>The connection manager MUST choose these tokens in a way that
+ makes it highly unlikely that two different avatars with the same
+ connection manager and protocol will have the same token.</p>
+
+ <tp:rationale>
+ <p>This means that clients MAY use the triple
+ (<tp:type>Connection_Manager_Name</tp:type>,
+ <tp:type>Protocol</tp:type>, avatar token) as a key for
+ their avatar cache. For instance, an avatar for a
+ telepathy-gabble Jabber contact might be stored in a file
+ .../gabble/jabber/4e199b4a1c40b497a95fcd1cd896351733849949.png.</p>
+ </tp:rationale>
+
+ <p>For instance, some protocols (like XMPP) identify avatars by a
+ hash of the avatar data; in this case, the hash can be used as the
+ avatar token.</p>
+
+ <p>Some protocols identify avatars by the timestamp of the last
+ change to the avatar; in these protocols it would be necessary for
+ the connection manager to encode both the timestamp and the
+ contact's identifier into the avatar token in order to ensure
+ uniqueness.</p>
+
+ <p>This token SHOULD be kept short and reasonably suitable for use
+ in a filename, but MAY contain any UTF-8 character (so clients using
+ avatar tokens in filenames MUST be prepared to escape characters
+ that are not valid in filenames). Connection managers for protocols
+ where tokens would otherwise become inconveniently large or contain
+ many unsuitable characters SHOULD hash the identifying data to
+ generate the token.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:mapping name="Avatar_Token_Map">
+ <tp:docstring>A dictionary whose keys are contact handles and whose
+ values are avatar tokens.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="s" tp:type="Avatar_Token" name="Token"/>
+ </tp:mapping>
+
+ <signal name="AvatarUpdated" tp:name-for-bindings="Avatar_Updated">
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for the contact whose avatar has changed
+ </tp:docstring>
+ </arg>
+ <arg name="New_Avatar_Token" tp:type="Avatar_Token" type="s">
+ <tp:docstring>
+ Unique token for their new avatar
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the avatar for a contact has been updated, or first
+ discovered on this connection. If the token differs from the token
+ associated with the client's cached avatar for this contact, the new
+ avatar should be requested with
+ <tp:member-ref>RequestAvatars</tp:member-ref>.
+ </tp:docstring>
+ </signal>
+
+ <signal name="AvatarRetrieved" tp:name-for-bindings="Avatar_Retrieved">
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact whose avatar has been retrieved
+ </tp:docstring>
+ </arg>
+ <arg name="Token" tp:type="Avatar_Token" type="s">
+ <tp:docstring>
+ The token corresponding to the avatar
+ </tp:docstring>
+ </arg>
+ <arg name="Avatar" type="ay">
+ <tp:docstring>
+ An array of bytes containing the image data
+ </tp:docstring>
+ </arg>
+ <arg name="Type" type="s">
+ <tp:docstring>
+ A string containing the image MIME type (eg image/jpeg), or empty if
+ unknown
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the avatar for a contact has been retrieved.
+ </tp:docstring>
+ </signal>
+
+ <property name="SupportedAvatarMIMETypes"
+ tp:name-for-bindings="Supported_Avatar_MIME_Types"
+ type="as" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ An array of supported MIME types (e.g. "image/jpeg").
+ Clients MAY assume that the first type in this array is preferred.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <property name="MinimumAvatarHeight"
+ tp:name-for-bindings="Minimum_Avatar_Height"
+ type="u" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ The minimum height in pixels of an avatar on this protocol, which MAY
+ be 0.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <property name="MinimumAvatarWidth"
+ tp:name-for-bindings="Minimum_Avatar_Width"
+ type="u" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ The minimum width in pixels of an avatar on this protocol, which MAY
+ be 0.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedAvatarHeight"
+ tp:name-for-bindings="Recommended_Avatar_Height"
+ type="u" access="read">
+ <tp:added version="0.17.22"/>
+ <tp:docstring>
+ The recommended height in pixels of an avatar on this protocol, or 0 if
+ there is no preferred height.
+ This property cannot change after the Connection goes to the Connected
+ state.
+
+ <tp:rationale>
+ In XMPP a recommended width is given by the protocol specification;
+ in proprietary protocols, using the same avatar size as the
+ proprietary client is likely to lead to the best display to other
+ users.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedAvatarWidth"
+ tp:name-for-bindings="Recommended_Avatar_Width"
+ type="u" access="read">
+ <tp:added version="0.17.22"/>
+ <tp:docstring>
+ The recommended width in pixels of an avatar on this protocol, or 0 if
+ there is no preferred width.
+ This property cannot change after the Connection goes to the Connected
+ state.
+
+ <tp:rationale>
+ The rationale is the same as for
+ <tp:member-ref>RecommendedAvatarHeight</tp:member-ref>.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarHeight"
+ tp:name-for-bindings="Maximum_Avatar_Height"
+ type="u" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ The maximum height in pixels of an avatar on this protocol, or 0 if
+ there is no limit.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarWidth"
+ tp:name-for-bindings="Maximum_Avatar_Width"
+ type="u" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ The maximum width in pixels of an avatar on this protocol, or 0 if
+ there is no limit.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarBytes"
+ tp:name-for-bindings="Maximum_Avatar_Bytes"
+ type="u" access="read">
+ <tp:added version="0.17.22">Fall back to calling
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref> if getting this
+ property fails.</tp:added>
+ <tp:docstring>
+ The maximum size in bytes of an avatar on this protocol, or 0 if
+ there is no limit.
+ This property cannot change after the Connection goes to the Connected
+ state.
+ </tp:docstring>
+ </property>
+
+ <method name="GetAvatarRequirements"
+ tp:name-for-bindings="Get_Avatar_Requirements">
+ <tp:deprecated version="0.17.22">Use GetAll to retrieve the
+ D-Bus properties on this interface, falling back to this method
+ on failure.</tp:deprecated>
+ <arg direction="out" type="as" name="MIME_Types">
+ <tp:docstring>
+ An array of supported MIME types (eg image/jpeg)
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="q" name="Min_Width">
+ <tp:docstring>
+ The minimum image width in pixels
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="q" name="Min_Height">
+ <tp:docstring>
+ The minimum image height in pixels
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="q" name="Max_Width">
+ <tp:docstring>
+ The maximum image width in pixels, or 0 if there is no limit
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="q" name="Max_Height">
+ <tp:docstring>
+ The maximum image height in pixels, or 0 if there is no limit
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="u" name="Max_Bytes">
+ <tp:docstring>
+ The maximum image size in bytes, or 0 if there is no limit
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get the required format of avatars on this connection.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetAvatarTokens" tp:name-for-bindings="Get_Avatar_Tokens">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="as" name="Tokens" tp:type="Avatar_Token[]">
+ <tp:docstring>
+ An array of avatar tokens or empty strings (if no avatar is set) in the
+ same order as the given array of contact handles
+ </tp:docstring>
+ </arg>
+ <tp:deprecated version="0.15.5">Use GetKnownAvatarTokens
+ instead.</tp:deprecated>
+ <tp:docstring>
+ Get the unique tokens for all of the given contacts' avatars.
+
+ Using this method in new Telepathy clients is deprecated; use
+ <tp:member-ref>GetKnownAvatarTokens</tp:member-ref> instead.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetKnownAvatarTokens"
+ tp:name-for-bindings="Get_Known_Avatar_Tokens">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a{us}" name="Tokens" tp:type="Avatar_Token_Map">
+ <tp:docstring>
+ A dictionary of handles mapped to avatar tokens, containing only
+ the known avatar tokens.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get the unique tokens for the given contacts' avatars. These tokens
+ can be persisted across connections, and should be used by the client
+ to check whether the avatars have been updated. For handles other than
+ the self handle, only tokens that are already known are returned; an
+ empty token means the given contact has no avatar. However, a CM must
+ always have the tokens for the self handle if one is set (even if it is
+ set to no avatar). On protocols where the avatar does not persist
+ between connections, a CM should omit the self handle from the returned
+ map until an avatar is explicitly set or cleared.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestAvatar" tp:name-for-bindings="Request_Avatar">
+ <arg direction="in" name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for the contact to request the avatar for
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="ay" name="Data">
+ <tp:docstring>
+ An array of bytes containing the image data
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="s" name="MIME_Type">
+ <tp:docstring>
+ A string containing the image MIME type (eg image/jpeg), or empty if
+ unknown
+ </tp:docstring>
+ </arg>
+ <tp:deprecated version="0.15.5">Use RequestAvatars
+ instead.</tp:deprecated>
+ <tp:docstring>
+ Request the avatar for a given contact. Using this method in new
+ Telepathy clients is deprecated; use RequestAvatars instead.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact does not currently have an avatar.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestAvatars" tp:name-for-bindings="Request_Avatars">
+ <arg direction="in" name="Contacts" type="au"
+ tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The contacts to retrieve avatars for
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request avatars for a number of contacts. The
+ <tp:member-ref>AvatarRetrieved</tp:member-ref> signal is emitted for
+ each avatar retrieved. If the handles are valid but retrieving an
+ avatar fails (for any reason, including the contact not having an
+ avatar) the AvatarRetrieved signal is not emitted for that contact.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="SetAvatar" tp:name-for-bindings="Set_Avatar">
+ <arg direction="in" name="Avatar" type="ay">
+ <tp:docstring>
+ An array of bytes representing the avatar image data
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="MIME_Type" type="s">
+ <tp:docstring>
+ A string representing the image MIME type
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="s" name="Token" tp:type="Avatar_Token">
+ <tp:docstring>
+ The string token of the new avatar
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Set a new avatar image for this connection. The avatar image must
+ respect the requirements obtained by
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref>.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="ClearAvatar" tp:name-for-bindings="Clear_Avatar">
+ <tp:added version="0.15.0" />
+ <tp:docstring>
+ Remove the avatar image for this connection.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:contact-attribute name="token" type="s" tp:type="Avatar_Token">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same string that would be returned by
+ <tp:member-ref>GetKnownAvatarTokens</tp:member-ref>
+ (omitted from the result if the contact's avatar token is not known,
+ present as an empty string if the contact is known not to have
+ an avatar). Unlike in the
+ <tp:member-ref>GetKnownAvatarTokens</tp:member-ref>
+ method, the avatar tokens for the self handle aren't required to be
+ present. This attribute should not be used to determine whether or
+ not the Avatar needs to be set.
+ </p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for requesting avatars for contacts on a given connection,
+ receiving notification when avatars are changed, and publishing your own
+ avatar.</p>
+
+ <p>Avatars are identified by a string, the <tp:type>Avatar_Token</tp:type>,
+ which represents a particular avatar. Tokens MUST be chosen by the
+ connection manager in such a way that the triple
+ (<tp:type>Connection_Manager_Name</tp:type>, <tp:type>Protocol</tp:type>,
+ <tp:type>Avatar_Token</tp:type>) uniquely identifies an avatar.
+ An empty token means that an avatar has not been set for this contact, and
+ a changed token implies the contact's avatar has changed, but the strings
+ should otherwise be considered opaque by clients.</p>
+
+ <p>A client should use <tp:member-ref>GetKnownAvatarTokens</tp:member-ref>
+ to request the tokens for the
+ avatars of all the contacts it is interested in when it connects. The
+ avatars can then be requested using
+ <tp:member-ref>RequestAvatars</tp:member-ref> for the contacts. Clients
+ should bind to the <tp:member-ref>AvatarUpdated</tp:member-ref> signal and
+ request a new copy of
+ the avatar when a contacts' avatar token changes. Clients should cache the
+ token and data of each contact's avatar between connections, to avoid
+ repeatedly retrieving the same avatar.</p>
+
+ <p>To publish an avatar, a client should use
+ <tp:member-ref>SetAvatar</tp:member-ref> to provide an image which meets
+ the requirements returned by the
+ <tp:member-ref>GetAvatarRequirements</tp:member-ref>
+ function. On some protocols the avatar is stored on the server, so setting
+ the avatar is persistent, but on others it is transferred via a peer to
+ peer mechanism, so needs to be set every connection. Hence, on every
+ connection, clients should inspect the avatar token of the connection's
+ self handle using <tp:member-ref>GetKnownAvatarTokens</tp:member-ref>; if
+ the self handle is not in the
+ returned map, the client should re-set the avatar. If the self handle's
+ avatar token is known, but the avatar has been changed locally since the
+ last connection, the client should upload the new avatar; if the avatar has
+ not changed locally, then the client should download the avatar from the
+ server if its token differs from the that of the local avatar.</p>
+
+ <p>To remove the published avatar on protocols which have persistent avatars,
+ a client should use the <tp:member-ref>ClearAvatar</tp:member-ref> method.
+ This method can safely be used even if there is no avatar for this
+ connection.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Balance.xml b/spec/spec/Connection_Interface_Balance.xml
new file mode 100644
index 000000000..974c651fd
--- /dev/null
+++ b/spec/spec/Connection_Interface_Balance.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Balance"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Balance">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.19.0">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>In many real-time communication services the user can pay for certain
+ services, typically calls to the
+ <abbr title="Public Switched Telephone Network">PSTN</abbr>,
+ in advance. In (at least) Skype, it's possible to query the current
+ balance in a machine-readable way.</p>
+ </tp:docstring>
+
+ <tp:struct name="Currency_Amount">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An amount of money in a specified currency. For example,
+ 3.21 British pounds would conventionally be represented by
+ (<var>Amount</var> = <tt>321</tt>, <var>Scale</var> = <tt>2</tt>,
+ <var>Currency</var> = <tt>"GBP"</tt>), but could be represented by
+ (<var>Amount</var> = <tt>3210</tt>, <var>Scale</var> = <tt>3</tt>,
+ <var>Currency</var> = <tt>"GBP"</tt>) in a service that records
+ balance in units of 0.001 pounds.</p>
+
+ <p>As a special case, if <var>Amount</var> = <tt>0</tt>,
+ <var>Scale</var> = <tt>2**32 - 1</tt> (i.e. the largest possible
+ 32-bit unsigned integer) and <var>Currency</var> = <tt>""</tt>, this
+ indicates an unknown amount.</p>
+ </tp:docstring>
+
+ <tp:member type="i" name="Amount">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The amount, expressed as a fixed-point number with decimal scale
+ defined by the <var>Scale</var> field; for instance, an
+ <var>Amount</var> value of <tt>1234</tt> with <var>Scale</var> of
+ <tt>2</tt> represents 12.34 in the currency unit given by the
+ <var>Currency</var> field.</p>
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Scale">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The decimal scale for the fixed point value of the
+ <var>Amount</var> field, defining the number of rightmost decimal
+ digits from the integer value which form the fractional part of the
+ resulting currency value.</p>
+
+ <p>As well as defining the interpretation of <var>Amount</var>, user
+ interfaces may use this value to determine the precision with which
+ to display the amount.</p>
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Currency">
+ <tp:docstring>
+ The currency code represented by this amount, which SHOULD be an
+ international currency code such as <tt>"EUR"</tt>, <tt>"USD"</tt>,
+ or <tt>"JPY"</tt> if possible. An empty string can be used to
+ indicate that the currency is not known.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="AccountBalance" tp:name-for-bindings="Account_Balance"
+ access="read" type="(ius)" tp:type="Currency_Amount">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The user's balance on the account corresponding to this <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>.
+ A negative amount may be possible on some services, and indicates
+ that the user owes money to the service provider.</p>
+
+ <p>On initial connection, this property may have an unknown
+ value, represented by <var>Amount</var> = <tt>0</tt>,
+ <var>Scale</var> = <tt>2**32 - 1</tt> (the largest possible 32-bit
+ unsigned integer) and <var>Currency</var> = <tt>""</tt>.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ManageCreditURI"
+ tp:name-for-bindings="Manage_Credit_URI"
+ access="read" type="s">
+ <tp:added version="0.22.2"/>
+ <tp:docstring>
+ A URI the user may visit via the web browser to manage and top-up their
+ account balance. This property is not guaranteed to be well-defined
+ until the connection becomes Connected; there is no change
+ notification.
+
+ <tp:rationale>
+ Different protocols and even servers or gateways (e.g. SIP and XMPP
+ PSTN gateways) will have a different website used to manage a user's
+ account balance. This property enables the client to provide that
+ to the user. A Connection Manager MAY set this itself (because it is
+ static or discoverable), or expose it as a connection parameter.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <signal name="BalanceChanged" tp:name-for-bindings="Balance_Changed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the user's balance has changed.</p>
+ </tp:docstring>
+
+ <arg name="Balance" type="(ius)" tp:type="Currency_Amount">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The new value of the <tp:member-ref>AccountBalance</tp:member-ref>
+ property.</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Capabilities.xml b/spec/spec/Connection_Interface_Capabilities.xml
new file mode 100644
index 000000000..8e5eb3357
--- /dev/null
+++ b/spec/spec/Connection_Interface_Capabilities.xml
@@ -0,0 +1,254 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Capabilities" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Capabilities">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connections where it is possible to know what channel
+ types may be requested before the request is made to the connection
+ object. Each capability represents a commitment by the connection
+ manager that it will ordinarily be able to create a channel when given
+ a request with the given type and handle.</p>
+
+ <p>Capabilities pertain to particular contact handles, and represent
+ activities such as having a text chat or a voice call with the user.
+ The activities are represented by the D-Bus interface name of the
+ channel type for that activity.</p>
+
+ <p>The generic capability flags are defined by
+ <tp:type>Connection_Capability_Flags</tp:type>.</p>
+
+ <p>In addition, channel types may have type specific capability flags of
+ their own, which are described in the documentation for each channel
+ type.</p>
+
+ <p>This interface also provides for user interfaces notifying the
+ connection manager of what capabilities to advertise for the user. This
+ is done by using the
+ <tp:member-ref>AdvertiseCapabilities</tp:member-ref> method, and deals
+ with the
+ interface names of channel types and the type specific flags pertaining
+ to them which are implemented by available client processes.</p>
+ </tp:docstring>
+
+ <tp:changed version="0.17.8">Previously, this interface
+ also expressed capabilities of the connection itself, indicating what
+ sorts of channels could be requested (for instance, the ability to
+ open chatroom lists or chatrooms). However, this was never very
+ well-defined or consistent, and as far as we know it was never
+ implemented correctly. This usage is now deprecated.</tp:changed>
+
+ <tp:deprecated version="0.19.8">Client implementations SHOULD use <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">ContactCapabilities</tp:dbus-ref>
+ instead.</tp:deprecated>
+ <tp:changed version="0.19.8">Connection managers implementing
+ Capabilities MUST implement ContactCapabilities too.</tp:changed>
+
+ <tp:flags name="Connection_Capability_Flags"
+ value-prefix="Connection_Capability_Flag" type="u">
+ <tp:flag suffix="Create" value="1">
+ <tp:docstring>
+ The given channel type and handle can be given to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">RequestChannel</tp:dbus-ref>
+ to create a new channel of this type.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Invite" value="2">
+ <tp:docstring>
+ The given contact can be invited to an existing channel of this type.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:struct name="Capability_Pair" array-name="Capability_Pair_List">
+ <tp:docstring>A pair (channel type, type-specific flags) as passed to
+ <tp:member-ref>AdvertiseCapabilities</tp:member-ref> on the
+ Capabilities interface.</tp:docstring>
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type"/>
+ <tp:member type="u" name="Type_Specific_Flags"/>
+ </tp:struct>
+
+ <tp:struct name="Contact_Capability" array-name="Contact_Capability_List">
+ <tp:docstring>A struct (contact handle, channel type, generic flags,
+ type-specific flags) representing a capability posessed by a contact,
+ as returned by <tp:member-ref>GetCapabilities</tp:member-ref> on the
+ Capabilities interface.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type"/>
+ <tp:member type="u" tp:type="Connection_Capability_Flags"
+ name="Generic_Flags"/>
+ <tp:member type="u" name="Type_Specific_Flags"/>
+ </tp:struct>
+
+ <tp:struct name="Capability_Change" array-name="Capability_Change_List">
+ <tp:docstring>A struct (contact handle, channel type, old generic flags,
+ new generic flags, old type-specific flags, new type-specific flags)
+ representing a change to one of a contact's capabilities, as seen in the
+ <tp:member-ref>CapabilitiesChanged</tp:member-ref> signal on the
+ Capabilities interface.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type"/>
+ <tp:member type="u" tp:type="Connection_Capability_Flags"
+ name="Old_Generic_Flags"/>
+ <tp:member type="u" tp:type="Connection_Capability_Flags"
+ name="New_Generic_Flags"/>
+ <tp:member type="u" name="Old_Type_Specific_Flags"/>
+ <tp:member type="u" name="New_Type_Specific_Flags"/>
+ </tp:struct>
+
+ <method name="AdvertiseCapabilities"
+ tp:name-for-bindings="Advertise_Capabilities">
+ <arg direction="in" name="Add" type="a(su)" tp:type="Capability_Pair[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structures containing:
+ <ul>
+ <li>a string channel type</li>
+ <li>a bitwise OR of type specific capability flags</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Remove" type="as" tp:type="DBus_Interface[]">
+ <tp:docstring>
+ An array of D-Bus interface names of channel types to remove
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a(su)" tp:type="Capability_Pair[]"
+ name="Self_Capabilities">
+ <tp:docstring>
+ An array of structures describing the current capabilities containing:
+ <ul>
+ <li>a string channel type</li>
+ <li>a bitwise OR of type specific capability flags</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Used by user interfaces to indicate which channel types they are able
+ to handle on this connection. Because these may be provided by
+ different client processes, this method accepts channel types to add
+ and remove from the set already advertised on this connection. The type
+ of advertised capabilities (create versus invite) is protocol-dependent
+ and hence cannot be set by the this method. In the case of a client
+ adding an already advertised channel type but with new channel type
+ specific flags, the connection manager should simply add the new flags
+ to the set of advertised capabilities.</p>
+
+ <p>Upon a successful invocation of this method, the
+ <tp:member-ref>CapabilitiesChanged</tp:member-ref>
+ signal will be emitted for the user's own handle ( <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.GetSelfHandle</tp:dbus-ref>)
+ by the connection manager to indicate the changes
+ that have been made. This signal should also be monitored to ensure
+ that the set is kept accurate - for example, a client may remove
+ capabilities or type specific capability flags when it exits
+ which are still provided by another client.</p>
+
+ <p>On connections managed by the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatcher</tp:dbus-ref>,
+ this method SHOULD NOT be used by clients other than the
+ ChannelDispatcher itself.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="CapabilitiesChanged"
+ tp:name-for-bindings="Capabilities_Changed">
+ <arg name="Caps" type="a(usuuuu)" tp:type="Capability_Change[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structures containing:
+ <ul>
+ <li>an integer handle representing the contact</li>
+ <li>a string channel type</li>
+ <li>a bitwise OR of the contact's old generic capability flags</li>
+ <li>a bitwise OR of the contact's new generic capability flags</li>
+ <li>a bitwise OR of the contact's old type specific capability flags</li>
+ <li>a bitwise OR of the contact's new type specific capability flags</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Announce that there has been a change of capabilities on the
+ given handle.</p>
+
+ <p>If the handle is zero, the capabilities refer to the connection
+ itself, in some poorly defined way. This usage is deprecated and
+ clients should ignore it.</p>
+ </tp:docstring>
+ </signal>
+
+ <method name="GetCapabilities" tp:name-for-bindings="Get_Capabilities">
+ <arg direction="in" name="Handles" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of contact handles for this connection.</p>
+
+ <p>This may include zero, which originally meant a query for
+ capabilities available on the connection itself. This usage
+ is deprecated; clients SHOULD NOT do this, and connection managers
+ SHOULD proceed as though zero had not been present in this
+ list.</p>
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a(usuu)" tp:type="Contact_Capability[]"
+ name="Contact_Capabilities">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structures containing:
+ <ul>
+ <li>an integer handle representing the contact</li>
+ <li>a string channel type</li>
+ <li>a bitwise OR of generic capability flags for the type</li>
+ <li>a bitwise OR of type specific capability flags for the type</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Returns an array of capabilities for the given contact handles.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ The handle does not represent a contact and is not zero
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:contact-attribute name="caps"
+ type="a(usuu)" tp:type="Contact_Capability[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same structs that would be returned by
+ <tp:member-ref>GetCapabilities</tp:member-ref>
+ (all of them will redundantly have the contact's handle as the
+ first member). Omitted from the result if the contact's capabilities
+ are not known; present in the result as an empty array if the
+ contact is known to have no capabilities at all.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Cellular.xml b/spec/spec/Connection_Interface_Cellular.xml
new file mode 100644
index 000000000..e9b10e3c5
--- /dev/null
+++ b/spec/spec/Connection_Interface_Cellular.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Cellular"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2008-2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Cellular">
+ <tp:added version="0.19.8">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface is for various cellular things (GSM and/or CDMA) that
+ aren't really applicable to other protocols.</p>
+ </tp:docstring>
+
+ <property name="MessageValidityPeriod" tp:name-for-bindings="Message_Validity_Period"
+ type="u" access="readwrite"
+ tp:is-connection-parameter='yup'>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Define how long should the service centre try message delivery before
+ giving up, failing delivery and deleting the message. A value of 0
+ means to use the service centre's default period.</p>
+
+ <p>The value specified is in seconds. Note that various protocols or
+ implementations may round the value up (eg. to a minute or hour
+ precision). The maximum validity period may vary depending on
+ protocol or provider.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="OverrideMessageServiceCentre"
+ tp:name-for-bindings="Override_Message_Service_Centre"
+ type="b" access="readwrite"
+ tp:is-connection-parameter='can i get a hell yeah?'>
+ <tp:added version='0.19.12'>Previously, as an undocumented
+ feature, setting <tp:member-ref>MessageServiceCentre</tp:member-ref>
+ to the empty string caused the SIM's default SMSC to be used.</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If <code>True</code>, SMSes will be sent via the service centre
+ specified by <tp:member-ref>MessageServiceCentre</tp:member-ref>. If
+ <code>False</code>, the SIM's default SMSC will be used, ignoring the
+ value of MessageServiceCentre.</p>
+
+ <tp:rationale>
+ <p>It could be desirable for a configuration interface to remember
+ the user's previous choice of custom SMSC, even if it's not in use.
+ This boolean allows that choice to be saved as an account parameter
+ by Mission Control, rather than the UI needing to save it elsewhere
+ to be restored if the user wants to reactivate it.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="MessageServiceCentre" tp:name-for-bindings="Message_Service_Centre"
+ type="s" access="readwrite"
+ tp:is-connection-parameter='HELL YEAH!!!'>
+ <tp:changed version='0.19.12'>This property's value is now
+ ignored unless
+ <tp:member-ref>OverrideMessageServiceCentre</tp:member-ref> is
+ <code>True</code>.</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+
+ <p>Address for the messaging service centre. Typically (as is the case
+ for GSM's SMSC), it's the ISDN / telephony address (ie. a phone
+ number). If
+ <tp:member-ref>OverrideMessageServiceCentre</tp:member-ref> is
+ <code>False</code>, this property's value should be ignored by the CM
+ in favour of the SIM's default SMSC.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="IMSI" tp:name-for-bindings="IMSI" type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The International Mobile Subscriber Identifier, if it exists. This
+ would originate from a SIM card. If the IMSI is unknown, this will
+ contain an empty string ("").</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="IMSIChanged" tp:name-for-bindings="IMSI_Changed">
+ <tp:docstring>
+ Emitted when the IMSI for the connection changes. This sort of thing
+ is rare, but could happen on cellular phones that allow hot-swapping
+ of SIM cards. In the case of SIM swapping, this signal would be
+ emitted twice; the first time while the SIM is being ejected (with an
+ empty string), and the second time after a new SIM has been inserted
+ (assuming that the IMSI can be determined from the new SIM).
+ </tp:docstring>
+
+ <arg name="IMSI" type="s">
+ <tp:docstring>
+ The new IMSI value. This may be an empty string in the case where
+ the IMSI is being reset or removed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="MessageReducedCharacterSet"
+ tp:name-for-bindings="Message_Reduced_Character_Set"
+ type="b" access="readwrite"
+ tp:is-connection-parameter='no... just kidding! yes!'>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Determines how to encode SMSes containing characters that do not
+ fit into a non-Unicode character set.
+ If <code>False</code> (which SHOULD be the default), messages will
+ be encoded as UCS-2 and sent with no loss of fidelity (at the
+ potential financial cost of using twice as many SMSes); if
+ <code>True</code>, the message will be recoded in an
+ implementation‐specific way to fit into a GSM reduced character
+ set.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="MessageNationalCharacterSet"
+ tp:name-for-bindings="Message_National_Character_Set"
+ type="s" access="readwrite"
+ tp:is-connection-parameter='affirmative'>
+ <tp:added version="0.21.12"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Hint for the connection manager for the GSM character set that
+ should be used to send SMSes. The connection manager SHOULD follow
+ this hint unless it has other ways to determine a better encoding.
+ If the value is <code>"gsm"</code> (which SHOULD be the default),
+ SMSes will be encoded in the normal 7-bit GSM character set,
+ eventually falling back to UCS-2; see the
+ <tp:member-ref>MessageReducedCharacterSet</tp:member-ref> property
+ for details.
+ Other valid character sets are specified in the
+ <a href="http://www.3gpp.org/ftp/specs/archive/23_series/23.038/"
+ >GSM standard</a> and are, for instance, <code>"turkey"</code>,
+ <code>"spain"</code> or <code>"portugal"</code>.
+ If the SMS cannot be encoded using the requested character set the
+ behaviour is implementation-specific, but it is RECOMMENDED that
+ the connection manager should behave as if this property was set
+ to <code>"gsm"</code>.</p>
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Client_Types.xml b/spec/spec/Connection_Interface_Client_Types.xml
new file mode 100644
index 000000000..97908561a
--- /dev/null
+++ b/spec/spec/Connection_Interface_Client_Types.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Client_Types"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ClientTypes">
+ <tp:added version="0.21.1">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface on connections to support protocols which allows users to
+ subscribe to the client types of their contacts.</p>
+
+ <p>One can connect to instant messaging networks on a huge variety of
+ devices, from PCs, to phones to consoles. It can be useful for users
+ to know what kind of device a contact is using so that he or she
+ can decide not to send that big file or start a video chat. This
+ interface exposes exactly this information for clients to display.</p>
+
+ <p>The client types are represented in strings, using the values
+ <a href="http://xmpp.org/registrar/disco-categories.html#client">
+ documented by the XMPP registrar</a> with some additional types
+ added for other protocols. A contact can set one or more client types
+ so this interface returns a list of strings to denote client types
+ for a contact. The well-known client types to be used are:</p>
+
+ <ul>
+ <li>bot</li>
+ <li>console (minimal non-GUI client used on dumb terminals or
+ text-only screens, <strong>not</strong> a games console)</li>
+ <li>handheld</li>
+ <li>pc</li>
+ <li>phone</li>
+ <li>web</li>
+<!-- Excluding these two because there's been no conclusion regarding my mail
+ to standards@xmpp.org about adding these two to their list:
+
+ <li>sms (the client is not actually an instant messaging client
+ but all messages sent to this contact will be delivered as SMSs)</li>
+ <li>game (a gaming device)</li>
+-->
+ </ul>
+
+ <p>If the empty list is given as the client types, this means that
+ details about the contact's client types are unknown. If there are
+ multiple resources of a contact online at one point in time, the
+ client types of the most available resource will be returned. In
+ other words, the returned client types are those for the resource whose
+ presence will be retreived using the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface">SimplePresence</tp:dbus-ref>
+ interface.</p>
+
+ <p>For example, if a contact has two resources:</p>
+
+ <ul>
+ <li>their phone, with presence "available"; and</li>
+ <li>their pc, with presence "busy";</li>
+ </ul>
+
+ <p>then the methods in this interface will return an array (with
+ one element: "phone") as the client types because that is the more
+ available resource. If at some later time the contact's phone's presence
+ changes to "away", the
+ <tp:member-ref>ClientTypesUpdated</tp:member-ref> signal will
+ notify that the contact's client types attribute has changed from
+ ["phone"] to ["pc"],
+ because "busy" is a more available presence than "away".</p>
+
+ </tp:docstring>
+
+ <tp:mapping name="Contact_Client_Types">
+ <tp:docstring>
+ A mapping from contact handle to client types.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact">
+ <tp:docstring>
+ A contact.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="as" name="Client_Types" tp:type="Contact_Client_Type[]">
+ <tp:docstring>
+ The contact's client types as documented earlier in this interface.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <method name="GetClientTypes" tp:name-for-bindings="Get_Client_Types">
+ <tp:docstring>
+ Return the client types of the given contacts, if they are
+ already known. If any of the given contacts' client types are
+ not known, request their current client types, but return
+ immediately without waiting for a reply; if a reply with a
+ non-empty client type array is later received for those
+ contacts, the
+ <tp:member-ref>ClientTypesUpdated</tp:member-ref> signal will
+ be emitted for them.
+
+ <tp:rationale>
+ This method is appropriate for "lazy" client type finding, for instance
+ displaying the client types (if available) of everyone in your contact
+ list.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The contacts whose client types should be returned or signalled.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Client_Types" type="a{uas}"
+ tp:type="Contact_Client_Types">
+ <tp:docstring>
+ The contacts' client types, if already known. Contacts whose client
+ types are not already known are omitted from the mapping; contacts known
+ to have no client type information appear in the mapping with an empty
+ list.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestClientTypes" tp:name-for-bindings="Request_Client_Types">
+ <tp:docstring>
+ Return the current client types of the given contact. If necessary, make
+ a request to the server for up-to-date information, and wait for a
+ reply.
+
+ <tp:rationale>
+ This method is appropriate for use in a "Contact Information..."
+ dialog; it can be used to show progress information (while waiting
+ for the method to return), and can distinguish between various error
+ conditions.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact whose client types should be returned.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Client_Types" type="as"
+ tp:type="Contact_Client_Type[]">
+ <tp:docstring>
+ The contact's client types. It MAY be empty, indicating that no client
+ type information was found.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied">
+ <tp:docstring>
+ The requested contact does not allow the local user to see their
+ client type information.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="ClientTypesUpdated" tp:name-for-bindings="Client_Types_Updated">
+ <tp:docstring>
+ Emitted when a contact's client types change or become known.
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact.
+ </tp:docstring>
+ </arg>
+ <arg name="Client_Types" type="as" tp:type="Contact_Client_Type[]">
+ <tp:docstring>
+ The contact's client types, or an empty list to indicate that nothing
+ is known about the contact's client types.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:contact-attribute name="client-types" type="as"
+ tp:type="Contact_Client_Type[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same mapping that would be returned by
+ <tp:member-ref>GetClientTypes</tp:member-ref> for this contact.
+ Omitted from the result if the contact's client types are not
+ known.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:simple-type name="Contact_Client_Type" type="s"
+ array-name="Contact_Client_Type_List">
+ <tp:docstring>A string representing a single client type of a
+ contact.</tp:docstring>
+ </tp:simple-type>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Communication_Policy.xml b/spec/spec/Connection_Interface_Communication_Policy.xml
new file mode 100644
index 000000000..31343de68
--- /dev/null
+++ b/spec/spec/Connection_Interface_Communication_Policy.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Communication_Policy"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Limited</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Connection.Interface.CommunicationPolicy.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.1">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.SimplePresence"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ This interface supports controlling which contacts are allowed
+ to initiate text chats, incoming calls, and other forms of
+ communication as supported by the underlying protocol. The
+ policies supported for different communication methods on this
+ connection are listed in the
+ <tp:member-ref>SupportedPolicies</tp:member-ref> property. The
+ current configuration is held in
+ <tp:member-ref>ActivePolicies</tp:member-ref>; it can be modified
+ using <tp:member-ref>SetPolicy</tp:member-ref>, and changes
+ are signalled by <tp:member-ref>PolicyChanged</tp:member-ref>.
+ </p>
+ </tp:docstring>
+
+ <tp:mapping name="Active_Policies_Map">
+ <tp:docstring>
+ A mapping of communication methods (channel types), and their
+ associated policy.
+ </tp:docstring>
+
+ <tp:member type="s" tp:type="DBus_Interface" name="Channel_Type">
+ <tp:docstring>
+ The channel interface with the policy.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="(uv)" tp:type="Access_Control" name="Active_Policy">
+ <tp:docstring>
+ The active policy for this channel type.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="SupportedPolicies"
+ tp:name-for-bindings="Supported_Policies" access="read"
+ type="a(asau)" tp:type="Supported_Policy[]">
+ <tp:docstring>
+ The communication policies supported by this connection.
+ </tp:docstring>
+ </property>
+
+ <property name="ActivePolicies" tp:name-for-bindings="Active_Policies"
+ access="read" type="a{s(uv)}" tp:type="Active_Policies_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The active communication policies on this
+ connection. Communication methods that are not in this
+ mapping are considered open.</p>
+
+ <p>For example, to allow incoming calls only from contacts
+ buddy list, and to allow text messages from anyone,
+ the policy would look like this:</p>
+
+ <pre>
+{
+ 'org.freedesktop.Telepathy.Channel.Type.Text' : Access_Control_Type_Open,
+ 'org.freedesktop.Telepathy.Channel.Type.Call' : Access_Control_Type_Publish_List
+}
+ </pre>
+
+ <p>Changes to this property are signalled by
+ <tp:member-ref>PolicyChanged</tp:member-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="SetPolicy" tp:name-for-bindings="Set_Policy">
+ <tp:docstring>
+ Set a policy for a communication method (channel
+ type). Depending on the server or protocol, more than one
+ communication method could be bound to the same policy, if
+ calling this method on one channel type changes the policy on
+ another channel type, the <tp:member-ref>PolicyChanged</tp:member-ref>
+ signal that would follow would include all the channel types
+ that have an altered policy.
+ </tp:docstring>
+ <arg name="Channel_Type" direction="in" type="s"
+ tp:type="DBus_Interface">
+ <tp:docstring>
+ The channel type to set the policy for.
+ </tp:docstring>
+ </arg>
+ <arg name="Policy" direction="in" type="(uv)"
+ tp:type="Access_Control">
+ <tp:docstring>
+ The policy to set for this channel.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="PolicyChanged" tp:name-for-bindings="Policy_Changed">
+ <tp:docstring>
+ <tp:member-ref>ActivePolicies</tp:member-ref> has
+ changed. This occurs when the server unilaterally changed the
+ policy or <tp:member-ref>SetPolicy</tp:member-ref> has been
+ called.
+ </tp:docstring>
+ <arg name="Changed_Policies" type="a{s(uv)}"
+ tp:type="Active_Policies_Map">
+ <tp:docstring>
+ A subset of the active policies that have changed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:struct name="Supported_Policy" array-name="Supported_Policy_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The communication methods (channel types), and the policies
+ that can be applied to them. This is server and protocol
+ dependant.</p>
+
+ <p>Grouped channel types will always have the same policy applied
+ to them.</p>
+
+ <tp:rationale>
+ Different protocols have different limitations to the
+ granularity of communication policies. One protocol might be
+ able to set a different policy for VoIP calls and text chat,
+ while another protocol might only be able to set one policy
+ to both VoIP and text chat.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:member type="as" tp:type="DBus_Interface[]"
+ name="Channel_Types">
+ <tp:docstring>
+ A list of channel interfaces that support these policies.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="au" tp:type="Access_Control_Type[]"
+ name="Supported_Policies">
+ <tp:docstring>
+ A list of supported policies.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ </interface>
+</node>
diff --git a/spec/spec/Connection_Interface_Contact_Blocking.xml b/spec/spec/Connection_Interface_Contact_Blocking.xml
new file mode 100644
index 000000000..756fd4db8
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contact_Blocking.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contact_Blocking" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009–2011 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactBlocking">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.ContactList"/>
+ <tp:added version='0.21.13'>Changes from the draft:
+ methods and signals now return <tp:type>Handle_Identifier_Map</tp:type>
+ (<code>a{us}</code>) rather than bare lists of contact handles
+ (<code>au</code>)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connections where contacts can be blocked from
+ communicating with this user and receiving this user's presence.
+ Clients may retrieve a list of currently-blocked contacts using
+ <tp:member-ref>RequestBlockedContacts</tp:member-ref>, and listen for
+ <tp:member-ref>BlockedContactsChanged</tp:member-ref> to be notified
+ when contacts are blocked and unblocked. The
+ <tp:member-ref>BlockContacts</tp:member-ref> and
+ <tp:member-ref>UnblockContacts</tp:member-ref> methods do what they say
+ on the tin; depending on the value of the
+ <tp:member-ref>ContactBlockingCapabilities</tp:member-ref> property,
+ contacts may be reported for spam or other abuse when calling
+ <tp:member-ref>BlockContacts</tp:member-ref>.</p>
+
+ <p>This interface is intended for protocols where blocking contacts
+ persists on the server between connections; connection managers for
+ protocols with no server-side support for blocking contacts MAY choose
+ to implement this interface using an on-disk file of blocked
+ contacts or some other means to store blocked contacts between
+ connections.</p>
+
+ <p>This interface is intended to replace the
+ <tp:dbus-ref namespace="ofdT.Channel.Type">ContactList</tp:dbus-ref>
+ channel with <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>
+ <code>List</code> and <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetID</tp:dbus-ref> <code>"deny"</code>
+ (along with the <tp:dbus-ref
+ namespace='ofdT.Connection.Interface'>ContactList</tp:dbus-ref> and
+ <tp:dbus-ref
+ namespace='ofdT.Connection.Interface'>ContactGroups</tp:dbus-ref>
+ interfaces replacing other channels with <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>
+ <code>List</code> and <tp:dbus-ref
+ namespace='ofdT.Channel'>TargetHandleType</tp:dbus-ref>
+ <code>Group</code>, respectively).</p>
+ </tp:docstring>
+
+ <method name="BlockContacts" tp:name-for-bindings="Block_Contacts">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Direct the server to block some contacts. The precise effect is
+ protocol-dependent, but SHOULD include ignoring all current and
+ subsequent communications from the given contacts, avoiding sending
+ presence to them in future, and if they were already receiving the
+ local user's presence, behaving as if the local user went
+ offline.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" type="au" direction="in" tp:type="Contact_Handle[]">
+ <tp:docstring>Some contacts to block. If some of the contacts in this
+ list are already blocked, the connection manager MUST act as if they
+ were not specified in this list.</tp:docstring>
+ </arg>
+
+ <arg name="Report_Abusive" type="b" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>In addition to blocking, report these contacts as abusive to the
+ server administrators.</p>
+
+ <p>Clients can determine whether this capability is available by
+ checking the
+ <tp:member-ref>ContactBlockingCapabilities</tp:member-ref>
+ property. If this argument is set to <code>True</code> by a client
+ despite <tp:member-ref>ContactBlockingCapabilities</tp:member-ref>
+ not containing the <code>Can_Report_Abusive</code> flag, the
+ connection manager SHOULD act as if it were <code>False</code> and
+ simply block the supplied contacts.</p>
+
+ <tp:rationale>
+ <p>A correct user interface shouldn't get this far without knowing
+ that reporting abusive contacts is not supported. If it does,
+ then the user has expressed their intention to block these
+ contacts. Returning an error would leave the UI with three
+ options:</p>
+
+ <ul>
+ <li>Ignore the error, leaving the contacts not actually blocked;</li>
+ <li>Display an error to the user;</li>
+ <li>Call this method again, passing <code>False</code> for this
+ argument.</li>
+ </ul>
+
+ <p>None of these seem preferable to the CM just ignoring this flag
+ if it doesn't support it: that way, the contacts will be blocked,
+ as the user requested, and UIs have fewer ways to mess up
+ entirely.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="UnblockContacts" tp:name-for-bindings="Unblock_Contacts">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Direct the server to unblock some contacts.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" type="au" direction="in" tp:type="Contact_Handle[]">
+ <tp:docstring>Some contacts to unblock. If some of the contacts in this
+ list are not currently blocked, the connection manager MUST act as if
+ they were not specified in this list.</tp:docstring>
+ </arg>
+ </method>
+
+ <method name="RequestBlockedContacts"
+ tp:name-for-bindings="Request_Blocked_Contacts">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>List the contacts that are blocked.</p>
+
+ <p>Clients SHOULD allow a relatively long timeout for calls to this
+ method, since on some protocols contact blocking is part of the
+ contact list, which can take a significant time to retrieve.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" type="a{us}" direction="out"
+ tp:type="Handle_Identifier_Map">
+ <tp:docstring>The blocked contacts’ handles, together with their
+ identifiers.</tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="BlockedContactsChanged"
+ tp:name-for-bindings="Blocked_Contacts_Changed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the list of blocked contacts is first retrieved
+ (before returning from any pending calls to
+ <tp:member-ref>RequestBlockedContacts</tp:member-ref>), and
+ whenever the list of blocked contacts subsequently changes.</p>
+ </tp:docstring>
+
+ <arg name="Blocked_Contacts" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring>Contacts added to the result of
+ <tp:member-ref>RequestBlockedContacts</tp:member-ref>.</tp:docstring>
+ </arg>
+
+ <arg name="Unblocked_Contacts" type="a{us}"
+ tp:type="Handle_Identifier_Map">
+ <tp:docstring>Contacts removed from the result of
+ <tp:member-ref>RequestBlockedContacts</tp:member-ref>.</tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:contact-attribute name="blocked" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p><code>True</code> if the contact would be in the result of
+ <tp:member-ref>RequestBlockedContacts</tp:member-ref>;
+ <code>False</code> or omitted if the contact is not blocked, or if it
+ is unknown whether the contact is blocked.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <property name="ContactBlockingCapabilities"
+ tp:name-for-bindings="Contact_Blocking_Capabilities"
+ tp:type="Contact_Blocking_Capabilities" type="u" access="read"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Additional capabilities for contact blocking; currently, this is
+ limited to whether contacts may be reported as abusive.</p>
+
+ <p>Note that there is no capability for supporting blocking itself:
+ the presence of this interface on a <tp:dbus-ref
+ namespace='ofdT'>Connection</tp:dbus-ref> indicates that blocking
+ contacts is supported.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Contact_Blocking_Capabilities" type="u"
+ value-prefix="Contact_Blocking_Capability">
+ <tp:flag suffix="Can_Report_Abusive" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ When calling <tp:member-ref>BlockContacts</tp:member-ref>, the
+ contacts may be reporting as abusive to the server administrators by
+ setting <var>Report_Abusive</var> to <code>True</code>.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Contact_Capabilities.xml b/spec/spec/Connection_Interface_Contact_Capabilities.xml
new file mode 100644
index 000000000..fb13c37d7
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contact_Capabilities.xml
@@ -0,0 +1,306 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contact_Capabilities" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006, 2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006, 2008 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.17.28">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Contact capabilities describe the channel classes which may be
+ created with a given contact in advance of attempting to create a
+ channel. Each capability represents a commitment by the
+ connection manager that it will ordinarily be able to create a channel
+ with a contact when given a request with the properties defined by the
+ channel class.</p>
+
+ <p>Capabilities pertain to particular contact handles, and represent
+ activities such as having a text chat, a voice call with the user or a
+ stream tube of a defined type.</p>
+
+ <p>This interface also enables user interfaces to notify the connection
+ manager what capabilities to advertise for the user to other contacts.
+ This is done by using the
+ <tp:member-ref>UpdateCapabilities</tp:member-ref> method.</p>
+
+ <tp:rationale>
+ <p>XMPP is a major user of this interface: XMPP contacts will not,
+ in general, be callable using VoIP unless they advertise suitable
+ Jingle capabilities.</p>
+
+ <p>Many other protocols also have some concept of capability flags,
+ which this interface exposes in a protocol-independent way.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:struct name="Handler_Capabilities"
+ array-name="Handler_Capabilities_List">
+ <tp:docstring>
+ A structure representing the capabilities of a single client.
+ </tp:docstring>
+
+ <tp:member name="Well_Known_Name" type="s" tp:type="DBus_Well_Known_Name">
+ <tp:docstring>
+ For implementations of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Client</tp:dbus-ref>
+ interface, the well-known bus name name of the client; for any other
+ process, any other reversed domain name that uniquely identifies it.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Channel_Classes" type="aa{sv}"
+ tp:type="String_Variant_Map[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of channel classes that can be handled by this client.
+ This will usually be a copy of the client's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ property.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Capabilities"
+ type="as" tp:type="Handler_Capability_Token[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of client capabilities supported by this client, to be
+ used by the connection manager to determine what capabilities to
+ advertise. This will usually be a copy of the client's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">Capabilities</tp:dbus-ref>
+ property.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="UpdateCapabilities" tp:name-for-bindings="Update_Capabilities">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Alter the connection's advertised capabilities to include
+ the intersection of the given clients' capabilities with what the
+ connection manager is able to implement.</p>
+
+ <p>On connections managed by the ChannelDispatcher, processes other
+ than the ChannelDispatcher SHOULD NOT call this method, and the
+ ChannelDispatcher SHOULD use this method to advertise the
+ capabilities of all the registered <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Client.Handler</tp:dbus-ref>
+ implementations.On connections not managed by the ChannelDispatcher,
+ clients MAY use this method directly, to indicate the channels they
+ will handle and the extra capabilities they have.</p>
+
+ <p>Upon a successful invocation of this method, the connection manager
+ will only emit the
+ <tp:member-ref>ContactCapabilitiesChanged</tp:member-ref> signal
+ for the user's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">SelfHandle</tp:dbus-ref>
+ if, in the underlying protocol, the new capabilities are distinct
+ from the previous state.</p>
+
+ <tp:rationale>
+ <p>The connection manager will essentially intersect the provided
+ capabilities and the channel classes it implements. Therefore,
+ certain properties which are never fixed for a channel class
+ (such as the target handle, or the Parameters property of a tube
+ channel) will almost certainly not be advertised.</p>
+ </tp:rationale>
+
+ <p>This method MAY be called on a newly-created connection while it
+ is still in the DISCONNECTED state, to request that when the
+ connection connects, it will do so with the appropriate
+ capabilities. Doing so MUST NOT fail.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Handler_Capabilities" type="a(saa{sv}as)"
+ tp:type="Handler_Capabilities[]">
+ <tp:docstring>
+ <p>The capabilities of one or more clients.</p>
+
+ <p>For each client in the given list, any capabilities previously
+ advertised for the same client name are discarded, then replaced by
+ the capabilities indicated.</p>
+
+ <p>As a result, if a client becomes unavailable, this method SHOULD
+ be called with a <tp:type>Handler_Capabilities</tp:type> structure
+ containing its name, an empty list of channel classes, and an
+ empty list of capabilities. When this is done, the connection
+ manager SHOULD free all memory associated with that client name.</p>
+
+ <tp:rationale>
+ <p>This method takes a list of clients so that
+ when the channel dispatcher first calls it (with a list of all
+ the Handlers that are initially available), the changes can be
+ made atomically, with only one transmission of updated
+ capabilities to the network. Afterwards, the channel dispatcher
+ will call this method with a single-element list every time
+ a Handler becomes available or unavailable.</p>
+ </tp:rationale>
+
+ <p>The connection manager MUST ignore any channel classes and client
+ capabilities for which there is no representation in the protocol
+ or no support in the connection manager.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetContactCapabilities"
+ tp:name-for-bindings="Get_Contact_Capabilities">
+ <arg direction="in" name="Handles" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of contact handles for this connection.</p>
+
+ <p>The handle zero MUST NOT be included in the request.</p>
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a{ua(a{sv}as)}"
+ tp:type="Contact_Capabilities_Map" name="Contact_Capabilities">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from contact handles to lists of requestable channel
+ classes, representing the channel requests that are expected
+ to succeed for that contact.</p>
+
+ <p>Contacts listed among Handles whose capabilities are unknown
+ SHOULD be omitted from this map; contacts known to have an empty
+ set of capabilities SHOULD be included in the keys of this map,
+ with an empty array as the corresponding value.</p>
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Returns an array of requestable channel classes for the given
+ contact handles, representing the channel requests that are
+ expected to succeed.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ The handle does not represent a contact. Zero is always invalid.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="ContactCapabilitiesChanged"
+ tp:name-for-bindings="Contact_Capabilities_Changed">
+ <arg name="caps" type="a{ua(a{sv}as)}"
+ tp:type="Contact_Capabilities_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ All the capabilities of the contacts
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Announce that there has been a change of capabilities on the
+ given handles. A single signal can be emitted for several
+ contacts.</p>
+
+ <tp:rationale>
+ <p>The underlying protocol can get several contacts' capabilities at
+ the same time.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </signal>
+
+ <tp:mapping name="Contact_Capabilities_Map"
+ array-name="Contact_Capabilities_Map_List">
+ <tp:docstring>A mapping from contact handle to their capabilities.
+ </tp:docstring>
+ <tp:member type="u" name="Key" tp:type="Contact_Handle">
+ <tp:docstring>
+ A contact handle.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="a(a{sv}as)" name="Value"
+ tp:type="Requestable_Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The contact's capabilities. These should be represented
+ in the same way as in <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+ >RequestableChannelClasses</tp:dbus-ref>,
+ except that they may have more fixed properties or fewer allowed
+ properties, to represent contacts who do not have all the
+ capabilities of the connection.</p>
+
+ <p>In particular, requestable channel classes for channels with
+ target handle type Contact MUST list <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandleType</tp:dbus-ref> among their fixed properties when
+ they appear here, and clients MAY assume that this will be the
+ case.</p>
+
+ <tp:rationale>
+ <p>This matches the initial implementations - service-side in
+ telepathy-gabble, and client-side in telepathy-qt4 - and means
+ that clients can use exactly the same code to interpret
+ RequestableChannelClasses and contact capabilities.</p>
+ </tp:rationale>
+
+ <p>Channel classes with target handle type Handle_Type_Contact
+ indicate that a request that matches the channel class, and also
+ either has the contact's handle as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel"
+ >TargetHandle</tp:dbus-ref> or the contact's identifier as
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel"
+ >TargetID</tp:dbus-ref>, can be expected to succeed. Connection
+ managers SHOULD NOT include the TargetHandle or TargetID as a
+ fixed property in contact capabilities.</p>
+
+ <tp:rationale>
+ <p>This makes one channel class sufficient to describe requests via
+ TargetHandle or TargetID, and is necessary in order to allow
+ clients to interpret RequestableChannelClasses and contact
+ capabilities with the same code.</p>
+ </tp:rationale>
+
+ <p>Channel classes with target handle type Handle_Type_Room or
+ Handle_Type_None indicate that if a channel matching the channel
+ class is created, then inviting the contact to that channel
+ can be expected to succeed.</p>
+
+ <tp:rationale>
+ <p>To support room-based XMPP protocols like
+ <a href="http://telepathy.freedesktop.org/wiki/Muji">Muji</a>
+ and MUC Tubes, it's necessary to be able to discover who can be
+ invited to a given room channel; most XMPP contacts won't
+ support being invited into a Muji conference call, at least
+ in the short to medium term.</p>
+ </tp:rationale>
+
+ <p>No interpretation is defined for channel classes with any other
+ target handle type, or for channel classes that do not fix a
+ target handle type, in this version of the Telepathy
+ specification.</p>
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:contact-attribute name="capabilities"
+ type="a(a{sv}as)" tp:type="Requestable_Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same structs that would be returned by
+ <tp:member-ref>GetContactCapabilities</tp:member-ref>.
+ Omitted from the result if the contact's capabilities
+ are not known; present in the result as an empty array if the
+ contact is known to have no capabilities at all.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Contact_Groups.xml b/spec/spec/Connection_Interface_Contact_Groups.xml
new file mode 100644
index 000000000..5282a8272
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contact_Groups.xml
@@ -0,0 +1,549 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contact_Groups" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactGroups">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.ContactList"/>
+ <tp:added version="0.21.0">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connections in which contacts can be placed in
+ user-defined groups.</p>
+
+ <p>The most basic functionality of this interface is to list and monitor
+ a contact's set of groups. To do this, use the
+ <tp:member-ref>GroupsChanged</tp:member-ref> signal, and the
+ <tp:token-ref>groups</tp:token-ref> contact attribute (this should
+ usually be done by connecting to the GroupsChanged signal, then
+ calling <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref> with this interface
+ included in the Interfaces argument). Simple user interfaces can
+ limit themselves to displaying that information, and ignore the rest
+ of this interface: to ensure that this works,
+ <tp:member-ref>GroupsChanged</tp:member-ref> is emitted for every
+ change, even if that change could be inferred from another signal
+ such as <tp:member-ref>GroupsRemoved</tp:member-ref>.</p>
+
+ <p>Looking at contacts' lists of groups is sufficient to present a
+ user interface resembling XMPP's data model, in which groups behave
+ like tags applied to contacts, and so an empty group cannot exist
+ or is not interesting. However, some protocols model groups as
+ objects in their own right. User interfaces may either track
+ the set of groups via the <tp:member-ref>Groups</tp:member-ref>
+ property and the <tp:member-ref>GroupsCreated</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals, or ignore
+ this extra information.</p>
+
+ <p>Similarly, in some protocols it is possible to rename a group as
+ a single atomic operation. Simpler user interfaces will
+ see the new name being created, the old name being removed, and the
+ members moving to the new name, via the signals described above.
+ More advanced user interfaces can optionally distinguish between an
+ atomic rename and a create/remove pair, and display renamed groups
+ differently, by monitoring the
+ <tp:member-ref>GroupRenamed</tp:member-ref> signal.</p>
+
+ <p>This interface also provides various methods to manipulate
+ user-defined groups, which can be expected to work if
+ <tp:member-ref>GroupStorage</tp:member-ref> is not None.</p>
+
+ <p>Depending on the protocol, some methods might be implemented by
+ more than one protocol operation; for instance, in a
+ "contact-centric" protocol like XMPP,
+ <tp:member-ref>SetContactGroups</tp:member-ref> is a single
+ protocol operation and <tp:member-ref>SetGroupMembers</tp:member-ref>
+ requires a protocol operation per contact, whereas in a more
+ "group-centric" protocol it might be the other way around. User
+ interfaces SHOULD call whichever method most closely resembles the
+ way in which the user's action was represented in the UI, and
+ let the connection manager deal with the details.</p>
+ </tp:docstring>
+
+ <property name="DisjointGroups" tp:name-for-bindings="Disjoint_Groups"
+ access="read" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>True if each contact can be in at most one group; false if each
+ contact can be in many groups.</p>
+
+ <p>This property cannot change after the connection has moved to the
+ Connected state. Until then, its value is undefined, and it may
+ change at any time, without notification.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="GroupStorage" tp:name-for-bindings="Group_Storage"
+ type="u" tp:type="Contact_Metadata_Storage_Type" access="read">
+ <tp:docstring>
+ <p>Indicates the extent to which contacts' groups can be set and
+ stored.</p>
+
+ <p>This property cannot change after the connection has moved to the
+ Connected state. Until then, its value is undefined, and it may
+ change at any time, without notification.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:contact-attribute name="groups" type="as">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The names of groups of which a contact is a member.</p>
+
+ <p>Change notification is via
+ <tp:member-ref>GroupsChanged</tp:member-ref>; clients can also
+ get extra context for group membership changes by receiving
+ <tp:member-ref>GroupRenamed</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref>.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <signal name="GroupsChanged" tp:name-for-bindings="Groups_Changed">
+ <tp:docstring>
+ Emitted when contacts' groups change.
+ </tp:docstring>
+
+ <arg name="Contact" type="au" tp:type="Contact_Handle">
+ <tp:docstring>The relevant contacts.</tp:docstring>
+ </arg>
+
+ <arg name="Added" type="as">
+ <tp:docstring>The names of groups to which the contacts were
+ added.</tp:docstring>
+ </arg>
+
+ <arg name="Removed" type="as">
+ <tp:docstring>The names of groups from which the contacts were
+ removed.</tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Groups" type="as" access="read"
+ tp:name-for-bindings="Groups">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The names of all groups that currently exist. This may be a
+ larger set than the union of all contacts' <code>groups</code>
+ contact attributes, if the connection allows groups to be
+ empty.</p>
+
+ <p>Change notification is via
+ <tp:member-ref>GroupsCreated</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref>; clients can also
+ distinguish between a create/remove pair and a renamed group by
+ receiving <tp:member-ref>GroupRenamed</tp:member-ref>.</p>
+
+ <p>This property's value is not meaningful until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> has become Success.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="GroupsCreated" tp:name-for-bindings="Groups_Created">
+ <tp:docstring>
+ Emitted when new, empty groups are created. This will often be
+ followed by <tp:member-ref>GroupsChanged</tp:member-ref> signals that
+ add some members.
+ </tp:docstring>
+
+ <arg name="Names" type="as">
+ <tp:docstring>The names of the new groups.</tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="GroupRenamed" tp:name-for-bindings="Group_Renamed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when a group is renamed, in protocols where this can
+ be distinguished from group creation, removal and membership
+ changes.</p>
+
+ <p>Immediately after this signal is emitted,
+ <tp:member-ref>GroupsCreated</tp:member-ref> MUST signal the
+ creation of a group with the new name, and
+ <tp:member-ref>GroupsRemoved</tp:member-ref> MUST signal the
+ removal of a group with the old name.</p>
+
+ <tp:rationale>
+ <p>Emitting these extra signals, in this order, means that clients
+ that are interested in the set of groups that exist (but treat a
+ rename and a create/remove pair identically) can ignore the
+ GroupRenamed signal entirely.</p>
+ </tp:rationale>
+
+ <p>If the group was not empty, immediately after those signals are
+ emitted, <tp:member-ref>GroupsChanged</tp:member-ref> MUST signal
+ that the members of that group were removed from the old name
+ and added to the new name.</p>
+
+ <p>On connection managers where groups behave like tags, renaming a
+ group MAY be signalled as a set of
+ <tp:member-ref>GroupsCreated</tp:member-ref>,
+ <tp:member-ref>GroupsRemoved</tp:member-ref> and
+ <tp:member-ref>GroupsChanged</tp:member-ref> signals, instead of
+ emitting this signal.</p>
+
+ <tp:rationale>
+ <p>On protocols like XMPP, another resource "renaming a group" is
+ indistinguishable from changing contacts' groups individually.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Old_Name" type="s">
+ <tp:docstring>The old name of the group.</tp:docstring>
+ </arg>
+
+ <arg name="New_Name" type="s">
+ <tp:docstring>The new name of the group.</tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="GroupsRemoved" tp:name-for-bindings="Groups_Removed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when one or more groups are removed. If they had members at
+ the time that they were removed, then immediately after this signal
+ is emitted, <tp:member-ref>GroupsChanged</tp:member-ref> MUST signal
+ that their members were removed.</p>
+
+ <tp:rationale>
+ <p>Emitting the signals in this order allows for two modes of
+ operation. A client interested only in a contact's set of groups
+ can ignore <tp:member-ref>GroupsRemoved</tp:member-ref> and rely
+ on the <tp:member-ref>GroupsChanged</tp:member-ref> signal that
+ will follow; a more elaborate client wishing to distinguish between
+ all of a group's members being removed, and the group itself
+ being removed, can additionally watch for
+ <tp:member-ref>GroupsRemoved</tp:member-ref> and use it to
+ disambiguate.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Names" type="as">
+ <tp:docstring>The names of the groups.</tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="SetContactGroups" tp:name-for-bindings="Set_Contact_Groups">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Add the given contact to the given groups (creating new groups
+ if necessary), and remove them from all other groups.</p>
+
+ <tp:rationale>
+ <p>This is the easiest and most correct way to implement user
+ interfaces that display a single contact with a list of groups,
+ resulting in a user expectation that when they apply the changes,
+ the contact's set of groups will become exactly what was
+ displayed.</p>
+ </tp:rationale>
+
+ <p>If the user is removed from a group of which they were the only
+ member, the group MAY be removed automatically.</p>
+
+ <tp:rationale>
+ <p>In protocols like XMPP where groups behave like tags, a group
+ with no members has no protocol representation.</p>
+ </tp:rationale>
+
+ <p>Any <tp:member-ref>GroupsCreated</tp:member-ref>,
+ <tp:member-ref>GroupsChanged</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle" direction="in">
+ <tp:docstring>The contact to alter.</tp:docstring>
+ </arg>
+
+ <arg name="Groups" type="as" direction="in">
+ <tp:docstring>The set of groups which the contact should be
+ in.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>Raised if <tp:member-ref>DisjointGroups</tp:member-ref>
+ is true and the list of groups has more than one
+ member.</tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="SetGroupMembers" tp:name-for-bindings="Set_Group_Members">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Add the given members to the given group (creating it if necessary),
+ and remove all other members.</p>
+
+ <tp:rationale>
+ <p>This is the easiest and most correct way to implement user
+ interfaces that display a single group with a list of contacts,
+ resulting in a user expectation that when they apply the changes,
+ the groups's set of members will become exactly what was
+ displayed.</p>
+ </tp:rationale>
+
+ <p>If <tp:member-ref>DisjointGroups</tp:member-ref> is true,
+ this will also remove each member from their previous group.</p>
+
+ <p>If the user is removed from a group of which they were the only
+ member, the group MAY be removed automatically.</p>
+
+ <p>Any <tp:member-ref>GroupsCreated</tp:member-ref>,
+ <tp:member-ref>GroupsChanged</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Group" type="s" direction="in">
+ <tp:docstring>The group to alter.</tp:docstring>
+ </arg>
+
+ <arg name="Members" type="au" tp:type="Contact_Handle[]" direction="in">
+ <tp:docstring>The set of members for the group. If this set is
+ empty, this method MAY remove the group.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="AddToGroup" tp:name-for-bindings="Add_To_Group">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Add the given members to the given group, creating it if
+ necessary.</p>
+
+ <p>If <tp:member-ref>DisjointGroups</tp:member-ref> is true,
+ this will also remove each member from their previous group.</p>
+
+ <tp:rationale>
+ <p>This is good for user interfaces in which you can edit groups
+ via drag-and-drop.</p>
+ </tp:rationale>
+
+ <p>Any <tp:member-ref>GroupsCreated</tp:member-ref>,
+ <tp:member-ref>GroupsChanged</tp:member-ref> and
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Group" type="s" direction="in">
+ <tp:docstring>The group to alter.</tp:docstring>
+ </arg>
+
+ <arg name="Members" type="au" tp:type="Contact_Handle[]" direction="in">
+ <tp:docstring>The set of members to include in the group.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RemoveFromGroup" tp:name-for-bindings="Remove_From_Group">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Remove the given members from the given group.</p>
+
+ <tp:rationale>
+ <p>This is good for user interfaces in which you can edit groups
+ via drag-and-drop.</p>
+ </tp:rationale>
+
+ <p>Any <tp:member-ref>GroupsChanged</tp:member-ref> or
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Group" type="s" direction="in">
+ <tp:docstring>The group to alter. If it does not exist, then it has
+ no members by definition, so this method SHOULD return
+ successfully.</tp:docstring>
+ </arg>
+
+ <arg name="Members" type="au" tp:type="Contact_Handle[]" direction="in">
+ <tp:docstring>The set of members to remove from the group. It is not
+ an error to remove members who are already not in the group.
+ If there are no members left in the group afterwards, the group MAY
+ itself be removed.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RemoveGroup" tp:name-for-bindings="Remove_Group">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Remove all members from the given group, then remove the group
+ itself. If the group already does not exist, this method SHOULD
+ return successfully.</p>
+
+ <p>Any <tp:member-ref>GroupsChanged</tp:member-ref> or
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Group" type="s" direction="in">
+ <tp:docstring>The group to remove.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RenameGroup" tp:name-for-bindings="Rename_Group">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Rename the given group.</p>
+
+ <p>On protocols where groups behave like tags, this is an API
+ short-cut for adding all of the group's members to a group with
+ the new name, then removing the old group.</p>
+
+ <tp:rationale>
+ <p>Otherwise, clients can't perform this operation atomically, even
+ if the connection could.</p>
+ </tp:rationale>
+
+ <p>Any <tp:member-ref>GroupRenamed</tp:member-ref> or
+ <tp:member-ref>GroupsRemoved</tp:member-ref> signals that result from
+ this method call MUST be emitted before the method returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >ContactListState</tp:dbus-ref> changes to Success.
+ If the ContactListState is Failure, this method SHOULD raise the
+ same error as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.ContactList"
+ >GetContactListAttributes</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Old_Name" type="s" direction="in">
+ <tp:docstring>The group to rename.</tp:docstring>
+ </arg>
+
+ <arg name="New_Name" type="s" direction="in">
+ <tp:docstring>The new name for the group.</tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Raised if <tp:member-ref>GroupStorage</tp:member-ref>
+ is Contact_Metadata_Storage_Type_None, i.e. groups cannot be edited.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.DoesNotExist">
+ <tp:docstring>Raised if there is no group with that
+ name.</tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>Raised if there is already a group with the new
+ name.</tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet"/>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Contact_Info.xml b/spec/spec/Connection_Interface_Contact_Info.xml
new file mode 100644
index 000000000..527d32522
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contact_Info.xml
@@ -0,0 +1,550 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contact_Info" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2008 Nokia Corporation </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactInfo">
+ <tp:added version="0.19.4">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:struct name="Contact_Info_Field" array-name="Contact_Info_Field_List">
+ <tp:member type="s" name="Field_Name">
+ <tp:docstring>
+ The name of the field; this is the lowercased name of a vCard field.
+ For example, a field representing a contact's address would be named
+ "adr".
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="as" name="Parameters">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of vCard type parameters applicable to this field, with their
+ values. The type parameter names, and any values that are
+ case-insensitive in vCard, MUST be in lower case. For example, a
+ contact's preferred home address would have parameters
+ 'type=home' and 'type=pref'.</p>
+
+ <tp:rationale>
+ The type parameter 'type' is likely to be the most common, but
+ there can be others, such as 'language=en'.
+ </tp:rationale>
+
+ <p>Characters which are required to be escaped in vCard type
+ parameters should not be escaped in this list. For instance,
+ a field "X-FOO;SEMICOLON=\;:bar" in a vCard would become
+ ('x-foo', ['semicolon=;'], ['bar']) in this interface.</p>
+
+ <tp:rationale>
+ This avoids Telepathy UIs having to understand the escaping and
+ unescaping rules for vCards. The type parameter name is not
+ allowed (by RFC 2425) to contain an '=' character, so no ambiguity
+ is introduced.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="as" name="Field_Value">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>For unstructured vCard fields (such as 'fn', a formatted name
+ field), a single-element array containing the field's value.</p>
+
+ <p>For structured fields (such as 'adr', an address field), an array
+ corresponding to the semicolon-separated elements of the field (with
+ empty strings for empty elements).</p>
+
+ <p>A vCard field with multiple comma-separated values, such as
+ 'nickname', should be represented by several
+ <tp:type>Contact_Info_Field</tp:type>s.</p>
+
+ <p>Characters which are required to be escaped in vCard values, such as
+ semi-colons and newlines, should not be escaped in this list (e.g. if
+ a value contains a newline, the data passed over D-Bus should
+ contain a literal newline character).</p>
+
+ <tp:rationale>
+ An earlier draft of this interface split structured vCard fields
+ into multiple Telepathy-level fields; for example, 'n' became
+ 'family-name', 'given-name', etc. But under this representation,
+ omitting empty components leads to difficulty identifying where one
+ name ends and another begins. Consider the fields ['given-name',
+ 'honorific-suffixes', 'family-name', 'honorific-prefixes']: does
+ this represent two 'n' fields, or one with incorrect component
+ ordering?
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Represents one piece of information about a contact, as modelled by
+ a single vCard field. Of the fields defined in RFC 2426, common
+ examples include:</p>
+
+ <dl>
+ <dt>fn</dt>
+ <dd>The contact's full name, formatted to their liking</dd>
+
+ <dt>n</dt>
+ <dd>The contact's full name, divided into five parts: family name,
+ given name, additional names, honorific prefixes, and honorific
+ suffixes</dd>
+
+ <dt>org</dt>
+ <dd>The contact's organisation, divided into the organization's name
+ possibly followed by one or more organizational unit names.</dd>
+
+ <dt>adr</dt>
+ <dd>A street address for the contact, divided into seven components:
+ post office box, extended address, street address, locality (e.g.,
+ city), region (e.g., state or province), the postal code, and the
+ country name.</dd>
+
+ <dt>label</dt>
+ <dd>A free-form street address for the contact, formatted as a
+ single value (with embedded newlines where necessary) suitable for
+ printing on an address label</dd>
+
+ <dt>tel</dt>
+ <dd>A telephone number for the contact.</dd>
+
+ <dt>email</dt>
+ <dd>An email address for the contact.</dd>
+ </dl>
+
+ <p>For example, the following vCard:</p>
+
+ <pre>
+ BEGIN:vCard
+ VERSION:3.0
+ FN:Wee Ninja
+ N;LANGUAGE=ja:Ninja;Wee;;;-san
+ ORG:Collabora, Ltd.;Management Division;Human Resources\; Company Policy Enforcement
+ ADR;TYPE=WORK,POSTAL,PARCEL:;;11 Kings Parade;Cambridge;Cambridgeshire
+ ;CB2 1SJ;UK
+ LABEL;TYPE=WORK,POSTAL,PARCEL:11 Kings Parade\nCambridge\nCambridgeshire\nUK\nCB2 1SJ
+ TEL;TYPE=VOICE,WORK:+44 1223 362967, +44 7700 900753
+ EMAIL;TYPE=INTERNET,PREF:wee.ninja@collabora.co.uk
+ EMAIL;TYPE=INTERNET:wee.ninja@example.com
+ URL:http://www.thinkgeek.com/geektoys/plush/8823/
+ NICKNAME:HR Ninja,Enforcement Ninja
+ END:vCard</pre>
+
+ <p>would be represented by (in Python-like syntax):</p>
+
+ <pre>
+[
+ ('fn', [], ['Wee Ninja']),
+ ('n', ['language=ja'], ['Ninja', 'Wee', '', '', '-san']),
+ ('org', [], ['Collabora, Ltd.', 'Management Division',
+ 'Human Resources; Company Policy Enforcement']),
+ ('adr', ['type=work','type=postal','type=parcel'],
+ ['','','11 Kings Parade','Cambridge', 'Cambridgeshire','CB2 1SJ','UK']),
+ ('label', ['type=work','type=postal','type=parcel'],
+ ['''11 Kings Parade
+ Cambridge
+ Cambridgeshire
+ UK
+ CB2 1SJ''']),
+ ('tel', ['type=voice','type=work'], ['+44 1223 362967']),
+ ('tel', ['type=voice','type=work'], ['+44 7700 900753']),
+ ('email', ['type=internet','type=pref'], ['wee.ninja@collabora.co.uk']),
+ ('email', ['type=internet'], ['wee.ninja@example.com']),
+ ('url', [], ['http://www.thinkgeek.com/geektoys/plush/8823/']),
+ ('nickname', [], ['HR Ninja']),
+ ('nickname', [], ['Enforcement Ninja'])
+]</pre>
+ </tp:docstring>
+ </tp:struct>
+
+ <tp:mapping name="Contact_Info_Map" array-name="">
+ <tp:docstring>A dictionary whose keys are contact handles and whose
+ values are contact information..</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
+ <tp:member type="a(sasas)" tp:type="Contact_Info_Field[]"
+ name="Contact_Info"/>
+ </tp:mapping>
+
+ <signal name="ContactInfoChanged" tp:name-for-bindings="Contact_Info_Changed">
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for the contact whose info has changed.
+ </tp:docstring>
+ </arg>
+ <arg name="ContactInfo" type="a(sasas)" tp:type="Contact_Info_Field[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of fields representing information about this contact.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a contact's information has changed or been received for
+ the first time on this connection.
+ </tp:docstring>
+ </signal>
+
+ <method name="GetContactInfo"
+ tp:name-for-bindings="Get_Contact_Info">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="ContactInfo" type="a{ua(sasas)}"
+ tp:type="Contact_Info_Map">
+ <tp:docstring>
+ A dictionary mapping contact handles to information, whose keys are
+ the subset of the requested list of handles for which information was
+ cached.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request information on several contacts at once. This SHOULD only
+ return cached information, omitting handles for which no information is
+ cached from the returned map.
+ </tp:docstring>
+ </method>
+
+ <method name="RefreshContactInfo"
+ tp:name-for-bindings="Refresh_Contact_Info">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ Integer handles for contacts.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Retrieve information for the given contact, requesting it from the
+ network if an up-to-date version is not cached locally. This method
+ SHOULD return immediately, emitting
+ <tp:member-ref>ContactInfoChanged</tp:member-ref> when the contacts'
+ updated contact information is returned.
+
+ <tp:rationale>
+ This method allows a client with cached contact information to
+ update its cache after a number of days.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestContactInfo"
+ tp:name-for-bindings="Request_Contact_Info">
+ <arg direction="in" name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ An integer handle for a contact.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Contact_Info" type="a(sasas)"
+ tp:type="Contact_Info_Field[]">
+ <tp:docstring>
+ Information about that contact.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Retrieve information for a contact, requesting it from the network if
+ it is not cached locally.
+
+ <tp:rationale>
+ This method is appropriate for an explicit user request to show
+ a contact's information; it allows a UI to wait for the contact
+ info to be returned.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The contact's information could not be retrieved.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="SetContactInfo" tp:name-for-bindings="Set_Contact_Info">
+ <tp:docstring>
+ Set new contact information for this connection, replacing existing
+ information. This method is only suppported if
+ <tp:member-ref>ContactInfoFlags</tp:member-ref> contains
+ <code>Can_Set</code>, and may only be passed fields conforming to
+ <tp:member-ref>SupportedFields</tp:member-ref>.
+ </tp:docstring>
+ <arg direction="in" name="ContactInfo" type="a(sasas)"
+ tp:type="Contact_Info_Field[]">
+ <tp:docstring>
+ The new information to be set.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ Setting your own information is not supported on this protocol.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The supplied fields do not match the restrictions specified by
+ <tp:member-ref>SupportedFields</tp:member-ref>.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:flags name="Contact_Info_Flags" value-prefix="Contact_Info_Flag"
+ type="u">
+ <tp:docstring>
+ Flags defining the behaviour of contact information on this protocol.
+ Some protocols provide no information on contacts without an explicit
+ request; others always push information to the connection manager as
+ and when it changes.
+ </tp:docstring>
+
+ <tp:flag suffix="Can_Set" value="1">
+ <tp:docstring>
+ Indicates that <tp:member-ref>SetContactInfo</tp:member-ref> is
+ supported on this connection.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Push" value="2">
+ <tp:docstring>
+ Indicates that the protocol pushes all contacts' information to the
+ connection manager without prompting. If set,
+ <tp:member-ref>ContactInfoChanged</tp:member-ref> will be emitted
+ whenever contacts' information changes.
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:simple-type name="VCard_Field" type="s">
+ <tp:docstring>
+ A string naming a field in a vCard, such as "fn" or "adr". Although
+ these are case-insensitive in RFC 2425, in Telepathy they MUST be
+ normalized to lower case. In the terminology of RFC 2425 this is
+ called a "type name", and corresponds to the "name" production given
+ in the ABNF.
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="VCard_Type_Parameter" type="s"
+ array-name="VCard_Type_Parameter_List">
+ <tp:docstring>
+ A type parameter as defined by RFC 2426, such as "type=cell" or
+ "language=en".
+ </tp:docstring>
+ </tp:simple-type>
+
+ <property name="ContactInfoFlags" type="u" access="read"
+ tp:type="Contact_Info_Flags" tp:name-for-bindings="Contact_Info_Flags">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An integer representing the bitwise-OR of flags on this
+ connection.</p>
+
+ <p>This property MAY change, without change notification, at any time
+ before the connection moves to status Connection_Status_Connected.
+ It MUST NOT change after that point.</p>
+
+ <tp:rationale>
+ <p>Some XMPP servers, like Facebook Chat, do not allow the vCard to
+ be changed (and so would not have the Can_Set flag). Whether the
+ user's server is one of these cannot necessarily be detected until
+ quite late in the connection process.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </property>
+
+ <tp:struct name="Field_Spec" array-name="Field_Specs">
+ <tp:docstring>A struct describing a vCard field, with parameters, that
+ may be passed to <tp:member-ref>SetContactInfo</tp:member-ref> on this
+ Connection.</tp:docstring>
+
+ <tp:member type="s" name="Name" tp:type="VCard_Field">
+ <tp:docstring>A vCard field name, such as 'tel'.</tp:docstring>
+ </tp:member>
+
+ <tp:member type="as" name="Parameters" tp:type="VCard_Type_Parameter[]">
+ <tp:docstring>The set of vCard type parameters which may be set on this
+ field. If this list is empty and the
+ Contact_Info_Field_Flag_Parameters_Exact flag is not set, any vCard type
+ parameters may be used.</tp:docstring>
+ </tp:member>
+
+ <tp:member type="u" name="Flags" tp:type="Contact_Info_Field_Flags">
+ <tp:docstring>Flags describing the behaviour of this
+ field.</tp:docstring>
+ </tp:member>
+
+ <tp:member type="u" name="Max">
+ <tp:docstring>Maximum number of instances of this field which may be
+ set. MAXUINT32 is used to indicate that there is no
+ limit.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="SupportedFields" type="a(sasuu)" tp:type="Field_Spec[]"
+ access="read" tp:name-for-bindings="Supported_Fields">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of field specifications describing the kinds of fields which may
+ be passed to <tp:member-ref>SetContactInfo</tp:member-ref>. The empty
+ list indicates that arbitrary vCard fields are permitted. This
+ property SHOULD be the empty list, and be ignored by clients, if
+ <tp:member-ref>ContactInfoFlags</tp:member-ref> does not contain the
+ Can_Set flag.</p>
+
+ <p>For example, a protocol in which arbitrary vCards were stored
+ as-is would set this property to the
+ empty list. A protocol whose notion of contact information is one
+ each of personal phone number, mobile phone number, location, email
+ address and date of birth, with no attributes allowed on each piece
+ of information, would set this property to (in Python-like
+ syntax):</p>
+
+ <pre>
+[
+ ('tel', ['type=home'], Parameters_Exact, 1),
+ ('tel', ['type=cell'], Parameters_Exact, 1),
+ ('adr', [], Parameters_Exact, 1),
+ ('bday', [], Parameters_Exact, 1),
+ ('email', ['type=internet'], Parameters_Exact, 1),
+]</pre>
+
+ <p>A protocol which allows users to specify up to four phone numbers,
+ which may be labelled as personal and/or mobile, would set this
+ property to
+ <code>[ ('tel', ['type=home', 'type=cell'], 0, 4), ]</code>.</p>
+
+ <tp:rationale>
+ <p>Studying existing IM protocols shows that in practice protocols
+ allow either a very restricted set of fields (such as MSN, which
+ seems to correspond roughly to the largest example above), or
+ something mapping 1:1 to a large subset of vCard (such as XMPP's
+ XEP-0054).</p>
+ </tp:rationale>
+
+ <p>This property MAY change, without change notification, at any time
+ before the connection moves to status Connection_Status_Connected.
+ It MUST NOT change after that point.</p>
+
+ <tp:rationale>
+ <p>Some XMPP servers, like Google Talk, only allow a small subset of
+ the "vcard-temp" protocol. Whether the user's server is one of
+ these cannot be detected until quite late in the connection
+ process.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Contact_Info_Field_Flags"
+ value-prefix="Contact_Info_Field_Flag" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Flags describing the behaviour of a vCard field.
+ </tp:docstring>
+ <tp:flag suffix="Parameters_Exact" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If present, exactly the parameters indicated must be set on this
+ field; in the case of an empty list of parameters, this implies that
+ parameters may not be used.</p>
+
+ <p>If absent, and the list of allowed parameters is non-empty,
+ any (possibly empty) subset of that list may be
+ used.</p>
+
+ <p>If absent, and the list of allowed parameters is empty,
+ any parameters may be used.</p>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:flag suffix="Overwritten_By_Nickname" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Indicates that this field will be overwritten when the user's alias
+ is changed with <tp:dbus-ref
+ namespace="ofdT.Connection.Interface.Aliasing">SetAliases</tp:dbus-ref>
+ or when the Account's <tp:dbus-ref
+ namespace="ofdT.Account">Nickname</tp:dbus-ref>
+ is updated. Clients that allow the editing of the Alias and the
+ ContactInfo in the same location should hide fields with this flag.</p>
+ <tp:rationale>
+ <p>If a client allowed the user to edit both the nickname and the
+ ContactInfo field at the same time, the user could set them to two
+ different values even though they map to the same property. This
+ would result in surprising behavior where the second value would
+ win over the first.</p>
+ </tp:rationale>
+ <p>In addition to hiding this field when editing ContactInfo together
+ with the user's nickname, it is recommended that clients call
+ <tp:member-ref>SetContactInfo</tp:member-ref> before setting the
+ user's nickname.</p>
+ <tp:rationale>
+ <p>This ensures that if the user changes the nickname, the correct
+ value will get set even if the stale nickname is mistakenly sent
+ along with <tp:member-ref>SetContactInfo</tp:member-ref>.</p>
+ </tp:rationale>
+ <p>If used, this flag typically appears on either the 'nickname' or
+ 'fn' field.</p>
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for requesting information about a contact on a given
+ connection. Information is represented as a list of
+ <tp:type>Contact_Info_Field</tp:type>s forming a
+ structured representation of a vCard (as defined by RFC 2426), using
+ field names and semantics defined therein.</p>
+
+ <p>On some protocols, information about your contacts is pushed to you,
+ with change notification; on others, like XMPP, the client must
+ explicitly request the avatar, and has no way to tell whether it has
+ changed without retrieving it in its entirety. This distinction is
+ exposed by <tp:member-ref>ContactInfoFlags</tp:member-ref> containing
+ the Push flag.</p>
+
+ <p>On protocols with the Push flag set, UIs can connect to
+ <tp:member-ref>ContactInfoChanged</tp:member-ref>, call
+ <tp:member-ref>GetContactInfo</tp:member-ref> once at login for the set
+ of contacts they are interested in, and then be sure they will receive
+ the latest contact info. On protocols like XMPP, clients can do the
+ same, but will receive (at most) opportunistic updates if the info is
+ retrieved for other reasons. Clients may call
+ <tp:member-ref>RequestContactInfo</tp:member-ref> or
+ <tp:member-ref>RefreshContactInfo</tp:member-ref> to force a contact's
+ info to be updated, but MUST NOT do so unless this is either in
+ response to direct user action, or to refresh their own cache after a
+ number of days.</p>
+
+ <tp:rationale>
+ <p>We don't want clients to accidentally cause a ridiculous amount of
+ network traffic.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:contact-attribute name="info"
+ type="a(sasas)" tp:type="Contact_Info_Field[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same value that would be returned by
+ <tp:member-ref>GetContactInfo</tp:member-ref> for this contact.
+ Omitted from the result if the contact's info
+ is not known.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Contact_List.xml b/spec/spec/Connection_Interface_Contact_List.xml
new file mode 100644
index 000000000..033c64d1d
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contact_List.xml
@@ -0,0 +1,1085 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contact_List" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactList">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.21.0">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connections that have any concept of a list of
+ known contacts (roster, buddy list, friends list etc.)</p>
+
+ <tp:rationale>
+ <p>On many protocols, there's a server-side roster (as in XMPP),
+ or a set of server-side lists that can be combined to form a
+ roster (as in MSN).</p>
+
+ <p>In some protocols (like link-local XMPP), while there might not be
+ any server or roster, it's possible to list "nearby" contacts.</p>
+
+ <p>In Telepathy 0.20 and older, we represented contact lists as a
+ collection of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type"
+ >ContactList</tp:dbus-ref> channels. This is remarkably difficult to
+ work with in practice - every client that cares about contact lists
+ has to take the union of some hard-to-define set of these
+ channels - and conflicts with the idea that channels that cannot
+ be dispatched to a handler should be closed.</p>
+ </tp:rationale>
+
+ <p>The list of contacts is not exposed as a D-Bus property; it can be
+ fetched using <tp:member-ref>GetContactListAttributes</tp:member-ref>.
+ </p>
+
+ <tp:rationale>
+ <p>In some protocols, such as XMPP, the contact list may not be
+ available immediately. The
+ <tp:member-ref>GetContactListAttributes</tp:member-ref> method
+ will fail until the contact list is available.
+ Using a method also allows extra attributes to be retrieved at
+ the same time.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:enum name="Contact_List_State" type="u">
+ <tp:docstring>
+ The progress made in retrieving the contact list.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>The connection has not started to retrieve the contact
+ list. If <tp:member-ref>GetContactListAttributes</tp:member-ref> is
+ called in this state, it will raise NotYet.</tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Waiting" value="1">
+ <tp:docstring>The connection has started to retrieve the contact
+ list, but has not yet succeeded or failed.
+ If <tp:member-ref>GetContactListAttributes</tp:member-ref> is called
+ in this state, it will raise NotYet.</tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Failure" value="2">
+ <tp:docstring>
+ <p>The connection has tried and failed to retrieve the contact
+ list. If <tp:member-ref>GetContactListAttributes</tp:member-ref>
+ is called in this state, it will immediately raise an error
+ indicating the reason for failure.</p>
+
+ <p>The connection manager SHOULD try again to obtain the contact
+ list, if appropriate for the protocol. If it succeeds later,
+ the <tp:member-ref>ContactListState</tp:member-ref> MUST advance
+ to Success.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Success" value="3">
+ <tp:docstring>The connection has successfully retrieved the contact
+ list. If <tp:member-ref>GetContactListAttributes</tp:member-ref>
+ is called in this state, it will return successfully.</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="ContactListState" tp:name-for-bindings="Contact_List_State"
+ type="u" tp:type="Contact_List_State" access="read">
+ <tp:docstring>
+ The progress made in retrieving the contact list.
+ Change notification is via
+ <tp:member-ref>ContactListStateChanged</tp:member-ref>.
+ </tp:docstring>
+ </property>
+
+ <signal name="ContactListStateChanged"
+ tp:name-for-bindings="Contact_List_State_Changed">
+ <tp:docstring>
+ Emitted when <tp:member-ref>ContactListState</tp:member-ref>
+ changes.
+ </tp:docstring>
+
+ <arg name="Contact_List_State" type="u" tp:type="Contact_List_State">
+ <tp:docstring>
+ The new value of <tp:member-ref>ContactListState</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="GetContactListAttributes"
+ tp:name-for-bindings="Get_Contact_List_Attributes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Return some contact attributes for a list of contacts
+ associated with the user. This list MUST include at least:</p>
+
+ <ul>
+ <li>all contacts whose <tp:token-ref>subscribe</tp:token-ref>
+ attribute is not No</li>
+ <li>all contacts whose <tp:token-ref>publish</tp:token-ref>
+ attribute is not No</li>
+ </ul>
+
+ <p>but MAY contain other contacts.</p>
+
+ <tp:rationale>
+ <p>For instance, on XMPP, all contacts on the roster would appear
+ here even if they have subscription="none", unless there's
+ reason to believe the user does not want to see them (such as
+ having been blocked).</p>
+ </tp:rationale>
+
+ <p>This list does not need to contain every visible contact: for
+ instance, contacts seen in XMPP or IRC chatrooms SHOULD NOT appear
+ here. Blocked contacts SHOULD NOT appear here, unless they still
+ have a non-<tt>No</tt> <tp:token-ref>subscribe</tp:token-ref> or
+ <tp:token-ref>publish</tp:token-ref> attribute
+ for some reason.</p>
+
+ <tp:rationale>
+ <p>It's reasonable to assume that blocked contacts should not be
+ visible to the user unless they specifically go looking for them,
+ at least in protocols like XMPP where blocking a contact
+ suppresses presence.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Interfaces" type="as"
+ tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of strings indicating which D-Bus interfaces the calling
+ process is interested in. Equivalent to the corresponding argument
+ to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Contacts"
+ >GetContactAttributes</tp:dbus-ref>,
+ except that if this list does not contain the ContactList
+ interface itself, it is treated as though that interface was also
+ requested.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Hold" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, all handles that appear as keys in the result have been
+ held on behalf of the calling process, as if by a call to
+ <tp:dbus-ref namespace="ofdT">Connection.HoldHandles</tp:dbus-ref>.
+ (If <tp:dbus-ref namespace="ofdT.Connection"
+ >HasImmortalHandles</tp:dbus-ref> is true, which SHOULD be the
+ case in all new connection managers, this has no effect.)</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{ua{sv}}" name="Attributes"
+ tp:type="Contact_Attributes_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary mapping the contact handles to contact attributes,
+ equivalent to the result of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Contacts"
+ >GetContactAttributes</tp:dbus-ref>.</p>
+
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The <tp:member-ref>ContactListState</tp:member-ref> is
+ None or Waiting. In particular, this error is raised if the
+ <tp:dbus-ref namespace="ofdT.Connection">Status</tp:dbus-ref>
+ is not yet Connection_Status_Connected.</p>
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Subscription_State" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An enumeration indicating whether presence subscription is denied,
+ denied but pending permission, or allowed. The exact semantics
+ vary according to where this type is used: see the
+ <tp:token-ref>subscribe</tp:token-ref> and
+ <tp:token-ref>publish</tp:token-ref> contact attributes for
+ details.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>The presence subscription state is
+ unknown.</tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="No" value="1">
+ <tp:docstring>Presence information cannot be seen, and either the
+ subscription state Removed_Remotely does not apply, or it is
+ not known whether that state applies.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Removed_Remotely" value="2">
+ <tp:docstring>Presence information cannot be seen because the
+ remote contact took action: either the local user's request to
+ see the remote contact's presence was denied, or the remote
+ contact requested to see the local user's presence but then
+ cancelled their request.</tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Ask" value="3">
+ <tp:docstring>Presence information cannot be seen. Permission
+ to see presence information has been requested, and the request
+ has not yet been declined or accepted.</tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Yes" value="4">
+ <tp:docstring>Presence information can be seen.</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:contact-attribute name="subscribe"
+ type="u" tp:type="Subscription_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If this attribute on a contact is Yes, this connection can
+ expect to receive their presence, along with any other information
+ that has the same access control.</p>
+
+ <tp:rationale>
+ <p>This is subscription="from" or subscription="both" in XMPP,
+ the "forward list" on MSN, or the contact being "added to
+ the local user's buddy list" in ICQ, for example.</p>
+ </tp:rationale>
+
+ <p>If this attribute is not Yes, the local user cannot generally
+ expect to receive presence from this contact. Their presence status
+ as returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.SimplePresence">GetPresences</tp:dbus-ref>
+ is likely to be (Unknown, "unknown", ""), unless the local user
+ can temporarily see their presence for some other reason (for
+ instance, on XMPP, contacts seen in chatrooms will temporarily
+ have available presence).</p>
+
+ <p>If this attribute is Ask, this indicates that the local user has
+ asked to receive the contact's presence at some time. It is
+ implementation-dependent whether contacts' subscribe attributes
+ can remain set to Ask, or are reset to No, when the connection
+ disconnects.</p>
+
+ <tp:rationale>
+ <p>Some protocols store the fact that we wishes to see a contact's
+ presence; on these protocols, this attribute can remain Ask
+ indefinitely. On other protocols, only contacts who have been
+ asked during the current session will ever have Ask status.</p>
+ </tp:rationale>
+
+ <p>If this attribute is Removed_Remotely, this indicates that the
+ local user has asked to receive the contact's presence at some time,
+ but the remote contact has rejected that request, and a local
+ user interface has not yet acknowledged this. It is
+ implementation-dependent whether contacts' subscribe attributes can
+ remain set to Removed_Remotely, or are reset to No, when the
+ connection disconnects.</p>
+
+ <p>After notifying the user, user interfaces MAY acknowledge a change
+ to <tt>subscribe</tt>=Removed_Remotely by calling either
+ <tp:member-ref>Unsubscribe</tp:member-ref> or
+ <tp:member-ref>RemoveContacts</tp:member-ref>, which will set
+ <tt>subscribe</tt> to No (and perhaps remove the contact). This
+ allows user interfaces to detect that the user has been notified
+ about the rejected request.</p>
+
+ <p>This attribute's value will be Unknown or omitted until the
+ <tp:member-ref>ContactListState</tp:member-ref> has changed to
+ Success.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:contact-attribute name="publish"
+ type="u" tp:type="Subscription_State">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If this attribute on a contact is Yes, the local user's presence
+ is published to that contact, along with any other information that
+ shares an access-control mechanism with presence (depending on
+ protocol, server configuration and/or user configuration, this may
+ include avatars, "rich presence" such as location, etc.).</p>
+
+ <tp:rationale>
+ <p>This is subscription="to" or subscription="both" in XMPP,
+ the "reverse list" on MSN, or the state of "being added to
+ the contact's buddy list" in ICQ, for example.</p>
+ </tp:rationale>
+
+ <p>If this attribute is not Yes, the
+ local user's presence is not published to that contact; however,
+ if it is Ask, the contact has requested that the local user's
+ presence is made available to them.</p>
+
+ <p>It is implementation-dependent whether contacts' <tt>publish</tt>
+ attributes can remain set to Ask, or are reset to No, when the
+ connection disconnects.</p>
+
+ <tp:rationale>
+ <p>Some protocols store the fact that a contact wishes to see our
+ presence; on these protocols, this attribute can remain Ask
+ indefinitely. On other protocols, only contacts who have asked
+ during the current session will ever have Ask status.</p>
+ </tp:rationale>
+
+ <p>If this attribute is Removed_Remotely, this indicates that the
+ remote contact has asked to receive the user's presence at some time,
+ but has then cancelled that request before a response was given by
+ the local user. User interfaces MAY reset <tt>publish</tt> from
+ Removed_Remotely to No, by calling either
+ <tp:member-ref>Unpublish</tp:member-ref> or
+ <tp:member-ref>RemoveContacts</tp:member-ref>.</p>
+
+ <p>If multiple factors affect whether a contact can receive the local
+ user's presence, this attribute SHOULD reflect the overall
+ result. For instance, an XMPP contact with subscription="to" or
+ subscription="both", but who has been blocked via
+ <a href="http://xmpp.org/extensions/xep-0016.html">XEP-0016 Privacy
+ Lists</a>, SHOULD have publish=No.</p>
+
+ <p>This attribute's value will be Unknown or omitted until the
+ <tp:member-ref>ContactListState</tp:member-ref> has changed to
+ Success.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:contact-attribute name="publish-request" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If the <tp:token-ref>publish</tp:token-ref> attribute is Ask, an
+ optional message that was sent by the contact asking to receive the
+ local user's presence; omitted if none was given.</p>
+
+ <tp:rationale>
+ <p>If the contact asking to receive our presence is also using
+ Telepathy, this is the message they supplied as the Message
+ argument to <tp:member-ref>RequestSubscription</tp:member-ref>.</p>
+ </tp:rationale>
+
+ <p>Otherwise, this SHOULD be omitted.</p>
+
+ <p>This attribute will also be omitted until the
+ <tp:member-ref>ContactListState</tp:member-ref> has changed to
+ Success.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <property name="ContactListPersists"
+ tp:name-for-bindings="Contact_List_Persists" type="b" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, presence subscriptions (in both directions) on this
+ connection are stored by the server or other infrastructure.</p>
+
+ <tp:rationale>
+ <p>XMPP, MSN, ICQ, etc. all behave like this.</p>
+ </tp:rationale>
+
+ <p>If false, presence subscriptions on this connection are not
+ stored.</p>
+
+ <tp:rationale>
+ <p>In SIMPLE (SIP), <em>clients</em> are expected to keep a record
+ of subscriptions, as described below. In link-local XMPP,
+ subscriptions are implicit (everyone on the local network receives
+ presence from everyone else) so nothing is ever stored.</p>
+ </tp:rationale>
+
+ <p>If <tp:member-ref>CanChangeContactList</tp:member-ref>
+ is true, Telepathy clients (e.g. user interfaces or address books)
+ MAY keep a record of permission to publish and requests to subscribe
+ locally, and attempt to restore it for each Connection. If
+ ContactListPersists is false, clients MAY do this for all contacts;
+ if ContactListPersists is true, clients SHOULD NOT change the state
+ of contacts that were not changed locally.</p>
+
+ <tp:rationale>
+ <p>In SIMPLE (SIP), ContactListPersists is false, but
+ CanChangeContactList is true. Presence will not be received
+ unless clients renew any subscriptions they have for each
+ connection, in the way described. There is no server-side storage,
+ so clients have no alternative but to maintain independent contact
+ lists.</p>
+
+ <p>In protocols like XMPP and MSN, it may be useful for clients to
+ queue up subscription requests or removals made while offline and
+ process them next time the connection is online. However, clients
+ should only replay the changes, rather than resetting the contact
+ list to match a stored copy, to avoid overwriting changes that
+ were made on the server.</p>
+ </tp:rationale>
+
+ <p>Clients that replay requests like this SHOULD do so by calling
+ AuthorizePublication to pre-approve publication of presence to the
+ appropriate contacts, followed by RequestSubscription to request the
+ appropriate contacts' presences.</p>
+
+ <p>This property cannot change after the connection has moved to the
+ Connected state. Until then, its value is undefined, and it may
+ change at any time, without notification.</p>
+ </tp:docstring>
+ </property>
+
+ <tp:enum name="Contact_Metadata_Storage_Type" type="u">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Values of this enumeration indicate the extent to which metadata
+ such as aliases and group memberships can be stored for the contacts
+ on a particular connection.</p>
+
+ <p>On some protocols, certain metadata (for instance, contact aliases)
+ can only be stored for contacts on the contact list, or contacts
+ with a particular contact list state.</p>
+
+ <p>To make it easier to deal with such protocols, if clients set
+ metadata on a contact who is not in the required state, the
+ Connection MUST cache the metadata for the duration of the session.
+ If clients request the attributes of that contact after the
+ appropriate "set" method has returned successfully, the Connection
+ MUST return the new (cached) value.</p>
+
+ <p>If the contact is later placed in the required state to store
+ metadata (for instance, if subscription to the contact's presence
+ is requested, on a protocol like MSN where the alias has storage type
+ Subscribed_Or_Pending), the connection MUST store the cached
+ metadata at that time.</p>
+
+ <tp:rationale>
+ <p>If the Connection didn't cache changes in this way, a client
+ intending to change the alias on MSN would have to wait until
+ the server acknowledged the subscription request; in the meantime,
+ other clients would still display the old alias.</p>
+ </tp:rationale>
+
+ <p>The only exception to that general rule is that if the Connection
+ cannot store particular metadata at all (i.e. the
+ storage type is None), it MUST reject attempts to set it.</p>
+
+ <tp:rationale>
+ <p>If the implementation knows that metadata can't be stored at
+ all, it's useful to report that, which can be done
+ synchronously. In general, user interfaces should detect
+ storage type None and not display editing controls at all.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This connection cannot store this type of metadata at all, and
+ attempting to do so will fail with NotImplemented.</p>
+
+ <tp:rationale>
+ <p>Link-local XMPP can't store aliases or group memberships at
+ all, and subscription and presence states are implicit (all
+ contacts on the local network have subscribe = publish = Yes
+ and no other contacts exist).</p>
+
+ <p>As of April 2010, the XMPP server for Facebook Chat provides a
+ read-only view of the user's Facebook contacts, so it could also
+ usefully have this storage type.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Subscribed_Or_Pending" value="1">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This type of metadata can only be stored permanently for contacts
+ whose subscribe attribute is Ask or Yes.</p>
+
+ <tp:rationale>
+ <p>Contact aliases and groups on MSN have this behaviour.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Subscribed" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This type of metadata can only be stored permanently for contacts
+ whose subscribe attribute is Yes.</p>
+
+ <tp:rationale>
+ <p>No service with this behaviour is currently known, but it's a
+ stricter form of Subscribed_Or_Pending.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue suffix="Anyone" value="3">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The user can set this metadata for any valid contact identifier,
+ whether or not they have any presence subscription relationship
+ to it, and it will be stored on their contact list.</p>
+
+ <tp:rationale>
+ <p>Contact aliases and groups on XMPP have this behaviour; it
+ is possible to put a contact in a group, or assign an alias
+ to them, without requesting that presence be shared.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Contact_Subscriptions" array-name="">
+ <tp:docstring>
+ A single contact's subscribe, publish and publish-request attributes.
+ </tp:docstring>
+
+ <tp:member name="Subscribe" type="u" tp:type="Subscription_State">
+ <tp:docstring>
+ The new value of the contact's "subscribe" attribute.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Publish" type="u" tp:type="Subscription_State">
+ <tp:docstring>
+ The new value of the contact's "publish" attribute.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Publish_Request" type="s">
+ <tp:docstring>
+ The new value of the contact's "publish-request" attribute,
+ or the empty string if that attribute would be omitted.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Contact_Subscription_Map" array-name="">
+ <tp:docstring>
+ A map from contacts to their subscribe, publish and publish-request
+ attributes.
+ </tp:docstring>
+
+ <tp:member name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact's handle.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="States" type="(uus)" tp:type="Contact_Subscriptions">
+ <tp:docstring>
+ The contact's subscribe, publish and publish-request attributes.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <signal name="ContactsChangedWithID"
+ tp:name-for-bindings="Contacts_Changed_With_ID">
+ <tp:added version="0.21.8"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the contact list becomes available, when contacts'
+ basic stored properties change, when new contacts are added to the
+ list that would be returned by
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>,
+ or when contacts are removed from that list.</p>
+
+ <tp:rationale>
+ <p>This provides change notification for that list, and for
+ contacts' <tp:token-ref>subscribe</tp:token-ref>,
+ <tp:token-ref>publish</tp:token-ref> and
+ <tp:token-ref>publish-request</tp:token-ref> attributes.</p>
+ </tp:rationale>
+
+ <p>Connection managers SHOULD also emit this signal when a contact
+ requests that the user's presence is published to them, even if
+ that contact's <tp:token>publish</tp:token> attribute is already
+ Ask and the <tp:token>publish-request</tp:token> has not changed.</p>
+
+ <tp:rationale>
+ <p>If the same contact sends 10 identical requests, 10 identical
+ signals should be emitted.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg type="a{u(uus)}" name="Changes" tp:type="Contact_Subscription_Map">
+ <tp:docstring>
+ The new <tp:token-ref>subscribe</tp:token-ref>,
+ <tp:token-ref>publish</tp:token-ref> and
+ <tp:token-ref>publish-request</tp:token-ref> attributes of all the
+ contacts that have been added, and all the contacts for which those
+ attributes have changed.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Identifiers" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The identifiers of the contacts in the <var>Changes</var> map.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Removals" type="a{us}" tp:type="Handle_Identifier_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The contacts that have been removed from the list that would be
+ returned by
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.
+ This also implies that they have subscribe = No and publish = No;
+ contacts MUST NOT be listed both here and in <var>Changes</var>.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <signal name="ContactsChanged"
+ tp:name-for-bindings="Contacts_Changed">
+ <tp:deprecated version="0.21.8">Connection managers MUST still
+ emit this signal, but clients SHOULD listen for the
+ <tp:member-ref>ContactsChangedWithID</tp:member-ref> signal in
+ addition, and ignore this signal after ContactsChangedWithID has been
+ emitted at least once.
+ </tp:deprecated>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted immediately after
+ <tp:member-ref>ContactsChangedWithID</tp:member-ref>, under the same
+ circumstances.</p>
+
+ <p>If clients receive this signal without first receiving a
+ corresponding <tp:member-ref>ContactsChangedWithID</tp:member-ref>,
+ they MUST assume that only this signal will be emitted.</p>
+ </tp:docstring>
+
+ <arg type="a{u(uus)}" name="Changes" tp:type="Contact_Subscription_Map">
+ <tp:docstring>
+ The same as the corresponding argument to
+ <tp:member-ref>ContactsChangedWithID</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Removals" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The same as the corresponding argument to
+ <tp:member-ref>ContactsChangedWithID</tp:member-ref>, except that it
+ only includes handles and not identifiers.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="CanChangeContactList" type="b" access="read"
+ tp:name-for-bindings="Can_Change_Contact_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, presence subscription and publication can be changed
+ using the
+ <tp:member-ref>RequestSubscription</tp:member-ref>,
+ <tp:member-ref>AuthorizePublication</tp:member-ref> and
+ <tp:member-ref>RemoveContacts</tp:member-ref> methods.</p>
+
+ <p>If false, all of those methods will always fail; they SHOULD raise
+ the error org.freedesktop.Telepathy.Error.NotImplemented.</p>
+
+ <tp:rationale>
+ <p>In XEP-0174 "Serverless Messaging" (link-local XMPP), presence is
+ implicitly published to everyone in the local subnet, so the user
+ cannot control their presence publication.</p>
+ </tp:rationale>
+
+ <p>This property cannot change after the connection has moved to the
+ Connected state. Until then, its value is undefined, and it may
+ change at any time, without notification.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="RequestSubscription" tp:name-for-bindings="Request_Subscription">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the given contacts allow the local user to
+ subscribe to their presence, i.e. that their subscribe attribute
+ becomes Yes.</p>
+
+ <p>Connection managers SHOULD NOT attempt to enforce a
+ mutual-subscription policy (i.e. when this method is called, they
+ should not automatically allow the contacts to see the local user's
+ presence). User interfaces that require mutual subscription
+ MAY call <tp:member-ref>AuthorizePublication</tp:member-ref>
+ at the same time as this method.</p>
+
+ <tp:rationale>
+ <p>Whether to enforce mutual subscription is a matter of policy,
+ so it is left to the user interface and/or the server.</p>
+ </tp:rationale>
+
+ <p>Before calling this method on a connection where <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Aliasing"
+ >GetAliasFlags</tp:dbus-ref> returns the <code>User_Set</code> flag,
+ user interfaces SHOULD obtain, from the user, an alias to
+ identify the contact in future, and store it using <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Aliasing"
+ >SetAliases</tp:dbus-ref>.</p>
+
+ <p>The user MAY be
+ prompted using the contact's current self-assigned nickname, or
+ something derived from the contact's (presumably self-assigned)
+ identifier, as a default, but these names chosen by the contact
+ SHOULD NOT be used without user approval.</p>
+
+ <tp:rationale>
+ <p>This is a generalization of
+ <a href="http://xmpp.org/extensions/xep-0165.html"
+ >XEP-0165 "Best Practices to Discourage JID Mimicking"</a>)
+ to protocols other than XMPP. A reasonable user interface for
+ this, as used in many XMPP clients, is to have a text entry
+ for the alias adjacent to the text entry for the identifier
+ to add.</p>
+ </tp:rationale>
+
+ <p>For contacts with subscribe=Yes, this method has no effect.
+ It MUST return successfully if all contacts are in this state.</p>
+
+ <p>For contacts with subscribe=Ask, this method SHOULD send a new
+ request, with the given message, if allowed by the underlying
+ protocol.</p>
+
+ <p>For contacts with subscribe=No or subscribe=Rejected, this method
+ SHOULD request that the contact allows the local user to subscribe
+ to their presence; in general, this will change their publish
+ attribute to Ask (although it could change directly to Yes in some
+ situations).</p>
+
+ <p>Any state changes that immediately result from this request MUST
+ be signalled via <tp:member-ref>ContactsChanged</tp:member-ref>
+ before this method returns.</p>
+
+ <tp:rationale>
+ <p>This makes it easy for user interfaces to see what practical
+ effect this method had.</p>
+ </tp:rationale>
+
+ <p>If the remote contact accepts the request, their subscribe
+ attribute will later change from Ask to Yes.</p>
+
+ <p>If the remote contact explicitly rejects the request (in protocols
+ that allow this), their subscribe attribute will later change from
+ Ask to Rejected.</p>
+
+ <p>If the subscription request is cancelled by the local user, the
+ contact's subscribe attribute will change from Ask to No.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:member-ref>ContactListState</tp:member-ref> changes to Success.
+ If the <tp:member-ref>ContactListState</tp:member-ref> changes to
+ Failure, this method SHOULD raise the same error as
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" direction="in"
+ type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more contacts to whom requests are to be sent.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Message" type="s" direction="in">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An optional plain-text message from the user, to send to those
+ contacts with the subscription request. The
+ <tp:member-ref>RequestUsesMessage</tp:member-ref> property
+ indicates whether this message will be used or ignored.</p>
+
+ <p>Clients SHOULD NOT send a non-empty message without first giving
+ the user an opportunity to edit it.</p>
+
+ <tp:rationale>
+ <p>These messages are typically presented to the remote contact
+ as if the user had typed them, so as a minimum, the user should be
+ allowed to see what the UI will be saying on their behalf.</p>
+ </tp:rationale>
+
+ <p>Connections where this message is not useful MUST still allow it to
+ be non-empty.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring>
+ The <tp:member-ref>ContactListState</tp:member-ref> is None
+ or Waiting.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It was not possible to perform the requested action, because
+ <tp:member-ref>CanChangeContactList</tp:member-ref> is false.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <property name="RequestUsesMessage" type="b" access="read"
+ tp:name-for-bindings="Request_Uses_Message">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, the Message parameter to
+ <tp:member-ref>RequestSubscription</tp:member-ref> is likely to be
+ significant, and user interfaces SHOULD prompt the user for a
+ message to send with the request; a message such as "I would like
+ to add you to my contact list", translated into the local user's
+ language, might make a suitable default.</p>
+
+ <tp:rationale>
+ <p>This matches user expectations in XMPP and ICQ, for instance.</p>
+ </tp:rationale>
+
+ <p>If false, the parameter is ignored; user interfaces SHOULD avoid
+ prompting the user, and SHOULD pass an empty string to
+ RequestSubscription.</p>
+
+ <tp:rationale>
+ <p><em>FIXME: is there any such protocol?</em></p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <method name="AuthorizePublication"
+ tp:name-for-bindings="Authorize_Publication">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>For each of the given contacts, request that the local user's
+ presence is sent to that contact, i.e. that their publish attribute
+ becomes Yes.</p>
+
+ <p>Connection managers SHOULD NOT attempt to enforce a
+ mutual-subscription policy (i.e. when this method is called, they
+ should not automatically request that the contacts allow the user to
+ subscribe to their presence). User interfaces that require mutual
+ subscription MAY call
+ <tp:member-ref>RequestSubscription</tp:member-ref> at the same time
+ as this method.</p>
+
+ <tp:rationale>
+ <p>Whether to enforce mutual subscription is a matter of policy,
+ so it is left to the user interface and/or the server.</p>
+ </tp:rationale>
+
+ <p>For contacts with publish=Yes, this method has no effect; it
+ MUST return successfully if all contacts given have this state.</p>
+
+ <p>For contacts with publish=Ask, this method accepts the
+ contact's request to see the local user's presence, changing
+ their publish attribute from Ask to Yes.</p>
+
+ <p>For contacts with publish=No, if the protocol allows it, this
+ method allows the contacts to see the local user's presence even
+ though they have not requested it, changing their publish attribute
+ from No to Yes. Otherwise, it merely records the fact that
+ presence publication to those contacts is allowed; if any of
+ those contacts ask to receive the local user's presence
+ later in the lifetime of the connection, the connection SHOULD
+ immediately allow them to do so, changing their publish
+ attribute directly from No to Yes.</p>
+
+ <tp:rationale>
+ <p>This makes it easy to implement the common UI policy that if
+ the user attempts to subscribe to a contact's presence, requests
+ for reciprocal subscription are automatically approved.</p>
+ </tp:rationale>
+
+ <p>Any state changes that immediately result from this request MUST
+ be signalled via <tp:member-ref>ContactsChanged</tp:member-ref>
+ before this method returns.</p>
+
+ <tp:rationale>
+ <p>This makes it easy for user interfaces to see what practical
+ effect this method had.</p>
+ </tp:rationale>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:member-ref>ContactListState</tp:member-ref> changes to Success.
+ If the <tp:member-ref>ContactListState</tp:member-ref> changes to
+ Failure, this method SHOULD raise the same error as
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" direction="in"
+ type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more contacts to authorize.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It was not possible to perform the requested action, because
+ <tp:member-ref>CanChangeContactList</tp:member-ref> is false.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring>
+ The <tp:member-ref>ContactListState</tp:member-ref> is None
+ or Waiting.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RemoveContacts" tp:name-for-bindings="Remove_Contacts">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Remove the given contacts from the contact list entirely. It is
+ protocol-dependent whether this works, and under which
+ circumstances.</p>
+
+ <p>If possible, this method SHOULD set the contacts' subscribe and
+ publish attributes to No, remove any stored aliases for those
+ contacts, and remove the contacts from the result of
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+
+ <p>This method SHOULD succeed even if it was not possible to carry out
+ the request entirely or for all contacts (for instance, if there is an
+ outstanding request to subscribe to the contact's presence, and it's
+ not possible to cancel such requests). However, all signals that
+ immediately result from this method call MUST be emitted before it
+ returns, so that clients can interpret the result.</p>
+
+ <tp:rationale>
+ <p>User interfaces removing a contact from the contact list are
+ unlikely to want spurious failure notifications resulting from
+ limitations of a particular protocol. However, emitting the
+ signals first means that if a client does want to check exactly
+ what happened, it can wait for the method to return (while
+ applying change-notification signals to its local cache of the
+ contact list's state), then consult its local cache of the
+ contact list's state to see whether the contact is still there.</p>
+ </tp:rationale>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:member-ref>ContactListState</tp:member-ref> changes to Success.
+ If the <tp:member-ref>ContactListState</tp:member-ref> changes to
+ Failure, this method SHOULD raise the same error as
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" direction="in"
+ type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more contacts to remove.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It was not possible to perform the requested action because
+ <tp:member-ref>CanChangeContactList</tp:member-ref> is false.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring>
+ The <tp:member-ref>ContactListState</tp:member-ref> is None
+ or Waiting.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Unsubscribe" tp:name-for-bindings="Unsubscribe">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Attempt to set the given contacts' subscribe attribute to No,
+ i.e. stop receiving their presence.</p>
+
+ <p>For contacts with subscribe=Ask, this attempts to cancel
+ an earlier request to subscribe to the contact's presence; for
+ contacts with subscribe=Yes, this attempts to
+ unsubscribe from the contact's presence.</p>
+
+ <p>As with <tp:member-ref>RemoveContacts</tp:member-ref>, this method
+ SHOULD succeed even if it was not possible to carry out the request
+ entirely or for all contacts; however, all signals that
+ immediately result from this method call MUST be emitted before it
+ returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:member-ref>ContactListState</tp:member-ref> changes to Success.
+ If the <tp:member-ref>ContactListState</tp:member-ref> changes to
+ Failure, this method SHOULD raise the same error as
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" direction="in"
+ type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more contacts to remove.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It was not possible to perform the requested action because
+ <tp:member-ref>CanChangeContactList</tp:member-ref> is false.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="Unpublish" tp:name-for-bindings="Unpublish">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Attempt to set the given contacts' publish attribute to No,
+ i.e. stop sending presence to them.</p>
+
+ <p>For contacts with publish=Ask, this method explicitly rejects the
+ contact's request to subscribe to the user's presence; for
+ contacts with publish=Yes, this method attempts to prevent the
+ user's presence from being received by the contact.</p>
+
+ <p>As with <tp:member-ref>RemoveContacts</tp:member-ref>, this method
+ SHOULD succeed even if it was not possible to carry out the request
+ entirely or for all contacts; however, all signals that
+ immediately result from this method call MUST be emitted before it
+ returns.</p>
+
+ <p>This method SHOULD NOT be called until the
+ <tp:member-ref>ContactListState</tp:member-ref> changes to Success.
+ If the <tp:member-ref>ContactListState</tp:member-ref> changes to
+ Failure, this method SHOULD raise the same error as
+ <tp:member-ref>GetContactListAttributes</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <arg name="Contacts" direction="in"
+ type="au" tp:type="Contact_Handle[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>One or more contacts to remove.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ It was not possible to perform the requested action because
+ <tp:member-ref>CanChangeContactList</tp:member-ref> is false.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotYet">
+ <tp:docstring>
+ The <tp:member-ref>ContactListState</tp:member-ref> is None
+ or Waiting.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Contacts.xml b/spec/spec/Connection_Interface_Contacts.xml
new file mode 100644
index 000000000..1020190d4
--- /dev/null
+++ b/spec/spec/Connection_Interface_Contacts.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Contacts" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005-2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Contacts">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.17.9"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface allows many attributes of many contacts to be
+ obtained in a single D-Bus round trip.</p>
+
+ <p>Each contact attribute has an string identifier
+ (<tp:type>Contact_Attribute</tp:type>), which is namespaced
+ by the D-Bus interface which defines it.</p>
+ </tp:docstring>
+
+ <tp:simple-type name="Contact_Attribute" type="s">
+ <tp:docstring>
+ A <tp:type>DBus_Interface</tp:type>, followed by a slash '/' character
+ and an identifier for an attribute defined by that interface. The
+ attribute identifier SHOULD be in lower case.
+
+ <tp:rationale>
+ These aren't D-Bus core Properties, and we want them to look visibly
+ different.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:mapping name="Single_Contact_Attributes_Map">
+ <tp:docstring>
+ Some of the attributes of a single contact.
+ </tp:docstring>
+
+ <tp:member type="s" tp:type="Contact_Attribute" name="Attribute">
+ <tp:docstring>
+ The name of the attribute
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="v" name="Value">
+ <tp:docstring>
+ The value of the attribute
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:mapping name="Contact_Attributes_Map">
+ <tp:docstring>Mapping returned by
+ <tp:member-ref>GetContactAttributes</tp:member-ref>, representing a
+ collection of Contacts and their requested attributes.</tp:docstring>
+
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact">
+ <tp:docstring>
+ A contact
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="a{sv}" tp:type="Single_Contact_Attributes_Map"
+ name="Attributes">
+ <tp:docstring>
+ Attributes of that contact
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="ContactAttributeInterfaces" access="read" type="as"
+ tp:type="DBus_Interface[]"
+ tp:name-for-bindings="Contact_Attribute_Interfaces">
+ <tp:docstring>
+ A list of D-Bus interfaces for which
+ <tp:member-ref>GetContactAttributes</tp:member-ref> is expected to work.
+ This cannot change during the lifetime of the Connection.
+ </tp:docstring>
+ </property>
+
+ <method name="GetContactAttributes"
+ tp:name-for-bindings="Get_Contact_Attributes">
+ <tp:docstring>
+ Return any number of contact attributes for the given handles.
+ </tp:docstring>
+
+ <arg direction="in" name="Handles" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of handles representing contacts.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Interfaces" type="as"
+ tp:type="DBus_Interface[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of strings indicating which D-Bus interfaces the calling
+ process is interested in. All supported attributes from these
+ interfaces, whose values can be obtained without additional network
+ activity, will be in the reply.</p>
+
+ <p>Connection managers SHOULD ignore interfaces requested which they
+ do not support (i.e. those not mentioned in the
+ <tp:member-ref>ContactAttributeInterfaces</tp:member-ref>
+ property.)</p>
+
+ <tp:rationale>
+ <p>This simplifies client-side code. Clients which care may
+ distinguish between unsupported interfaces (e.g. this Connection
+ does not support Avatars), and interfaces on which no information
+ is known for these contacts (e.g. we don't know the avatar tokens
+ of any of the contacts, so we omitted them all) by inspecting
+ <tp:member-ref>ContactAttributeInterfaces</tp:member-ref>.</p>
+ </tp:rationale>
+
+ <p>Attributes from the interface
+ <tp:dbus-ref>org.freedesktop.Telepathy.Connection</tp:dbus-ref>
+ are always returned, and need not be requested explicitly.</p>
+
+ <p>As well as returning cached information immediately, the
+ connection MAY start asynchronous requests to obtain better
+ values for the contact attributes. If better values are later
+ obtained by this process, they will be indicated with the usual
+ signals (such as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Aliasing">AliasesChanged</tp:dbus-ref>).</p>
+
+ <tp:rationale>
+ For instance, an XMPP connection manager could download vCards
+ in response to a request for <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Aliasing</tp:dbus-ref>
+ attributes.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:changed version="0.19.2">
+ requesting information for interfaces not mentioned in
+ <tp:member-ref>ContactAttributeInterfaces</tp:member-ref> is no
+ longer an error. Be aware that older connection managers may still
+ consider this an error.
+ </tp:changed>
+ </arg>
+
+ <arg direction="in" name="Hold" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If true, all handles that appear as keys in the result have been
+ held on behalf of the calling process, as if by a call to
+ <tp:dbus-ref namespace="ofdT">Connection.HoldHandles</tp:dbus-ref>.
+ (If <tp:dbus-ref namespace="ofdT.Connection"
+ >HasImmortalHandles</tp:dbus-ref> is true, which SHOULD be the
+ case in all new connection managers, this has no effect.)</p>
+
+ <tp:rationale>
+ <p>For further round-trip avoidance.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" type="a{ua{sv}}" name="Attributes"
+ tp:type="Contact_Attributes_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary mapping the contact handles to contact attributes.
+ If any of the requested handles are in fact invalid, they are
+ simply omitted from this mapping. If contact attributes are not
+ immediately known, the behaviour is defined by the interface;
+ the attribute should either be omitted from the result or
+ replaced with a default value.</p>
+
+ <p>Each contact's attributes will always include at least the
+ identifier that would be obtained by inspecting the handle
+ (<code>org.freedesktop.Telepathy.Connection/contact-id</code>).</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ </tp:possible-errors>
+ </method>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Forwarding.xml b/spec/spec/Connection_Interface_Forwarding.xml
new file mode 100644
index 000000000..32c7e1cbb
--- /dev/null
+++ b/spec/spec/Connection_Interface_Forwarding.xml
@@ -0,0 +1,346 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Forwarding"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2005-2010 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright © 2005-2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Forwarding.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.19.6">(draft version, not API-stable)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This connection interface is for protocols that are capable of
+ signaling to remote contacts that incoming communication channels
+ should be instead sent to a separate contact. This might apply to
+ things such as call forwarding, for example.</p>
+
+ <p>In some cases, a CM may register forwarding rules with an external
+ service; in those cases, it will never see the incoming channel, and
+ the forwarding will happen automatically.</p>
+
+ <p>In other cases, the CM will handle the forwarding itself. When an
+ incoming channel is detected, the status of the local user will
+ determine whether or not a forwarding rule is matched. For some
+ rules, this MAY happen immediately (ie, if the user is Busy); for
+ others, there MAY be a timeout (in seconds) that must expire
+ before the forwarding rule is matched (the timeout is specified
+ by the first element in the <tp:type>Forwarding_Rule_Entry</tp:type> list).</p>
+
+ <p>Once a forwarding rule is matched and any necessary timeouts have
+ expired, the CM can forward the incoming channel to the specified
+ handle. If for whatever reason the remote handle does not accept
+ the channel AND the CM supports multiple forwarding entries AND
+ any necessary timeouts have expired (specified by the next entry
+ in the list), the CM can forward the incoming channel to the next
+ handle in the entry list. This continues until the list is
+ exhausted, or the incoming channel is accepted.</p>
+
+ <p>Note that the rule matches are only for the first entry in the
+ in the forwarding rule list. Once the incoming channel has been
+ forwarded, the next entry in the list (assuming one exists and
+ the contact that the channel has been forwarded to does not respond
+ after any necessary timeouts) is used regardless of the status of
+ the forwarded channel. The initial match rule might have been
+ Busy, whereas the contact that the channel has been forwarded to
+ might be offline. Even in this case, the Busy list is still
+ traversed until the channel is handled (or there are no more
+ forwarding entries in the list).</p>
+
+ <p>For example, assuming the following dict for Forwarding_Rules:</p>
+ <pre>
+ ForwardingRules = {
+ Busy: ( initial-timeout: 30, [
+ (handle: 3, timeout: 15),
+ (handle: 5, timeout: 20)
+ ]),
+ NoReply: ( initial-timeout: 15, [
+ (handle: 5, timeout: 30),
+ (handle: 3, timeout: 20)
+ ])
+ }</pre>
+
+ <p>We can imagine a scenario where an incoming channel is detected,
+ the media stream is available (ie, not Busy),
+ and the local user is online. While the CM is waiting for the local user to
+ accept the channel, it looks at NoReply's first timeout value. After 15s if
+ the local user hasn't accepted, the CM forwards the channel to Handle #5. The
+ CM then waits 30s for Handle #5 to accept the channel. If after 30s it does
+ not, the CM forwards the incoming channel to Handle #3, which will have
+ 20s to accept the channel.</p>
+
+ <p>When an unanswered <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>StreamedMedia</tp:dbus-ref> call is
+ forwarded, both the contact and the self handle should be removed from
+ the group with the self handle as the actor, and
+ <tp:type>Channel_Group_Change_Reason</tp:type> <code>No_Answer</code> or
+ <code>Busy</code>, as appropriate. For <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Call1</tp:dbus-ref> channels, the
+ <tp:type>Call_State_Change_Reason</tp:type> <code>Forwarded</code>
+ should be used.</p>
+ </tp:docstring>
+
+ <tp:enum name="Forwarding_Condition" type="u">
+ <tp:docstring>
+ The various forwarding conditions that are supported by this interface.
+ In general, the conditions should not overlap; it should be very clear
+ which rule would be chosen given a CM's behavior with an incoming
+ channel. The exception to this is Unconditional,
+ which will override all other rules.
+ </tp:docstring>
+
+ <tp:enumvalue value="0" suffix="Unconditional">
+ <tp:docstring>
+ Incoming channels should always be forwarded. Note that setting this
+ will override any other rules. If not set, other rules will
+ be checked when an incoming communication channel is detected.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="1" suffix="Busy">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The incoming channel should be forwarded if a busy signal is
+ detected. What defines "Busy" is CM-specific (perhaps a single
+ resource is already in use, or a user's status is set to Busy
+ <tp:type>Connection_Presence_Type</tp:type>).</p>
+
+ <p>If initial timeout is specified for Busy condition and call
+ waiting is not supported by the service, the timeout will be
+ ignored.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="2" suffix="No_Reply">
+ <tp:docstring>
+ The incoming channel should be forwarded if the local user doesn't
+ accept it within the specified amount of time.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="3" suffix="Not_Reachable">
+ <tp:docstring>
+ The incoming channel should be forwarded if the user is offline.
+ This could be a manual setting (the user has chosen to set their
+ presence to offline or invisible) or something specified by the
+ underlying network (the user is not within range of a cell tower).
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Forwarding_Rule_Entry"
+ array-name="Forwarding_Rule_Entry_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A forwarding rule entry. These MAY be chained together
+ for CMs that support chaining of forwards (in other words,
+ a forwarding rule may have multiple entries; if the contact
+ in the first entry doesn't respond, the incoming channel
+ might be forwarded to the contact in the second entry).</p>
+
+ <p>For CMs and protocols that don't support chaining of
+ entries, only the first entry would be used.</p>
+ </tp:docstring>
+
+ <tp:member type="u" name="Timeout">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The length of time (in seconds) to wait the contact to respond
+ to the forwarded channel. This MAY be ignored by the CM if it
+ isn't supported by the underlying network/protocol for the
+ specific status of the remote contact (for example, a GSM call
+ that is forwarded may return Not_Reachable immediately without
+ waiting for the timeout value to expire).</p>
+
+ <p>A value of 0 means the condition can match immediately. A
+ value of MAX_UINT32 means that the CM's default should be
+ used.</p>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="u" tp:type="Contact_Handle" name="Handle">
+ <tp:docstring>
+ The contact to forward an incoming channel to. If the handle
+ doesn't point to anything (e.g. points to a phone number that
+ doesn't exist), the entry SHOULD be skipped.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Forwarding_Rule_Chain">
+ <tp:docstring>
+ A chain of forwarding rules and an initial timeout after which
+ the rules are applied.
+ </tp:docstring>
+
+ <tp:member type="u" name="InitialTimeout">
+ <tp:docstring>Initial timeout for the rule.</tp:docstring>
+ </tp:member>
+
+ <tp:member type="a(uu)" name="Rules" tp:type="Forwarding_Rule_Entry[]">
+ <tp:docstring>The forwarding targets (an array of type
+ <tp:type>Forwarding_Rule_Entry</tp:type>).
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Forwarding_Rule_Map" array-name="">
+ <tp:docstring>A dictionary whose keys are forwarding conditions and
+ whose values are <tp:type>Forwarding_Rule_Chain</tp:type> structs.
+ </tp:docstring>
+
+ <tp:member type="u" tp:type="Forwarding_Condition" name="Condition" />
+ <tp:member type="(ua(uu))" tp:type="Forwarding_Rule_Chain"
+ name="Rule_Chain" />
+ </tp:mapping>
+
+ <tp:mapping name="Supported_Forwarding_Conditions_Map" array-name="">
+ <tp:docstring>A dictionary whose keys are forwarding conditions and
+ whose values are maximum number of <tp:type>Forwarding_Rule_Entry</tp:type>
+ for the condition.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Forwarding_Condition" name="Condition" />
+ <tp:member type="u" name="Chain_Length" />
+ </tp:mapping>
+
+ <property name="SupportedForwardingConditions" type="a{uu}" access="read"
+ tp:type="Supported_Forwarding_Conditions_Map"
+ tp:name-for-bindings="Supported_Forwarding_Conditions">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map of forwarding conditions supported on this connection to
+ maximum number of <tp:type>Forwarding_Rule_Entry</tp:type>
+ supported for the specific condition.</p>
+
+ <tp:rationale>
+ <p>When forwarding is done by the provider, different providers
+ might support different chain sizes, or provider and local
+ implementation chain sizes might differ.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="ForwardingRules" type="a{u(ua(uu))}" access="read"
+ tp:type="Forwarding_Rule_Map" tp:name-for-bindings="Forwarding_Rules">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The current forwarding rules that are enabled for this connection.
+ Forwarding rules each contain an array of type
+ <tp:type>Forwarding_Rule_Entry</tp:type>.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="ForwardingRuleChanged"
+ tp:name-for-bindings="Forwarding_Rule_Changed">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the <tp:member-ref>ForwardingRules</tp:member-ref> property changes.</p>
+
+ <p>By the time this is emitted, the property MUST have been updated
+ with the new rules being active. If any protocol/network
+ requests must be made, they should be completed before the signal
+ is emitted.</p>
+ </tp:docstring>
+
+ <arg name="Condition" type="u" tp:type="Forwarding_Condition">
+ <tp:docstring>
+ The condition of the forwarding rule that's been changed.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Timeout" type="u">
+ <tp:docstring>
+ The new initial timeout for the rule.
+ </tp:docstring>
+ </arg>
+
+ <arg name="Forwards" type="a(uu)" tp:type="Forwarding_Rule_Entry[]">
+ <tp:docstring>
+ The new (and as of the emission of the signal, currently active)
+ forwards. The order is relevant; those at the lowest array index
+ are used first.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="SetForwardingRule" tp:name-for-bindings="Set_Forwarding_Rule">
+ <tp:docstring>
+ Update the forwarding rules.
+ </tp:docstring>
+
+ <arg direction="in" name="Condition" type="u" tp:type="Forwarding_Condition">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The forwarding rule to override. Note that this SHOULD not affect
+ other rules; setting a rule that overrides others (such as
+ Forwarding_Rule_Unconditional) will not modify other rules. This
+ means that when a client sets Forwarding_Rule_Busy and then
+ temporarily sets Forwarding_Rule_Unconditional, the
+ Forwarding_Rule_Busy rule will retain settings after
+ Forwarding_Rule_Unconditional, has been unset.</p>
+
+ <p>If the CM has no choice but to adjust multiple rules after a call
+ to this function (ie, due to the network or protocol forcing such
+ behavior), the CM MUST emit multiple <tp:member-ref>ForwardingRuleChanged</tp:member-ref>
+ signals for each changed rule. The order of the signals is
+ implementation-dependent, with the only requirement that the
+ last signal is for the rule that was originally requested to have
+ been changed (e.g. if Unconditional automatically modifies
+ Busy and NoReply, three
+ separate <tp:member-ref>ForwardingRuleChanged</tp:member-ref> signals should be raised with the
+ last signal being for Forwarding_Rule_Unconditional).</p>
+
+ <p>Each forwarding condition will occur no more than once in
+ the rule array. Setting a rule will overwrite the old rule
+ with the same <tp:type>Forwarding_Condition</tp:type> in its entirety.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="Forwards" type="a(uu)" tp:type="Forwarding_Rule_Entry[]">
+ <tp:docstring>
+ The forwarding targets (an array of type <tp:type>Forwarding_Rule_Entry</tp:type>) to
+ activate for the rule. An empty array will effectively disable the
+ rule.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Old_Forwards" type="a(uu)" tp:type="Forwarding_Rule_Entry[]">
+ <tp:docstring>
+ The old forwarding targets (an array of type <tp:type>Forwarding_Rule_Entry</tp:type>).
+ This is the list of entries that is being replaced with the call to
+ <tp:member-ref>SetForwardingRule</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The specified Condition is not supported by this connection,
+ or the number of chained
+ <tp:member-ref>SupportedForwardingConditions</tp:member-ref> should
+ be checked prior to calling
+ <tp:member-ref>SetForwardingRule</tp:member-ref>.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ A Handle that has been supplied is invalid.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Keepalive.xml b/spec/spec/Connection_Interface_Keepalive.xml
new file mode 100644
index 000000000..9f4ac6833
--- /dev/null
+++ b/spec/spec/Connection_Interface_Keepalive.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Keepalive"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright © 2010 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Keepalive.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.21.2">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Most messaging protocols allow the client to send periodic
+ content-less pings to the server when the connection is otherwise idle,
+ to reassure both itself and the server that its connection is still
+ alive. Depending on the nature of the network connection, and the
+ device running the client, the desired interval between such pings may
+ vary.</p>
+
+ <tp:rationale>
+ <p>For instance, on a mobile handset connected via 3G,
+ overly-frequent keepalives can drain the battery through needlessly
+ waking up the radio, and a relatively high interval is appropiate. By
+ contrast, a desktop computer is less likely to be asleep in the first
+ place, and users expect dropped connections to be noticed as soon as
+ possible.</p>
+ </tp:rationale>
+
+ <p>This interface provides a
+ <tp:member-ref>KeepaliveInterval</tp:member-ref> property which
+ controls the frequency of keepalive pings, if any. Connection managers
+ implementing this property should also include it in <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy'>Protocol.Parameters</tp:dbus-ref>
+ with the <code>DBus_Property</code> flag, allowing the desired value to
+ be stored in <tp:dbus-ref
+ namespace='org.freedesktop.Telepathy'>Account.Parameters</tp:dbus-ref>
+ and passed onto the connection by the account manager.</p>
+ </tp:docstring>
+
+ <property name="KeepaliveInterval" type="u" access="readwrite"
+ tp:name-for-bindings="Keepalive_Interval"
+ tp:is-connection-parameter='och aye'>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time in seconds between pings sent to the server to ensure that
+ the connection is still alive, or <tt>0</tt> to disable such
+ pings.</p>
+
+ <p>This property (and parameter) supersedes the older
+ <tt>keepalive-interval</tt>
+ <tp:type>Connection_Parameter_Name</tp:type>.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Location.xml b/spec/spec/Connection_Interface_Location.xml
new file mode 100644
index 000000000..c4fd68c3b
--- /dev/null
+++ b/spec/spec/Connection_Interface_Location.xml
@@ -0,0 +1,464 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Location"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Collabora Ltd.</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Location">
+ <tp:added version="0.17.27">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface on connections to support protocols which allow users to
+ publish their current geographical location, and subscribe to the
+ current location of their contacts.</p>
+
+ <p>This interface is geared strongly towards automatic propagation and
+ use of this information, so focuses on latitude, longitude and
+ altitude which can be determined by GPS, although provision is also
+ included for an optional human-readable description of locations. All
+ co-ordinate information is required to be relative to the WGS84
+ datum.</p>
+
+ <p>The information published through this interface is intended to have
+ the same scope as presence information, so will normally be made
+ available to those individuals on the user's "publish" contact list.
+ Even so, user interfaces should not automatically publish location
+ information without the consent of the user, and it is recommended
+ that an option is made available to reduce the accuracy of the
+ reported information to allow the user to maintain their privacy.</p>
+
+ <p>Location information is represented using the terminology of XMPP's
+ <a href="http://www.xmpp.org/extensions/xep-0080.html">XEP-0080</a>
+ or the XEP-0080-derived
+ <a href="http://geoclue.freedesktop.org/">Geoclue</a> API where
+ possible.</p>
+
+ <p>Clients of this interface SHOULD register an interest in it by calling
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.AddClientInterest</tp:dbus-ref> with an argument
+ containing the name of this interface,
+ before calling any Location method. If they do so, they SHOULD also call
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.RemoveClientInterest</tp:dbus-ref> after use to allow
+ the CM to release resources associated with this interface.</p>
+ </tp:docstring>
+
+ <!-- Potentially to be reinstated later:
+ http://bugs.freedesktop.org/show_bug.cgi?id=19585
+ <tp:enum name="Location_Accuracy_Level" type="u">
+ <tp:docstring>
+ A location accuracy level. This should be kept in sync with
+ GeoclueAccuracyLevel in the Geoclue project.
+ </tp:docstring>
+
+ <tp:enumvalue suffix="None" value="0">
+ <tp:docstring>
+ The accuracy is unspecified.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Country" value="1">
+ <tp:docstring>
+ The location indicates the contact's country.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Region" value="2">
+ <tp:docstring>
+ The location indicates the contact's region within a country.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Locality" value="3">
+ <tp:docstring>
+ The location indicates the contact's locality within a region
+ (e.g. the correct city).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Postal_Code" value="4">
+ <tp:docstring>
+ The location indicates the correct postal code.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Street" value="5">
+ <tp:docstring>
+ The location indicates the correct street.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Detailed" value="6">
+ <tp:docstring>
+ The location's accuracy is given by the accuracy key.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ -->
+
+ <tp:mapping name="Location">
+ <tp:docstring>
+ A user's location, represented as an extensible mapping.
+ </tp:docstring>
+
+ <tp:member name="Key" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+
+ <p>Civic addresses are represented by the following well-known
+ keys (all of which have string values), which should be kept in
+ sync with those used in XEP-0080 and in the Geoclue project:</p>
+
+ <ul>
+ <li>countrycode - s: an ISO-3166-1 alpha-2 (two-letter) country
+ code, e.g. "us", "gb", "fr"</li>
+ <li>country - s: a country name in unspecified locale, e.g.
+ "USA"</li>
+ <li>region - s: an administrative region of the nation, such as a
+ state or province</li>
+ <li>locality - s: a locality within the administrative region, such
+ as a town or city</li>
+ <li>area - s: a named area such as a campus or neighborhood</li>
+ <li>postalcode - s: a code used for postal delivery</li>
+ <li>street - s: a thoroughfare within the locality, or a crossing of
+ two thoroughfares</li>
+ </ul>
+
+ <p>The following address keys are defined in XEP-0080 but not by
+ Geoclue, and are also allowed:</p>
+
+ <ul>
+ <li>building - s: a specific building on a street or in an area</li>
+ <li>floor - s: a particular floor in a building</li>
+ <li>room - s: a particular room in a building</li>
+ <li>text - s: any more specific information, e.g.
+ "Northwest corner of the lobby"</li>
+ <li>description - s: A natural-language name for or description of
+ the location, e.g. "Bill's house"</li>
+ <li>uri - s: a URI representing the location or pointing to more
+ information about it</li>
+ </ul>
+
+ <p>Since the previous strings have data intended to be read by users,
+ the language used should be stated using:</p>
+
+ <ul>
+ <li>language - s: a specific language or locale of location
+ information in a format compatible to RFC 4646. Note that UTF-8
+ is the only allowed encoding, e.g. "en" or "fr-CA".</li>
+ </ul>
+
+ <p>Positions are represented by the following well-known keys:</p>
+
+ <ul>
+ <li>lat - d: latitude in decimal degrees north, -90 to +90,
+ relative to the WGS-84 datum
+ <tp:rationale>
+ This is from XEP-0080; the XEP allows use of a different
+ datum, but recommends this one. We enforce sanity by requiring
+ a consistent datum: a minimal compliant implementation of this
+ specification in terms of XEP-0080 would simply ignore the
+ &lt;lat&gt; and &lt;lon&gt; elements if &lt;datum&gt; exists
+ and has a value other than WGS-84, while an advanced
+ implementation might correct for the different datum.
+ </tp:rationale>
+ </li>
+ <li>lon - d: Longitude in decimal degrees east, -180 to +180,
+ relative to the WGS-84 datum
+ <tp:rationale>
+ Same rationale as 'lat'
+ </tp:rationale>
+ </li>
+ <li>alt - d: altitude in metres above sea level (negative
+ if below sea level)
+ <tp:rationale>
+ This is from XEP-0080
+ </tp:rationale>
+ </li>
+
+ <!-- Potentially to be reinstated later:
+ http://bugs.freedesktop.org/show_bug.cgi?id=19585
+ <li>accuracy-level - i (<tp:type>Location_Accuracy_Level</tp:type>):
+ an indication of accuracy, which SHOULD be omitted if it would be
+ Location_Accuracy_Level_None or
+ Location_Accuracy_Level_Detailed
+ <tp:rationale>
+ This is a struct field in GeoClue; the name is new in this
+ specification, and was chosen in an attempt to avoid clashing
+ with any future XEP-0080 terminology.
+ </tp:rationale>
+ </li>
+ -->
+
+ <li>accuracy - d: horizontal position error in metres if
+ known
+ <tp:rationale>
+ This is from XEP-0080
+ </tp:rationale>
+ </li>
+ </ul>
+
+ <p>Velocities are represented by the following well-known keys:</p>
+
+ <ul>
+ <li>speed - d: speed in metres per second
+ <tp:rationale>
+ This is from XEP-0080
+ </tp:rationale>
+ </li>
+ <li>bearing - d: direction of movement in decimal degrees,
+ where North is 0 and East is 90
+ <tp:rationale>
+ This is from XEP-0080, and is equivalent to the struct field
+ called "direction" in GeoClue
+ </tp:rationale>
+ </li>
+ </ul>
+
+ <p>Other well-known keys:</p>
+
+ <ul>
+ <li>timestamp - x (<tp:type>Unix_Timestamp64</tp:type>): the time
+ that the contact was at this location, in seconds since
+ 1970-01-01T00:00:00Z (i.e. the beginning of 1970 in UTC)
+ <tp:rationale>
+ XEP-0080 uses an ISO 8601 string for this, but a number of
+ seconds since the epoch is probably easier to work with.
+ </tp:rationale>
+ </li>
+ </ul>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Value" type="v">
+ <tp:docstring>
+ The value corresponding to the well-known key.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:mapping name="Contact_Locations" type="a{ua{sv}}">
+ <tp:docstring>
+ A map from contacts to their locations.
+ </tp:docstring>
+ <tp:member name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>A contact</tp:docstring>
+ </tp:member>
+ <tp:member name="Location" type="a{sv}" tp:type="Location">
+ <tp:docstring>The contact's location, which MAY be empty to indicate
+ that the contact's location is unknown</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <method name="GetLocations" tp:name-for-bindings="Get_Locations">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Return the current locations of the given contacts, if they are
+ already known. If any of the given contacts' locations are not known,
+ request their current locations, but return immediately without waiting
+ for a reply; if a reply with a non-empty location is later received
+ for those contacts, the <tp:member-ref>LocationUpdated</tp:member-ref>
+ signal will be emitted for them.</p>
+
+ <tp:rationale>
+ <p>This method is appropriate for "lazy" location finding, for instance
+ displaying the location (if available) of everyone in your contact
+ list.</p>
+ </tp:rationale>
+
+ <p>For backwards compatibility, if this method is called by a client
+ whose "interest count" for this interface, as defined by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.AddClientInterest</tp:dbus-ref>, is zero, the
+ Connection SHOULD behave as if AddClientInterest had been called for
+ this interface just before that method call. Clients that do not
+ explicitly call AddClientInterest SHOULD NOT call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.RemoveClientInterest</tp:dbus-ref> either.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The contacts whose locations should be returned or signalled.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Locations" type="a{ua{sv}}"
+ tp:type="Contact_Locations">
+ <tp:docstring>
+ The contacts' locations, if already known. Contacts whose locations
+ are not already known are omitted from the mapping; contacts known
+ to have no location information appear in the mapping with an empty
+ Location dictionary.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestLocation" tp:name-for-bindings="Request_Location">
+ <tp:docstring>
+ Return the current location of the given contact. If necessary, make
+ a request to the server for up-to-date information, and wait for a
+ reply.
+
+ <tp:rationale>
+ This method is appropriate for use in a "Contact Information..."
+ dialog; it can be used to show progress information (while waiting
+ for the method to return), and can distinguish between various error
+ conditions.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact whose location should be returned.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Location" type="a{sv}" tp:type="Location">
+ <tp:docstring>
+ The contact's location. It MAY be empty, indicating that no location
+ information was found.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied">
+ <tp:docstring>
+ The requested contact does not allow the local user to see their
+ location information.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="LocationUpdated" tp:name-for-bindings="Location_Updated">
+ <tp:docstring>
+ Emitted when a contact's location changes or becomes known.
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact
+ </tp:docstring>
+ </arg>
+ <arg name="Location" type="a{sv}" tp:type="Location">
+ <tp:docstring>
+ The contact's location, or empty to indicate that nothing is known
+ about the contact's location.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="SetLocation" tp:name-for-bindings="Set_Location">
+ <tp:docstring>
+ Set the local user's own location.
+ </tp:docstring>
+
+ <arg direction="in" name="Location" type="a{sv}">
+ <tp:docstring>
+ The location to advertise. If the user wants to obscure their
+ exact location by reducing the precision or accuracy, clients
+ MUST do this themselves, rather than relying on the connection
+ manager to do so. Clients that interact with more than one
+ connection SHOULD advertise the same reduced-accuracy location
+ to all of them, so that contacts cannot obtain an undesirably
+ accurate location by assuming that random errors have been added
+ and averaging the locations advertised on multiple connections.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The user's server does not support publishing their own location.
+ If it is possible to determine this ahead of time, the
+ <code>Can_Set</code> flag will not be set in
+ <tp:member-ref>SupportedLocationFeatures</tp:member-ref>.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="LocationAccessControlTypes" type="au" access="read"
+ tp:type="Rich_Presence_Access_Control_Type[]" tp:name-for-bindings="Location_Access_Control_Types">
+ <tp:docstring>The types of access control that are supported by this
+ connection.</tp:docstring>
+ </property>
+
+ <property name="LocationAccessControl" type="(uv)" access="readwrite"
+ tp:type="Rich_Presence_Access_Control" tp:name-for-bindings="Location_Access_Control">
+ <tp:docstring>The current access control mechanism and settings
+ for this connection. Before publishing location for the first time,
+ if this has not been set by a client, implementations SHOULD
+ set it to be as restrictive as possible (an empty whitelist, if
+ supported).</tp:docstring>
+ </property>
+
+ <property name="SupportedLocationFeatures"
+ tp:name-for-bindings="Supported_Location_Features"
+ type="u" tp:type="Location_Features" access="read">
+ <tp:added version="0.19.6"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Indicates the Location features supported by this connection. This
+ property MAY be undefined before <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">Status</tp:dbus-ref>
+ becomes <code>Connected</code>, but MUST remain constant thereafter.
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Location_Features" type="u" value-prefix="Location_Feature">
+ <tp:flag suffix="Can_Set" value="1">
+ <tp:docstring>
+ Indicates that setting your own location with
+ <tp:member-ref>SetLocation</tp:member-ref> is supported on this
+ connection.
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Flags describing the Location features which may be supported on any
+ given connection.
+ </tp:docstring>
+ </tp:flags>
+
+ <tp:contact-attribute name="location"
+ type="a{sv}" tp:type="Location">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same mapping that would be returned by
+ <tp:member-ref>GetLocations</tp:member-ref> for this contact.
+ Omitted from the result if the contact's location
+ is not known.</p>
+
+ <p>For backwards compatibility, if contact attributes that include
+ this interface are requested
+ by a client whose "interest count" for this interface, as defined by
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.AddClientInterest</tp:dbus-ref>, is zero, the
+ Connection SHOULD behave as if AddClientInterest was called for this
+ interface just before that request. Clients that do not explicitly
+ call AddClientInterest SHOULD NOT call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.RemoveClientInterest</tp:dbus-ref> either.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Mail_Notification.xml b/spec/spec/Connection_Interface_Mail_Notification.xml
new file mode 100644
index 000000000..395e1019d
--- /dev/null
+++ b/spec/spec/Connection_Interface_Mail_Notification.xml
@@ -0,0 +1,624 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Mail_Notification"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ >
+ <tp:copyright> Copyright (C) 2007 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Connection.Interface.MailNotification">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.21.3">(as stable API)</tp:added>
+
+ <tp:client-interest>
+ <tp:docstring>
+ A client MUST notify interest in this feature before it will be
+ enabled.
+ </tp:docstring>
+ </tp:client-interest>
+
+ <tp:flags name="Mail_Notification_Flags" value-prefix="Mail_Notification_Flag" type="u" >
+ <tp:flag suffix="Supports_Unread_Mail_Count" value="1">
+ <tp:docstring>
+ This Connection provides the number of unread e-mails (or e-mail
+ threads) in the main folder of your e-mail account, as the
+ <tp:member-ref>UnreadMailCount</tp:member-ref> property. The
+ connection manager will update this value by emitting the
+ <tp:member-ref>UnreadMailsChanged</tp:member-ref> signal.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Supports_Unread_Mails" value="2">
+ <tp:docstring>
+ This Connection provides a detailed list of unread e-mails, as the
+ <tp:member-ref>UnreadMails</tp:member-ref> property. If this flag
+ is set, <tt>Supports_Unread_Mail_Count</tt> MUST be set, and
+ <tt>Emits_Mails_Received</tt> MUST NOT be set.
+ The Connection will update the list by emitting the
+ <tp:member-ref>UnreadMailsChanged</tp:member-ref> signals.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Emits_Mails_Received" value="4">
+ <tp:docstring>
+ This Connection emits the <tp:member-ref>MailsReceived</tp:member-ref>
+ signal, which provides details about newly arrived e-mails but does
+ not maintain their read/unread status afterwards. This flag MUST NOT
+ be combined with <tt>Supports_Unread_Mails</tt>.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Supports_Request_Inbox_URL" value="8">
+ <tp:docstring>
+ This Connection can provide a URL (with optional POST data) to
+ open the the inbox of the e-mail account in a web-based client, via
+ the <tp:member-ref>RequestInboxURL</tp:member-ref> method.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Supports_Request_Mail_URL" value="16">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This Connection can provide a URL (with optional POST data) to open
+ a specific mail in a web-based client, via the
+ <tp:member-ref>RequestMailURL</tp:member-ref> method. This feature
+ is not useful unless either Emits_Mails_Received or
+ Supports_Unread_Mails is set.</p>
+
+ <p>If this flag is not set, clients SHOULD fall back to using
+ <tp:member-ref>RequestInboxURL</tp:member-ref> if available.</p>
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Thread_Based" value="32">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Each <tp:type>Mail</tp:type> represents a thread of e-mails, which
+ MAY have more than one sender.</p>
+
+ <tp:rationale>
+ <p>Google Talk notifies users about new mail in terms of unread
+ threads, rather than unread e-mails.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:flag>
+
+ <tp:docstring>
+ <p>Flags representing capabilities provided by a connection manager.
+ Those values can be used as bitfield. Some flags depend on, or
+ conflict with, each other.</p>
+
+ <p>Connections SHOULD implement as many of these features as the
+ underlying protocol allows, preferring to implement
+ Supports_Unread_Mails instead of Emits_Mails_Received if both are
+ possible.</p>
+ </tp:docstring>
+ </tp:flags>
+
+ <tp:enum name="HTTP_Method" type="u">
+ <tp:enumvalue suffix="Get" value="0">
+ <tp:docstring>
+ Use the GET method when opening the URL.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Post" value="1">
+ <tp:docstring>
+ Use the POST method when opening the URL. Refer to
+ <tp:type>HTTP_Post_Data</tp:type> for more details.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:docstring>
+ The HTTP Method with which to request a URL.
+ </tp:docstring>
+ </tp:enum>
+
+ <tp:struct name="HTTP_Post_Data" array-name="HTTP_Post_Data_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A pair (key, value) representing POST data compatible with the
+ application/x-www-form-urlencoded MIME type. The strings MUST be
+ valid UTF-8 strings, and the characters used in the key MUST obey
+ the requirements of the
+ <a href="http://www.w3.org/TR/html401/types.html#type-cdata">
+ HTML CDATA type</a>. The value MUST NOT be
+ encoded with HTML entities.</p>
+
+ <p>For example, if the POST data should contain a key "less-than" with value
+ "&lt;", and a key "percent" with value "%", this should be represented as
+ two HTTP_Post_Data structures, ("less-than", "&lt;") and ("percent", "%"),
+ resulting in a POST request whose request body is "less-than=&amp;lt;&amp;percent=%25".
+ If a client passes this to a browser by writing it into an HTML form, it
+ could do so by representing it as:</p>
+
+ <pre>
+ &lt;input type="hidden" name="less-than"&gt;&amp;lt;&lt;/input&gt;
+ &lt;input type="hidden" name="percent"&gt;%&lt;/input&gt;
+ </pre>
+
+ <tp:rationale>
+ <p>This data can be used to generate a HTML file that will
+ automatically load the URL with appropriate POST data, in which case
+ the client MUST convert any characters that are special within HTML
+ into HTML entities. Alternatively, it can be used in an API that will
+ instruct the browser how to load the URL (like the Netscape Plug-in
+ API), in which case the client MUST escape
+ <a href="http://www.ietf.org/rfc/rfc1738.txt">characters that are
+ reserved in URLs</a>, if appropriate for that API.</p>
+
+ <p>An array of pairs is used instead of a map from keys to values,
+ because it's valid to repeat keys in both HTML and
+ x-www-form-urlencoded data.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:member type="s" name="Key">
+ <tp:docstring>The key, corresponding to a HTML control
+ name</tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Value">
+ <tp:docstring>The value</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Mail_Address" array-name="Mail_Address_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A pair (name, address) representing an e-mail address,
+ such as ("Nicolas Dufresne", "nicolas.dufresne@collabora.co.uk"). At
+ least one of name and address MUST be provided. A missing element will
+ be represented by the empty string.</p>
+ <tp:rationale>
+ <p>The CM should provide as much information as possible, but not all
+ protocols provide both the displayed name and the address. (If a
+ protocol doesn't provide either, it should omit the appropriate
+ field from the <tp:type>Mail</tp:type> entirely.)</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:member type="s" name="Name">
+ <tp:docstring>The displayed name corresponding to the e-mail
+ address</tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Address">
+ <tp:docstring>The actual e-mail address</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Mail_URL">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A structure containing the required information to open a web-based
+ e-mail UI, without needing re-authentication (if possible).</p>
+
+ <p>Because the URL and POST data frequently contain short-lived
+ credential tokens, a new URL should be requested (by calling one of
+ the methods that returns a Mail_URL) for each visit to the web-based
+ UI, and the URL should be visited soon after it is returned.</p>
+ </tp:docstring>
+ <tp:member type="s" name="URL">
+ <tp:docstring>
+ The URL to which to send a request.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Method" tp:type="HTTP_Method">
+ <tp:docstring>
+ The HTTP method of the request.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="a(ss)" name="Post_Data" tp:type="HTTP_Post_Data[]">
+ <tp:docstring>
+ An array of name-value pairs containing the POST data to use when
+ opening the URL. This MUST be an empty array if the Method is not
+ POST.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Mail" array-name="Mail_List">
+ <tp:docstring>
+ An extensible map representing a mail, or (on protocols where
+ <tt>Thread_Based</tt> appears in
+ <tp:member-ref>MailNotificationFlags</tp:member-ref>) a thread of
+ mails. All keys are optional where not otherwise stated; however, at
+ least one of "senders" and "subject" must be included.
+ </tp:docstring>
+
+ <tp:member type="s" name="Key">
+ <tp:docstring>
+ <p>A key providing information about the mail or thread. Well-known
+ keys are as follows:</p>
+
+ <dl>
+ <dt>id &#8212; s</dt>
+ <dd>
+ <p>A unique ID for this e-mail. CMs with
+ <tt>Supports_Unread_Mails</tt> set in
+ <tp:member-ref>MailNotificationFlags</tp:member-ref> MUST provide
+ this key in each <tp:type>Mail</tp:type>.</p>
+
+ <p>If provided, the ID SHOULD be unique to a Mail at least until
+ that mail is removed with the
+ <tp:member-ref>UnreadMailsChanged</tp:member-ref> signal
+ (in protocols with <tt>Supports_Unread_Emails</tt>), or
+ unique for the duration of a session (otherwise).</p>
+
+ <tp:rationale>
+ <p>In protocols with Supports_Unread_Mails, this key is used to
+ indicate which mail was removed. In protocols without that
+ feature, it's impossible to tell when a mail has been removed
+ (and hence how long the identifier will remain valid for use
+ with <tp:member-ref>RequestMailURL</tp:member-ref>).</p>
+ </tp:rationale>
+ </dd>
+
+ <dt>url-data &#8212; any type</dt>
+ <dd>An opaque identifier (typically a string or list of strings)
+ provided to the Connection when calling
+ <tp:member-ref>RequestMailURL</tp:member-ref>,
+ containing information used by the Connection to build the URL.
+ </dd>
+
+ <dt>senders &#8212; a(ss) (<tp:type>Mail_Address</tp:type>)</dt>
+ <dd>
+ An array of sender display name and e-mail address pairs. Note that
+ only e-mails represented as a thread can have multiple senders.
+ </dd>
+
+ <dt>to-addresses &#8212; a(ss) (<tp:type>Mail_Address</tp:type>)</dt>
+ <dd>
+ An array of display name and e-mail address pairs representing
+ the recipients.
+ </dd>
+
+ <dt>cc-addresses &#8212; a(ss) (<tp:type>Mail_Address</tp:type>)</dt>
+ <dd>
+ An array of display name and e-mail address pairs representing
+ the carbon-copy recipients.
+ </dd>
+
+ <dt>sent-timestamp &#8212; x (<tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>A UNIX timestamp indicating when the message was sent, or for
+ a thread, when the most recent message was sent.
+ </dd>
+
+ <dt>received-timestamp &#8212; x (<tp:type>Unix_Timestamp64</tp:type>)</dt>
+ <dd>A UNIX timestamp indicating when the message was received, or for
+ a thread, when the most recent message was received.
+ </dd>
+
+ <dt>has-attachments &#8212; b</dt>
+ <dd>If true, this mail has attachments.</dd>
+
+ <dt>subject &#8212; s</dt>
+ <dd>
+ The subject of the message. This MUST be encoded in UTF-8.
+ </dd>
+
+ <dt>content-type &#8212; s</dt>
+ <dd>
+ <p>The MIME type of the message content. Two types are currently
+ supported: "text/plain" for plain text, and "text/html" for a
+ HTML document. If omitted, "text/plain" MUST be assumed.
+ Regardless of MIME type, the content MUST be valid UTF-8 (which
+ may require that the Connection transcodes it from a legacy
+ encoding).</p>
+
+ <tp:rationale>
+ <p>All strings on D-Bus must be UTF-8.</p>
+ </tp:rationale>
+ </dd>
+
+ <dt>truncated &#8212; b</dt>
+ <dd>
+ If true, the content is only a partial message; if false or
+ omitted, the content is the entire message.
+ </dd>
+
+ <dt>content &#8212; s</dt>
+ <dd>
+ The body of the message, possibly truncated, encoded as appropriate
+ for "content-type".
+ </dd>
+
+ <dt>folder &#8212; s</dt>
+ <dd>
+ The name of the folder containing this e-mails.
+ If omitted, the inbox SHOULD be assumed.
+ </dd>
+ </dl>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Value" type="v">
+ <tp:docstring>The value, of whatever type is appropriate for the
+ key.</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="MailNotificationFlags" type="u" access="read"
+ tp:type="Mail_Notification_Flags"
+ tp:name-for-bindings="Mail_Notification_Flags">
+ <tp:docstring>
+ Integer representing the bitwise-OR of supported features for e-mails
+ notification on this server. This property MUST NOT change after the
+ Connection becomes CONNECTED.
+
+ <tp:rationale>
+ This property indicates the behavior and availability
+ of the other properties and signals within this interface. A
+ connection manager that cannot at least set one of the flags
+ in the <tp:type>Mail_Notification_Flags</tp:type>
+ SHOULD NOT provide this interface.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="UnreadMailCount" type="u" access="read"
+ tp:name-for-bindings="Unread_Mail_Count">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The number of unread messages in the Inbox. Change notification is
+ via <tp:member-ref>UnreadMailsChanged</tp:member-ref>.</p>
+
+ <p>This property is only useful if <tt>Supports_Unread_Mail_Count</tt>
+ is set in the <tp:member-ref>MailNotificationFlags</tp:member-ref>;
+ otherwise, it MUST be zero.</p>
+
+ <p>If <tt>Thread_Based</tt> appears in the
+ <tp:member-ref>MailNotificationFlags</tp:member-ref>, this property
+ counts the number of threads, not the number of mails.</p>
+
+ <p>Note that this count MAY be bigger than the number of items in
+ <tp:member-ref>UnreadMails</tp:member-ref>. See
+ <tp:member-ref>UnreadMails</tp:member-ref> for more details.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="UnreadMails" type="aa{sv}" tp:type="Mail[]"
+ tp:name-for-bindings="Unread_Mails" access="read">
+ <tp:docstring>
+ <p>An array of unread <tp:type>Mail</tp:type>s. Change notification is
+ via <tp:member-ref>UnreadMailsChanged</tp:member-ref>. This property
+ is only useful if <tt>Supports_Unread_Mails</tt> is set in
+ <tp:member-ref>MailNotificationFlags</tp:member-ref>; otherwise, it
+ MUST be an empty list.</p>
+ <p>The array size MAY be shorter than
+ <tp:member-ref>UnreadMailCount</tp:member-ref>.</p>
+ <tp:rationale>
+ <p>Some servers may limits the amount of detailed e-mails sent. This
+ can significantly reduce the network traffic for large inbox. For
+ this reason, it is normal that
+ <tp:member-ref>UnreadMailCount</tp:member-ref> be bigger or equal
+ to the size of this array.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="MailAddress" type="s"
+ tp:name-for-bindings="Mail_Address" access="read">
+ <tp:docstring>
+ A string representing the e-mail address of the account. The CMs MUST
+ provide this information.
+ <tp:rationale>
+ In close integration of MailNotification with other e-mail services,
+ the e-mail address can be used has a unique identifier for the
+ account. Possible integration could be between Telepathy and
+ Evolution where the e-mail address is the common information in
+ both interfaces.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <signal name="MailsReceived" tp:name-for-bindings="Mails_Received">
+ <arg name="Mails" type="aa{sv}" tp:type="Mail[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of <tp:type>Mail</tp:type>s. Those e-mail MUST NOT have
+ the "id" key.</p>
+
+ <tp:rationale>
+ <p>On connections that emit this signal, it's impossible to tell
+ when a mail has been removed, and hence when "id" has become
+ invalid.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <tp:docstring>
+ Emitted when new e-mails messages arrive to the inbox associated with
+ this connection. This signal is used for protocols that are not able
+ to maintain the <tp:member-ref>UnreadMails</tp:member-ref> list, but
+ do provide real-time notification about newly arrived e-mails. It MUST
+ NOT be emitted unless <tt>Emits_Mails_Received</tt> is set in
+ <tp:member-ref>MailNotificationFlags</tp:member-ref>.
+ </tp:docstring>
+ </signal>
+
+ <signal name="UnreadMailsChanged"
+ tp:name-for-bindings="Unread_Mails_Changed">
+ <arg name="Count" type="u">
+ <tp:docstring>
+ Number of unread messages in the inbox (the new value of
+ <tp:member-ref>UnreadMailCount</tp:member-ref>).
+ </tp:docstring>
+ </arg>
+ <arg name="Mails_Added" type="aa{sv}" tp:type="Mail[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of <tp:type>Mail</tp:type> that are being added or updated
+ in <tp:member-ref>UnreadMails</tp:member-ref>.</p>
+
+ <tp:rationale>
+ <p>Mails may be updated when the URL information (URL and POST data)
+ have changed, or senders were added or removed from an e-mail
+ thread.</p>
+ </tp:rationale>
+
+ <p>If the <tt>Supports_Unread_Mails</tt> flag is not set, this list
+ MUST be empty, even if Count has increased.</p>
+ </tp:docstring>
+ </arg>
+ <arg name="Mails_Removed" type="as">
+ <tp:docstring>
+ A list of e-mail IDs that are being removed from
+ <tp:member-ref>UnreadMails</tp:member-ref>.
+ If the <tt>Supports_Unread_Mails</tt> flag is not set, this list
+ MUST be empty, even if Count has decreased.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when <tp:member-ref>UnreadMails</tp:member-ref> or
+ <tp:member-ref>UnreadMailCount</tp:member-ref> have changed. It MUST
+ NOT be emited if <tt>Supports_Unread_Mail_Count</tt> flag is not set
+ in <tp:member-ref>MailNotificationFlags</tp:member-ref>.</p>
+
+ <p><tt>Mails_Added</tt> and
+ <tt>Mails_Removed</tt> MUST be empty if the
+ <tt>Supports_Unread_Mails</tt> flag is not set.</p>
+ </tp:docstring>
+ </signal>
+
+ <method name="RequestInboxURL"
+ tp:name-for-bindings="Request_Inbox_URL">
+ <arg direction="out" name="URL" type="(sua(ss))" tp:type="Mail_URL" >
+ <tp:docstring>
+ A struture containing a URL and optional additional data to open a
+ webmail client, without re-authentication if possible.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ This method creates and returns a URL and an optional POST data that
+ allow opening the Inbox folder of a webmail account. This URL MAY
+ contain tokens with a short lifetime, so clients SHOULD request a new
+ URL for each visit to the webmail interface. This method is implemented
+ only if the <tt>Supports_Request_Inbox_URL</tt> flag is set in
+ <tp:member-ref>MailNotificationFlags</tp:member-ref>.
+
+ <tp:rationale>
+ We are not using properties here because the tokens are unsuitable
+ for sharing between clients, and network round-trips may be required
+ to obtain the information that leads to authentication free webmail
+ access.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RequestMailURL"
+ tp:name-for-bindings="Request_Mail_URL">
+ <arg direction="in" name="ID" type="s">
+ <tp:docstring>
+ The mail's <tt>id</tt> as found in the <tp:type>Mail</tp:type>
+ structure, or the empty string if no <tt>id</tt> key was provided.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="URL_Data" type="v">
+ <tp:docstring>
+ Whatever <tt>url-data</tt> was found in the <tp:type>Mail</tp:type>
+ structure, or the boolean value False (D-Bus type 'b') if no
+ <tt>url-data</tt> was provided in the Mail.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="URL" type="(sua(ss))" tp:type="Mail_URL" >
+ <tp:docstring>
+ A struture that contains a URL and optional additional data to open a
+ webmail client, without re-authentication if possible.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ This method creates and returns a URL and optional POST data that
+ allow opening a specific mail in a webmail interface. This
+ method is implemented only if <tt>Supports_Request_Mail_URL</tt> flag
+ is set in <tp:member-ref>MailNotificationFlags</tp:member-ref>.
+ <tp:rationale>
+ See <tp:member-ref>RequestInboxURL</tp:member-ref> for design
+ rationale.
+ </tp:rationale>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface to support receiving notifications about a e-mail
+ account associated with this connection.</p>
+
+ <p>In protocols where this is possible, this interface also allows the
+ connection manager to provide the necessary information for clients
+ to open a web-based mail client without having to re-authenticate.</p>
+
+ <p>To use this interface, a client MUST first subscribe by passing the
+ name of this interface to the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.AddClientInterest</tp:dbus-ref> method. The subscription
+ mechanic aims at reducing network traffic and memory footprint in the
+ situation where nobody is currently interesting in provided
+ information. When done with this interface, clients SHOULD call
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.RemoveClientInterest</tp:dbus-ref> to allow the CM to
+ release resources.</p>
+
+ <p>Protocols have various different levels of Mail Notification support.
+ To describe the level of support, the interface provides a property
+ called <tp:member-ref>MailNotificationFlags</tp:member-ref>.
+ Not all combinations are valid; protocols can be divided into four
+ categories as follows.</p>
+
+ <p>Connections to the most capable protocols, such as Google's XMPP Mail
+ Notification extension, have the Supports_Unread_Mails flag (this
+ implies that they must also have Supports_Unread_Mail_Count, but not
+ Emits_Mails_Received). On these connections, clients
+ requiring change notification MUST monitor the
+ <tp:member-ref>UnreadMailsChanged</tp:member-ref> signal, and
+ either recover the initial state from the
+ <tp:member-ref>UnreadMails</tp:member-ref> property (if they require
+ details other than the number of mails) or the
+ <tp:member-ref>UnreadMailCount</tp:member-ref> property (if they
+ are only interested in the number of unread mails). The
+ <tp:member-ref>MailsReceived</tp:member-ref> signal is never emitted
+ on these connections, so clients that will display a short-term
+ notification for each new mail MUST do so in response to emission of
+ the <tp:member-ref>UnreadMailsChanged</tp:member-ref> signal.</p>
+
+ <p>The most common situation, seen in protocols like MSN and Yahoo, is
+ that the number of unread mails is provided and kept up-to-date,
+ and a separate notification is emitted with some details of each new
+ mail. This is a combination of the following two features, and clients
+ SHOULD implement one or both as appropriate for their requirements.</p>
+
+ <p>On protocols that have the Emits_Mails_Received flag (which implies
+ that they do not have Supports_Unread_Mails), the CM does not keep
+ track of any mails; it simply emits a notification whenever new mail
+ arrives. Those events may be used for short term display (like a
+ notification popup) to inform the user. No protocol is known to support
+ only this feature, but it is useful for integration with libraries that
+ that do not implement tracking of the number of mails. Clients
+ requiring these notifications MUST monitor the
+ <tp:member-ref>MailsReceived</tp:member-ref> signal on any connections
+ with this flag.</p>
+
+ <p>On protocols that have the Supports_Unread_Mail_Count flag but not
+ the Supports_Unread_Mails flag, clients cannot display complete
+ details of unread email, but can display an up-to-date count of the
+ <em>number</em> of unread mails. To do this, they must monitor the
+ <tp:member-ref>UnreadMailsChanged</tp:member-ref> signal, and
+ retrieve the initial state from the
+ <tp:member-ref>UnreadMailCount</tp:member-ref> property.</p>
+
+ <p>
+ Orthogonal features described by the
+ <tp:member-ref>MailNotificationFlags</tp:member-ref> property include the
+ RequestSomethingURL methods, which are used to obtain URLs allowing
+ clients to open a webmail client. Connections SHOULD support as many
+ of these methods as possible.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
+
diff --git a/spec/spec/Connection_Interface_Power_Saving.xml b/spec/spec/Connection_Interface_Power_Saving.xml
new file mode 100644
index 000000000..571bf6d51
--- /dev/null
+++ b/spec/spec/Connection_Interface_Power_Saving.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Power_Saving"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ >
+ <tp:copyright> Copyright © 2007-2010 Collabora Limited </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface
+ name="org.freedesktop.Telepathy.Connection.Interface.PowerSaving">
+ <tp:added version="0.21.5">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Some protocols support mechanisms for reducing bandwidth usage—and
+ hence power usage, on mobile devices—when the user is not directly
+ interacting with their IM client. For instance, Google Talk's XMPP
+ server supports queueing incoming presence updates at the client's
+ instruction; the client can instruct the server to deliver all
+ outstanding presence updates at a later time. This interface may be
+ used to instruct the connection manager to enable and disable such
+ protocol-level features when a screensaver is activated, the device
+ screen is locked, and so on, by calling the
+ <tp:member-ref>SetPowerSaving</tp:member-ref> method.</p>
+
+ <p>Enabling power saving SHOULD NOT change behaviour in any way
+ that is noticable to a user not actively interacting with their client.
+ For example, delaying presence updates somewhat is unlikely to be
+ noticed by a user not staring at their device waiting for a contact to
+ come online; on the other hand, requesting that the server queue
+ incoming messages would be noticable by the user, so is not an
+ acceptable effect of calling
+ <tp:member-ref>SetPowerSaving</tp:member-ref>.</p>
+ </tp:docstring>
+
+ <method name="SetPowerSaving" tp:name-for-bindings="Set_Power_Saving">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Turn power saving mode on or off.</p>
+
+ <tp:rationale>
+ <p>Depending on the device's activity level, the
+ connection can have its power saving mode turned on or off.</p>
+ </tp:rationale>
+
+ <p>Errors raised by this method indicate that power saving could not be
+ enabled, which SHOULD NOT generally be treated as fatal.</p>
+
+ <tp:rationale>
+ If the CM cannot switch modes, either because of the
+ protocol (<code>NotImplemented</code>), or because of the service
+ (<code>NotAvailable</code>), Mission Control (or whoever manages this)
+ should be made aware. The error could be ignored or, in the extreme,
+ be fascist and disconnect the account.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Activate" type="b">
+ <tp:docstring>
+ <code>True</code> if protocol-level power saving features should be
+ activated; <code>False</code> if they should be de-activated.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The current connection has no power saving features.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="PowerSavingActive" type="b" access="read"
+ tp:name-for-bindings="Power_Saving_Active">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p><code>True</code> if protocol-level power saving features are
+ currently activated. This property can be changed using the
+ <tp:member-ref>SetPowerSaving</tp:member-ref> method; change
+ notifications is via the
+ <tp:member-ref>PowerSavingChanged</tp:member-ref> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="PowerSavingChanged"
+ tp:name-for-bindings="Power_Saving_Changed">
+ <arg name="Active" type="b">
+ <tp:docstring>
+ The new state of the power saving feature.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The <tp:member-ref>PowerSavingActive</tp:member-ref>
+ property changed.
+ </tp:docstring>
+ </signal>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Presence.xml b/spec/spec/Connection_Interface_Presence.xml
new file mode 100644
index 000000000..8a344d416
--- /dev/null
+++ b/spec/spec/Connection_Interface_Presence.xml
@@ -0,0 +1,346 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Presence" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>
+ Copyright (C) 2005, 2006 Collabora Limited
+ </tp:copyright>
+ <tp:copyright>
+Copyright (C) 2005, 2006 Nokia Corporation
+ </tp:copyright>
+ <tp:copyright>
+Copyright (C) 2006 INdT
+ </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Presence">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.SimplePresence"/>
+
+ <tp:mapping name="Multiple_Status_Map">
+ <tp:docstring>Mapping used in
+ <tp:type>Last_Activity_And_Statuses</tp:type> and passed to
+ <tp:member-ref>SetStatus</tp:member-ref>, representing a collection of
+ statuses. Use of this mapping with more than one member is
+ deprecated.</tp:docstring>
+ <tp:member type="s" name="Status"/>
+ <tp:member type="a{sv}" tp:type="String_Variant_Map" name="Parameters"/>
+ </tp:mapping>
+ <tp:struct name="Last_Activity_And_Statuses" array-name="">
+ <tp:docstring>Structure representing a contact's presence, containing
+ a last-activity time (deprecated) and a Multiple_Status_Map.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Unix_Timestamp" name="Last_Activity"/>
+ <tp:member type="a{sa{sv}}" tp:type="Multiple_Status_Map"
+ name="Statuses"/>
+ </tp:struct>
+ <tp:mapping name="Contact_Presences">
+ <tp:docstring>Mapping returned by
+ <tp:member-ref>GetPresence</tp:member-ref> and signalled by
+ <tp:member-ref>PresenceUpdate</tp:member-ref>, where the keys are
+ contacts and the values represent their presences.</tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact"/>
+ <tp:member type="(ua{sa{sv}})" tp:type="Last_Activity_And_Statuses"
+ name="Presence"/>
+ </tp:mapping>
+ <tp:struct name="Status_Spec" array-name="">
+ <tp:member type="u" tp:type="Connection_Presence_Type" name="Type"/>
+ <tp:member type="b" name="May_Set_On_Self"/>
+ <tp:member type="b" name="Exclusive"/>
+ <tp:member type="a{ss}" tp:type="String_String_Map"
+ name="Parameter_Types"/>
+ </tp:struct>
+ <tp:mapping name="Status_Spec_Map">
+ <tp:member type="s" name="Identifier"/>
+ <tp:member type="(ubba{ss})" tp:type="Status_Spec" name="Spec"/>
+ </tp:mapping>
+
+ <method name="AddStatus" tp:name-for-bindings="Add_Status">
+ <arg direction="in" name="Status" type="s">
+ <tp:docstring>
+ The string identifier of the desired status
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Parameters" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring>
+ A dictionary of optional parameter names mapped to their variant-boxed values
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that a single presence status is published for the user, along
+ with any desired parameters. Changes will be indicated by
+ <tp:member-ref>PresenceUpdate</tp:member-ref> signals being emitted.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+ <method name="ClearStatus" tp:name-for-bindings="Clear_Status">
+ <tp:docstring>
+ Request that all of a user's presence statuses be removed. Be aware
+ that this request may simply result in the statuses being replaced by a
+ default available status. Changes will be indicated by
+ <tp:member-ref>PresenceUpdate</tp:member-ref> signals being emitted.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+ <method name="GetPresence" tp:name-for-bindings="Get_Presence">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of the contacts whose presence should be obtained
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Presence" type="a{u(ua{sa{sv}})}"
+ tp:type="Contact_Presences">
+ <tp:docstring>
+ Presence information in the same format as for the
+ <tp:member-ref>PresenceUpdate</tp:member-ref> signal
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get presence previously emitted by
+ <tp:member-ref>PresenceUpdate</tp:member-ref> for the given contacts.
+ Data is returned in the same structure as the PresenceUpdate signal.
+ Using this method in favour of
+ <tp:member-ref>RequestPresence</tp:member-ref> has the advantage that
+ it will not wake up each client connected to the PresenceUpdate signal.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+ <method name="GetStatuses" tp:name-for-bindings="Get_Statuses">
+ <arg direction="out" type="a{s(ubba{ss})}" tp:type="Status_Spec_Map"
+ name="Available_Statuses">
+ <tp:docstring>
+ A dictionary of string identifiers mapped to a struct for each status, containing:
+ <ul>
+ <li>a type value from one of the values above</li>
+ <li>a boolean to indicate if this status may be set on yourself</li>
+ <li>a boolean to indicate if this is an exclusive status which you
+ may not set alongside any other</li>
+ <li>a dictionary of valid optional string argument names mapped to
+ their types</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get a dictionary of the valid presence statuses for this connection.
+ This is only available when online because only some statuses will
+ be available on some servers.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+ <signal name="PresenceUpdate" tp:name-for-bindings="Presence_Update">
+ <arg name="Presence" type="a{u(ua{sa{sv}})}" tp:type="Contact_Presences">
+ <tp:docstring>
+ A dictionary of contact handles mapped to a struct containing
+ a UNIX timestamp of the last activity time (in UTC), and
+ a dictionary mapping the contact's current status identifiers to
+ a dictionary of optional parameter names mapped to their
+ variant-boxed values
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ This signal should be emitted when your own presence has been changed,
+ or the presence of the member of any of the connection's channels has
+ been changed, or when the presence requested by
+ <tp:member-ref>RequestPresence</tp:member-ref> is available.
+ </tp:docstring>
+ </signal>
+ <method name="RemoveStatus" tp:name-for-bindings="Remove_Status">
+ <arg direction="in" name="Status" type="s">
+ <tp:docstring>
+ The string identifier of the status not to publish anymore for the user
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that the given presence status is no longer published for the
+ user. Changes will be indicated by
+ <tp:member-ref>PresenceUpdate</tp:member-ref> signals being emitted. As
+ with <tp:member-ref>ClearStatus</tp:member-ref>, removing a status may
+ actually result in it being replaced by a default available status.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>The status requested is not currently set</tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+ <method name="RequestPresence" tp:name-for-bindings="Request_Presence">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of the contacts whose presence should be obtained
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request the presence for contacts on this connection. A <tp:member-ref>PresenceUpdate</tp:member-ref>
+ signal will be emitted when they are received. This is not the same as
+ subscribing to the presence of a contact, which must be done using the
+ 'subscription' <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">ContactList</tp:dbus-ref>,
+ and on some protocols presence information may not be available unless
+ a subscription exists.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The presence of the requested contacts is not reported to this connection
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+ <method name="SetLastActivityTime"
+ tp:name-for-bindings="Set_Last_Activity_Time">
+ <arg direction="in" name="Time" type="u" tp:type="Unix_Timestamp">
+ <tp:docstring>
+ A UNIX timestamp of the user's last activity time (in UTC)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that the recorded last activity time for the user be updated on
+ the server.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ This protocol has no concept of idle time
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+ <method name="SetStatus" tp:name-for-bindings="Set_Status">
+ <arg direction="in" name="Statuses" type="a{sa{sv}}" tp:type="Multiple_Status_Map">
+ <tp:docstring>
+ A dictionary mapping status identifiers to dictionaries, which
+ map optional parameter names to their variant-boxed values
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the user's presence be changed to the given statuses
+ and desired parameters. Changes will be reflected by
+ <tp:member-ref>PresenceUpdate</tp:member-ref>
+ signals being emitted.</p>
+
+ <p>Statuses whose <tp:type>Connection_Presence_Type</tp:type>
+ is Offline, Error or Unknown MUST NOT be passed to this
+ function. Connection managers SHOULD reject these statuses.</p>
+
+ <tp:rationale>
+ <p>The same rationale as for <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">SimplePresence.SetPresence</tp:dbus-ref>
+ applies.</p>
+ </tp:rationale>
+
+ <p>On certain protocols, this method may be
+ called on a newly-created connection which is still in the
+ DISCONNECTED state, and will sign on with the requested status.
+ If the requested status is not available after signing on,
+ NotAvailable will be returned and the connection will remain
+ offline, or if the protocol does not support signing on with
+ a certain status, Disconnected will be returned.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:deprecated version="0.17.21">Client implementations
+ SHOULD use <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">SimplePresence</tp:dbus-ref>
+ instead.</tp:deprecated>
+ <tp:changed version="0.17.23">Connection managers implementing
+ Presence MUST implement SimplePresence too.</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+
+ <p>This interface is for services which have a concept of presence which
+ can be published for yourself and monitored on your contacts.
+ Telepathy's definition of presence is based on that used by
+ <a href="http://www.galago-project.org/">the Galago project</a>.</p>
+
+ <p>Presence on an individual (yourself or one of your contacts) is modelled as
+ a last activity time along with a set of zero or more statuses, each of
+ which may have arbitrary key/value parameters. Valid statuses are defined
+ per connection, and a list of them can be obtained with the
+ <tp:member-ref>GetStatuses</tp:member-ref> method.</p>
+
+ <p>(The SimplePresence interface which replaces this one restricts
+ presences to one status per contact, with an optional message, which is
+ in practice all that was implemented on this interface.)</p>
+
+ <p>Each status has an arbitrary string identifier which should have an agreed
+ meaning between the connection manager and any client which is expected to
+ make use of it. The well-known values defined by the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">SimplePresence</tp:dbus-ref>
+ interface SHOULD be used where possible</p>
+
+ <p>As well as these well-known status identifiers, every status also has a
+ numerical type value chosen from
+ <tp:type>Connection_Presence_Type</tp:type> which can be used by the client
+ to classify even unknown statuses into different fundamental types.</p>
+
+ <p>These numerical types exist so that even if a client does not understand
+ the string identifier being used, and hence cannot present the presence to
+ the user to set on themselves, it may display an approximation of the
+ presence if it is set on a contact.</p>
+
+ <p>The dictionary of variant types allows the connection manager to exchange
+ further protocol-specific information with the client. It is recommended
+ that the string (s) argument 'message' be interpreted as an optional
+ message which can be associated with a presence status.</p>
+
+ <p>If the connection has a 'subscribe' contact list,
+ <tp:member-ref>PresenceUpdate</tp:member-ref> signals should be emitted to
+ indicate changes of contacts on this list, and should also be emitted for
+ changes in your own presence. Depending on the protocol, the signal may
+ also be emitted for others such as people with whom you are communicating,
+ and any user interface should be updated accordingly.</p>
+
+ <p>On some protocols, <tp:member-ref>RequestPresence</tp:member-ref> may
+ only succeed on contacts on your 'subscribe' list, and other contacts will
+ cause a PermissionDenied error. On protocols where there is no 'subscribe'
+ list, and RequestPresence succeeds, a client may poll the server
+ intermittently to update any display of presence information.</p>
+ </tp:docstring>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Privacy.xml b/spec/spec/Connection_Interface_Privacy.xml
new file mode 100644
index 000000000..b89d968f4
--- /dev/null
+++ b/spec/spec/Connection_Interface_Privacy.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Privacy" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Privacy"
+ tp:causes-havoc='not well-tested'>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <method name="GetPrivacyMode" tp:name-for-bindings="Get_Privacy_Mode">
+ <arg direction="out" type="s">
+ <tp:docstring>
+ A string representing the current privacy mode
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Return the current privacy mode, which must be one of the values
+ returned by GetPrivacyModes.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+ <method name="GetPrivacyModes" tp:name-for-bindings="Get_Privacy_Modes">
+ <arg direction="out" type="as">
+ <tp:docstring>
+ An array of valid privacy modes for this connection
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Returns the privacy modes available on this connection. The following
+ well-known names should be used where appropriate:
+ <dl>
+ <dt>allow-all</dt><dd>any contact may initiate communication</dd>
+ <dt>allow-specified</dt><dd>only contacts on your 'allow' list may initiate communication</dd>
+ <dt>allow-subscribed</dt><dd>only contacts on your subscription list may initiate communication</dd>
+ </dl>
+ </tp:docstring>
+ </method>
+ <signal name="PrivacyModeChanged"
+ tp:name-for-bindings="Privacy_Mode_Changed">
+ <arg name="Mode" type="s">
+ <tp:docstring>
+ The current privacy mode
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the privacy mode is changed or the value has been
+ initially received from the server.
+ </tp:docstring>
+ </signal>
+ <method name="SetPrivacyMode" tp:name-for-bindings="Set_Privacy_Mode">
+ <arg direction="in" name="Mode" type="s">
+ <tp:docstring>
+ The desired privacy mode
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that the privacy mode be changed to the given value, which
+ must be one of the values returned by GetPrivacyModes. Success is
+ indicated by the method returning and the PrivacyModeChanged
+ signal being emitted.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ </tp:possible-errors>
+ </method>
+ <tp:docstring>
+ An interface to support getting and setting privacy modes to configure
+ situations such as not being contactable by people who are not on your
+ subscribe list. If this interface is not implemented, the default can be
+ presumed to be allow-all (as defined in GetPrivacyModes).
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Renaming.xml b/spec/spec/Connection_Interface_Renaming.xml
new file mode 100644
index 000000000..d08b748d9
--- /dev/null
+++ b/spec/spec/Connection_Interface_Renaming.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Renaming" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Renaming"
+ tp:causes-havoc='not well-tested'>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <signal name="Renamed" tp:name-for-bindings="Renamed">
+ <arg name="Original" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the original identifier
+ </tp:docstring>
+ </arg>
+ <arg name="New" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The handle of the new identifier
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the unique identifier of a contact on the server
+ changes.</p>
+
+ <p>Any channels associated with the contact's original handle will
+ continue to be to that handle, and so are no longer useful (unless
+ the contact renames back, or another contact connects with that
+ unique ID). Clients may open a similar channel associated with the
+ new handle to continue communicating with the contact.</p>
+
+ <p>For example, if a GUI client associates text
+ channels with chat windows, it should detach the old channel
+ from the chat window, closing it, and associate a channel to the
+ new handle with the same window.</p>
+
+ <p>If the contact's old handle is in any of the member lists of
+ a channel which has the groups interface, it will be removed from
+ the channel and the new handle will be added. The resulting
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.Group">MembersChanged</tp:dbus-ref>
+ signal must be emitted <em>after</em> the
+ <tp:member-ref>Renamed</tp:member-ref> signal; the reason should be
+ RENAMED.
+ </p>
+
+ <p>The handles may be either general-purpose or channel-specific.
+ If the original handle is general-purpose, the new handle must be
+ general-purpose; if the original handle is channel-specific, the
+ new handle must be channel-specific in the same channel.
+ </p>
+ </tp:docstring>
+ </signal>
+ <method name="RequestRename" tp:name-for-bindings="Request_Rename">
+ <arg direction="in" name="Identifier" type="s">
+ <tp:docstring>
+ The desired identifier
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the user's own identifier is changed on the server.
+ If successful, a <tp:member-ref>Renamed</tp:member-ref> signal will
+ be emitted for the current "self handle" as returned by <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">GetSelfHandle</tp:dbus-ref>.</p>
+ <p>It is protocol-dependent how the identifier that's actually
+ used will be derived from the supplied identifier; some sort of
+ normalization might take place.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+ <tp:docstring>
+ An interface on connections to support protocols where the unique
+ identifiers of contacts can change. Because handles are immutable,
+ this is represented by a pair of handles, that representing the
+ old name, and that representing the new one.
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Requests.xml b/spec/spec/Connection_Interface_Requests.xml
new file mode 100644
index 000000000..c8dc32804
--- /dev/null
+++ b/spec/spec/Connection_Interface_Requests.xml
@@ -0,0 +1,631 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Requests"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ >
+ <tp:copyright>Copyright (C) 2008 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Requests">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An enhanced version of the Telepathy connection interface, which can
+ represent bundles of channels that should be dispatched together, and
+ does not assume any particular properties by which channels are
+ uniquely identifiable.</p>
+
+ <p>If this interface is implemented on a connection, then
+ <tp:member-ref>NewChannels</tp:member-ref> MUST be emitted for
+ all new channels, even those created with <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection"
+ >RequestChannel</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <tp:struct name="Channel_Details" array-name="Channel_Details_List">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+
+ <tp:docstring>
+ Enough details of a channel that clients can work out how to dispatch
+ or handle it.
+ </tp:docstring>
+
+ <tp:member name="Channel" type="o">
+ <tp:docstring>
+ The object path of the channel.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Properties of the channel.</p>
+
+ <p>Connection managers MUST NOT include properties in this mapping
+ if their values can change. Clients MUST ignore properties
+ that appear in this mapping if their values can change.</p>
+
+ <tp:rationale>
+ <p>If properties that could change were included, the following
+ race condition would be likely to exist in some cases:</p>
+
+ <ul>
+ <li>NewChannels or Get("Channels") includes a property P with
+ value V1</li>
+ <li>Client creates a proxy object for the channel</li>
+ <li>The value of P changes to V2</li>
+ <li>Client connects to PChanged signal</li>
+ <li>Client should call Get("P") or GetAll here, to avoid the
+ race, but client's author has forgotten to do so</li>
+ <li>Proxy object thinks P == V1, but actually P == V2</li>
+ </ul>
+
+ <p>We've taken the opportunity to make the API encourage the
+ client author to get it right. Where possible, we intend that
+ properties whose value will be used in channel dispatching
+ or other "early" processing will be defined so that they are
+ immutable (can never change).</p>
+ </tp:rationale>
+
+ <p>Each dictionary MUST contain the keys
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.ChannelType</tp:dbus-ref>,
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetHandleType</tp:dbus-ref>,
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetHandle</tp:dbus-ref>,
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetID</tp:dbus-ref>
+ and
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.Requested</tp:dbus-ref>.
+ </p>
+
+ <tp:rationale>
+ <p>We expect these to be crucial to the channel-dispatching
+ process.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <method name="CreateChannel" tp:name-for-bindings="Create_Channel">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:changed version="0.17.14">It is now guaranteed that
+ CreateChannel returns the channel before NewChannels announces it
+ (the reverse was previously guaranteed).</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that an entirely new channel is created.</p>
+
+ <tp:rationale>
+ <p>There is deliberately no flag corresponding to the
+ suppress_handler argument to
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.RequestChannel</tp:dbus-ref>,
+ because passing a FALSE value for that argument is deprecated.
+ Requests made using this interface always behave as though
+ suppress_handler was TRUE.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+
+ <arg direction="in" name="Request" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties, which MUST include
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">ChannelType</tp:dbus-ref>.
+ Some properties
+ are defined such that only an exact match makes sense, and
+ connection managers MUST NOT satisfy a request with a channel
+ where that property does not match; some properties are defined
+ such that the connection manager MAY treat the request as merely
+ a hint, and make a best-effort attempt to satisfy it. This is
+ documented separately for each property.</p>
+
+ <p>If this dictionary contains a property whose semantics
+ are not known to the connection manager, this method MUST fail
+ without side-effects (in particular it must not create a new
+ channel).</p>
+
+ <tp:rationale>
+ <p>This is necessary if we want to be able to invent properties
+ in future that, when used in a request, are hard requirements
+ rather than just hints. A connection manager that did not know
+ the semantics of those properties could incorrectly return a
+ new channel that did not satisfy the requirements.</p>
+ </tp:rationale>
+
+ <p>The connection manager MUST NOT respond successfully,
+ and SHOULD NOT create a new channel or cause any other
+ side-effects, unless it can create a new channel that satisfies
+ the client's requirements.</p>
+
+ <p>Properties that will be set by this argument need not have write
+ access after the channel has been created - indeed, it is
+ expected that most will be read-only.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channel" direction="out" type="o">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The Channel object, which MUST NOT be signalled with
+ <tp:member-ref>NewChannels</tp:member-ref> until after this method
+ returns.</p>
+
+ <tp:rationale>
+ <p>This allows the requester to alter its handling of
+ NewChannels by knowing whether one of the channels satisfied
+ a request it made.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Properties" direction="out" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Properties of the channel that was produced, equivalent to
+ the properties in <tp:type>Channel_Details</tp:type>.
+ Connection managers MUST NOT include properties here whose
+ values can change, for the same reasons as in
+ <tp:type>Channel_Details</tp:type>.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The channel request was one that can never succeed,
+ such as requesting an unsupported channel type, or requesting
+ a channel type which this connection manager does not support with
+ the given target handle type.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ An invalid handle was requested as the value of a property whose
+ value is a handle (like
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.TargetHandle</tp:dbus-ref>),
+ or a syntactically invalid identifier was requested as the value
+ of a property whose value is the string corresponding to a handle
+ (like <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.TargetID</tp:dbus-ref>).
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The request matched the fixed properties of a
+ <tp:type>Requestable_Channel_Class</tp:type> in
+ <tp:member-ref>RequestableChannelClasses</tp:member-ref>, but the
+ allowed arguments did not make sense; for example, a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">RoomList</tp:dbus-ref>
+ was requested, but the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.RoomList">Server</tp:dbus-ref>
+ property provided was not a valid DNS name.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable">
+ <tp:docstring>
+ The requested channel cannot be created because the requested
+ contact is using a client that lacks a particular feature.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Offline">
+ <tp:docstring>
+ The requested channel cannot be created because the target is
+ offline.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The requested channel cannot be created, but in
+ principle, a similar request might succeed in future.
+ For instance, this might be because:</p>
+
+ <ul>
+ <li>a channel matching the request already exists and the
+ protocol requires that only one such channel can exist at a
+ time</li>
+ <li>a channel matching the request has already been requested
+ (by a previous call to CreateChannel,
+ <tp:member-ref>EnsureChannel</tp:member-ref>,
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.RequestChannel</tp:dbus-ref>
+ or similar) and the protocol requires that only one such
+ channel can exist at a time</li>
+ </ul>
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Banned"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Full"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.InviteOnly"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="EnsureChannel" tp:name-for-bindings="Ensure_Channel">
+ <tp:added version="0.17.12"/>
+ <tp:changed version="0.17.14">It is now guaranteed that if
+ the channel was created by this call to EnsureChannel, it's returned
+ before NewChannels announces it (the reverse was previously
+ guaranteed).</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that channels are ensured to exist.</p>
+
+ <tp:rationale>
+ <p>The connection manager is in the best position to determine which
+ existing channels could satisfy which requests.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+
+ <arg direction="in" name="Request" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary containing desirable properties, with the same
+ semantics as the corresponding parameter to
+ <tp:member-ref>CreateChannel</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Yours" direction="out" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>If false, the caller of EnsureChannel MUST assume that some
+ other process is handling this channel; if true, the caller of
+ EnsureChannel SHOULD handle it themselves or delegate it to another
+ client.</p>
+
+ <p>If the creation of a channel makes several calls to EnsureChannel
+ (and no other requests) successful, exactly one of those calls MUST
+ return a true value for this argument.</p>
+
+ <p>If the creation of a channel makes other requests successful,
+ the value returned for this argument MUST be such that exactly
+ one of the clients making requests ends up responsible for the
+ channel. In particular, if
+ <tp:member-ref>CreateChannel</tp:member-ref> returns a channel
+ <em>C</em>, any EnsureChannel calls that also return <em>C</em>
+ MUST return a false value for this argument.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Channel" direction="out" type="o">
+ <tp:docstring>
+ The Channel object. If it was created as a result of this method
+ call, it MUST NOT be signalled by
+ <tp:member-ref>NewChannels</tp:member-ref> until after this method
+ returns.
+
+ <tp:rationale>
+ <p>This allows the requester to alter its handling of
+ NewChannels by knowing whether one of the channels satisfied
+ a request it made.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <arg name="Properties" direction="out" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Properties of the channel that was produced, equivalent to
+ the properties in <tp:type>Channel_Details</tp:type>.
+ Connection managers MUST NOT include properties here whose
+ values can change, for the same reasons as in
+ <tp:type>Channel_Details</tp:type>.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The channel request was one that can never succeed,
+ such as requesting an unsupported channel type, or requesting
+ a channel type which this connection manager does not support with
+ the given target handle type.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle">
+ <tp:docstring>
+ An invalid handle was requested as the value of a property whose
+ value is a handle (like
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.TargetHandle</tp:dbus-ref>),
+ or a syntactically invalid identifier was requested as the value
+ of a property whose value is the string corresponding to a handle
+ (like <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Channel.TargetID</tp:dbus-ref>).
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The request matched the fixed properties of a
+ <tp:type>Requestable_Channel_Class</tp:type> in
+ <tp:member-ref>RequestableChannelClasses</tp:member-ref>, but the
+ allowed arguments did not make sense; for example, a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">RoomList</tp:dbus-ref>
+ was requested, but the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.RoomList">Server</tp:dbus-ref>
+ property provided was not a valid DNS name.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotCapable">
+ <tp:docstring>
+ The requested channel cannot be created because the requested
+ contact is using a client that lacks a particular feature.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Offline">
+ <tp:docstring>
+ The requested channel cannot be created because the target is
+ offline.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The requested channel cannot be created, but in
+ principle, a similar request might succeed in future.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Banned"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.Full"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.Channel.InviteOnly"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ </tp:possible-errors>
+ </method>
+
+ <signal name="NewChannels" tp:name-for-bindings="New_Channels">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:changed version="0.17.14">Added a guarantee of ordering
+ relative to NewChannel</tp:changed>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>New channels have been created. The connection manager SHOULD emit
+ a single signal for any group of closely related channels that are
+ created at the same time, so that the channel dispatcher can try to
+ dispatch them to a handler as a unit.</p>
+
+ <p>In particular, if additional channels are created as a side-effect
+ of a call to <tp:member-ref>CreateChannel</tp:member-ref>,
+ these channels SHOULD appear in the same NewChannels signal as
+ the channel that satisfies the request.</p>
+
+ <tp:rationale>
+ <p>Joining a MUC Tube in XMPP requires joining the corresponding
+ MUC (chatroom), so a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type">Text</tp:dbus-ref>
+ channel can be created as a side-effect.</p>
+ </tp:rationale>
+
+ <p>Every time NewChannels is emitted, it MUST be followed by
+ a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection.NewChannel</tp:dbus-ref>
+ signal for each channel.</p>
+
+ <tp:rationale>
+ <p>The double signal emission is for the benefit of older Telepathy
+ clients, which won't be listening for NewChannels.</p>
+
+ <p>The more informative NewChannels signal comes first so that
+ clients that did not examine the connection to find
+ out whether Requests is supported will see the more informative
+ signal for each channel first, and then ignore the less
+ informative signal because it announces a new channel of which
+ they are already aware.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Channels" type="a(oa{sv})" tp:type="Channel_Details[]">
+ <tp:docstring>
+ The channels and their details. All channels that are signalled
+ together like this MUST have the same
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.FUTURE">Bundle</tp:dbus-ref>
+ property, which may
+ either refer to an existing bundle, or establish a new bundle.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <property name="Channels" tp:name-for-bindings="Channels"
+ type="a(oa{sv})" access="read" tp:type="Channel_Details[]">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:docstring>
+ A list of all the channels which currently exist on this connection.
+ Change notification is via the
+ <tp:member-ref>NewChannels</tp:member-ref> and
+ <tp:member-ref>ChannelClosed</tp:member-ref> signals.
+ </tp:docstring>
+ </property>
+
+ <signal name="ChannelClosed" tp:name-for-bindings="Channel_Closed">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:docstring>
+ Emitted when a channel is closed and hence disappears from the
+ <tp:member-ref>Channels</tp:member-ref> property.
+
+ <tp:rationale>
+ This is redundant with the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel">Closed</tp:dbus-ref>
+ signal on the channel itself, but it does provide full change
+ notification for the Channels property.
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg name="Removed" type="o">
+ <tp:docstring>
+ The channel which has been removed from the Channels property
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:mapping name="Channel_Class" array-name="Channel_Class_List">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Mapping representing a class of channels that can be requested
+ from a connection manager, can be handled by a user interface,
+ are supported by a contact, etc.</p>
+
+ <p>Classes of channel are identified by the fixed values of
+ a subset of their properties.</p>
+
+ <p>Channel classes SHOULD always include the keys
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.ChannelType</tp:dbus-ref>
+ and
+ <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetHandleType</tp:dbus-ref>.
+ (One exception is that <tp:dbus-ref namespace="ofdT.Channel.Type"
+ >ContactSearch</tp:dbus-ref> channels do not have TargetHandleType
+ <code>None</code> in their requestable channel classes, for
+ historical reasons.)</p>
+ </tp:docstring>
+
+ <tp:member type="s" name="Key" tp:type="DBus_Qualified_Member">
+ <tp:docstring>
+ A D-Bus interface name, followed by a dot and a D-Bus property name.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="v" name="Value">
+ <tp:docstring>
+ The value of the property.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:struct name="Requestable_Channel_Class"
+ array-name="Requestable_Channel_Class_List">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Structure representing a class of channels that can be requested,
+ identified by a set of properties that identify that class of
+ channel.</p>
+
+ <tp:rationale>
+ <p>This will often just be the channel type and the handle type,
+ but can include other properties of the channel - for instance,
+ encrypted channels might require properties that
+ unencrypted channels do not, like an encryption key.</p>
+ </tp:rationale>
+
+ <p>In some cases, these classes of channel may overlap, in the sense
+ that one class fixes all the properties that another class does,
+ plus some more properties.</p>
+
+ <tp:rationale>
+ <p>For older clients to still be able to understand how to request
+ channels in the presence of a hypothetical "encryption" interface,
+ we'd need to represent it like this:</p>
+
+ <ul>
+ <li>class 1: ChannelType = Text, TargetHandleType = CONTACT</li>
+ <li>class 2: Channel.ChannelType = Text,
+ Channel.TargetHandleType = CONTACT,
+ Encryption.Encrypted = TRUE</li>
+ </ul>
+ </tp:rationale>
+ </tp:docstring>
+
+ <tp:member name="Fixed_Properties" type="a{sv}"
+ tp:type="Channel_Class">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The property values that identify this requestable channel class.
+ These properties MUST be included in requests for a channel of this
+ class, and MUST take these values.</p>
+
+ <p>Clients that do not understand the semantics of all the
+ Fixed_Properties MUST NOT request channels of this class, since
+ they would be unable to avoid making an incorrect request.</p>
+
+ <p>This implies that connection managers wishing to make channels
+ available to old or minimal clients SHOULD have a channel class
+ with the minimum number of Fixed_Properties, and MAY additionally
+ have channel classes with extra Fixed_Properties.</p>
+
+ <p>Interface designers SHOULD avoid introducing fixed properties
+ whose types are not serializable in a <code>.manager</code>
+ file.</p>
+
+ <tp:rationale>
+ <p>Connection managers with a fixed property that is not
+ serializable cannot have a complete <code>.manager</code>
+ file.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Allowed_Properties" type="as"
+ tp:type="DBus_Qualified_Member[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Properties that MAY be set when requesting a channel of this
+ channel type and handle type.</p>
+
+ <p>This array MUST NOT include properties that are in the
+ Fixed_Properties mapping.</p>
+
+ <p>Properties in this array may either be required or optional,
+ according to their documented semantics.</p>
+
+ <tp:rationale>
+ <p>For instance, if
+ TargetHandleType takes a value that is not Handle_Type_None,
+ one or the other of TargetHandle and TargetID is required.
+ Clients are expected to understand the documented relationship
+ between the properties, so we do not have separate arrays
+ of required and optional properties.</p>
+ </tp:rationale>
+
+ <p>If this array contains the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.FUTURE">Bundle</tp:dbus-ref>
+ property, then this class of channel can be combined with other
+ channels with that property in a request, or added to an existing
+ bundle. If not, this signifies that the connection manager is
+ unable to mark channels of this class as part of a bundle - this
+ means that to the remote contact they are likely to be
+ indistinguishable from channels requested separately.</p>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="RequestableChannelClasses" access="read"
+ type="a(a{sv}as)" tp:type="Requestable_Channel_Class[]"
+ tp:name-for-bindings="Requestable_Channel_Classes">
+ <tp:added version="0.17.11">(as stable API)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The classes of channel that are expected to be available on this
+ connection, i.e. those for which
+ <tp:member-ref>CreateChannel</tp:member-ref> can reasonably
+ be expected to succeed. User interfaces can use this information
+ to show or hide UI components.</p>
+
+ <p>This property cannot change after the connection has gone to
+ state Connection_Status_Connected, so there is no change
+ notification (if the connection has context-dependent capabilities,
+ it SHOULD advertise support for all classes of channel that it might
+ support during its lifetime). Before this state has been reached,
+ the value of this property is undefined.</p>
+
+ <tp:rationale>
+ <p>This is not on an optional interface, because connection
+ managers can always offer some sort of clue about the channel
+ classes they expect to support (at worst, they can announce
+ support for everything for which they have code).</p>
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Resources.xml b/spec/spec/Connection_Interface_Resources.xml
new file mode 100644
index 000000000..716089cd6
--- /dev/null
+++ b/spec/spec/Connection_Interface_Resources.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Resources"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.Resources.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.1">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface on connections to show contact attributes for
+ specific resources of a contact, if the protocol supports
+ multiple resources. Resources are most common in XMPP, hence the
+ name of this interface, but they are also present in MSN, where
+ they are called points of presence.</p>
+
+ <p>When a client requests some attribute of a contact using its
+ handle on the connection, the CM uses an algorithm to choose the
+ most appropriate resource for the job. If there is only one
+ resource, then the choice is obvious. If, however, there is more
+ than one resource connected at any one time, the CM either
+ aggregates all appropriate information to return (in the case of
+ capabilities), or chooses one specific resource (in the case of
+ presence).</p>
+
+ <p>Resources in XMPP have names, and it can be extremely useful
+ for the user to be able to know which resources of a contact are
+ online, providing the names are human-readable. Before now,
+ resources have not been exposed in Telepathy, but this interface
+ attempts to change this.</p>
+
+ <p>When using this interface, it is a little like using the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface"
+ >Contacts</tp:dbus-ref> interface, but only resource-specific
+ attributes are ever returned. The resource-specific contact
+ attributes are decided on by the CM, but XMPP's are listed
+ below:</p>
+
+ <ul>
+ <li><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">SimplePresence/presence</tp:dbus-ref></li>
+ <li><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">ContactCapabilities/capabilities</tp:dbus-ref></li>
+ <li><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">ClientTypes/client-types</tp:dbus-ref></li>
+ </ul>
+
+ </tp:docstring>
+
+ <method name="GetResources" tp:name-for-bindings="Get_Resources">
+ <tp:docstring>
+ Return the resource information of the given contacts. If any
+ of the contact attributes for specific resources of the given
+ contacts' are not known return immediately without waiting for
+ a reply.
+ </tp:docstring>
+
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ The contacts whose resource attributes should be returned.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Resources" type="a{ua{sa{sv}}}"
+ tp:type="Resources_Attributes_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The contacts' resources and the contact attributes specific
+ to each resource. If contact attributes are not immediately
+ known, the behaviour is defined by the interface; the
+ attribute should either be omitted from the result or
+ replaced with a default value.</p>
+
+ <p>For every contact handle passed into this method, it is
+ guaranteed that there will be a key in the returned map
+ that corresponds to said handle. If there is no information
+ regarding the contact the resource information map will be
+ empty.</p>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ </tp:possible-errors>
+ </method>
+
+ <tp:enum name="Resources_Human_Readability" type="u">
+ <tp:enumvalue suffix="Never" value="0">
+ <tp:docstring>
+ The resource string is never human-readable.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Maybe" value="1">
+ <tp:docstring>
+ The resource string might be human-readable.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <property name="ResourcesHumanReadable" type="u" access="read"
+ tp:type="Resources_Human_Readability"
+ tp:name-for-bindings="Resources_Human_Readable">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Whether the resources returned from <tp:member-ref>GetResources</tp:member-ref>
+ are human readable or not.</p>
+
+ <p>If the connection manager knows that all resource names are
+ automatically generated, then the resource strings mean
+ nothing to the user. Showing these strings in the UI would
+ be confusing, so by setting this to
+ Resources_Human_Readability_Never, the UI is advised not to
+ show resources.</p>
+
+ <p>If on the other hand, all resources are set to nice names
+ (such as "office" or "home") then it might be wise to expose
+ these strings in the UI, so this property would be set to
+ Resources_Human_Readability_Maybe. This is the case in XMPP --
+ most resources are set in a way that the user can deduce some
+ information from them. The absence of an Always enum value is
+ because in the case of XMPP, the resource string could be
+ partially human-readable (as on Google Talk, where a resource
+ of "home" is changed by the server to a unique string like
+ "home_1234fdec") or not at all human-readable.</p>
+
+ </tp:docstring>
+ </property>
+
+ <signal name="ResourcesUpdated" tp:name-for-bindings="Resources_Updated">
+ <tp:docstring>
+ Emitted when a contact has a resource added or removed, or any
+ contact attribute for any resource changes.
+ </tp:docstring>
+
+ <arg name="Contact" type="u" tp:type="Contact_Handle">
+ <tp:docstring>
+ The contact.
+ </tp:docstring>
+ </arg>
+ <arg name="Resources" tp:type="Resource_Information_Map"
+ type="a{sa{sv}}">
+ <tp:docstring>
+ The contact's resource information. All resource information
+ is given, not just the details which have changed.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:mapping name="Resource_Information_Map">
+ <tp:docstring>
+ A map of a contact's resources to their resource-specific
+ information.
+ </tp:docstring>
+
+ <tp:member name="Key" type="s">
+ <tp:docstring>
+ <p>The name of the resource.</p>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Contact_Attributes" type="a{sv}"
+ tp:type="Single_Contact_Attributes_Map">
+ <tp:docstring>
+ A map of contact attributes whose data is specific to this
+ resource.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:mapping name="Resources_Attributes_Map">
+ <tp:docstring>Mapping returned by
+ <tp:member-ref>GetResources</tp:member-ref>, representing a
+ collection of Contacts, their resources, and their
+ resource-specific contact attributes.</tp:docstring>
+
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact">
+ <tp:docstring>
+ A contact.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="a{sa{sv}}" tp:type="Resource_Information_Map"
+ name="Resources">
+ <tp:docstring>
+ A map of the contact's resources to their resource-specific
+ information.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:contact-attribute name="resources" type="a{sa{sv}}"
+ tp:type="Resource_Information_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same mapping that would be returned by
+ <tp:member-ref>GetResources</tp:member-ref> for this contact.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Service_Point.xml b/spec/spec/Connection_Interface_Service_Point.xml
new file mode 100644
index 000000000..b135c04c7
--- /dev/null
+++ b/spec/spec/Connection_Interface_Service_Point.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Service_Point" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright © 2005-2010 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright © 2005-2010 Collabora Ltd </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ServicePoint">
+ <tp:added version="0.19.7">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connections whose channels may be able to indicate
+ specific they are connected to some form
+ of service station. For example, when
+ dialing 9-1-1 in the US, a GSM modem/network will recognize that as
+ an emergency call, and inform higher levels of the stack that the
+ call is being handled by an emergency service. In this example,
+ the call is handled by a Public Safety Answering Point (PSAP) which is labeled
+ as "urn:service:sos". Other networks and protocols may handle this
+ differently while still using this interface.</p>
+ </tp:docstring>
+
+ <tp:struct name="Service_Point_Info" array-name="Service_Point_Info_List">
+ <tp:member type="(us)" tp:type="Service_Point" name="Service_Point">
+ <tp:docstring>
+ The service point.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="as" name="Service_IDs">
+ <tp:docstring>
+ A list of IDs that are mapped to this service. This is provided as
+ a convenience for the UIs, but the preferred method for
+ requesting channel to a service is by setting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Interface.ServicePoint">InitialServicePoint</tp:dbus-ref>
+ property in a channel request.
+ </tp:docstring>
+ </tp:member>
+ <tp:docstring>
+ <p>Description of a service point and IDs which are mapped to it.</p>
+
+ <p>An example Service Point info for GSM emergency calls (callable
+ through "911" and "112") could look like:</p>
+
+<pre>
+ ServicePointInfo = (
+ Service_Point: (
+ Service_Point_Type: 1 (Emergency),
+ Service_Point: "urn:service:sos"
+ ),
+ Service_IDs: [ "911", "112" ]
+ )
+</pre>
+ </tp:docstring>
+ </tp:struct>
+
+ <property name="KnownServicePoints" tp:name-for-bindings="Known_Service_Points"
+ type="a((us)as)" tp:type="Service_Point_Info[]" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The list of all (known) service points.
+ </tp:docstring>
+ </property>
+
+ <signal name="ServicePointsChanged" tp:name-for-bindings="Service_Points_Changed">
+ <arg name="Service_Points" type="a((us)as)" tp:type="Service_Point_Info[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The new value of
+ <tp:member-ref>KnownServicePoints</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the list of known service points (or their IDs) has
+ changed.
+ </tp:docstring>
+ </signal>
+
+ <tp:struct name="Service_Point">
+ <tp:docstring>A service point.</tp:docstring>
+ <tp:member type="u" name="Service_Point_Type"
+ tp:type="Service_Point_Type">
+ <tp:docstring>
+ The service type.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Service">
+ <tp:docstring>
+ String representation of the service point. The representation is
+ service specific; it may be a 'service' Uniform Resource Name as
+ specified by <a
+ href="http://www.rfc-editor.org/rfc/rfc5031.txt">RFC 5031</a>,
+ or may be in some other form. Empty, unused or unknown value is
+ represented by "".
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:enum name="Service_Point_Type" type="u">
+ <tp:docstring>
+ The various types of service points a channel might connect to.
+ </tp:docstring>
+
+ <tp:enumvalue value="0" suffix="None">
+ <tp:docstring>
+ The channel is not communicating with a service point, or it is not
+ known whether it is communicating with a service point (e.g. an
+ ordinary call).
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="1" suffix="Emergency">
+ <tp:docstring>
+ The service point is a generic emergency point.
+ </tp:docstring>
+ </tp:enumvalue>
+
+ <tp:enumvalue value="2" suffix="Counseling">
+ <tp:docstring>
+ The service point is some kind of counseling service (ie, mental health
+ or child-services counseling).
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Interface_Simple_Presence.xml b/spec/spec/Connection_Interface_Simple_Presence.xml
new file mode 100644
index 000000000..0860f5fea
--- /dev/null
+++ b/spec/spec/Connection_Interface_Simple_Presence.xml
@@ -0,0 +1,695 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Interface_Simple_Presence" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005-2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.SimplePresence">
+ <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
+
+ <tp:struct name="Simple_Presence">
+ <tp:docstring>
+ A struct representing the presence of a contact.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Connection_Presence_Type" name="Type">
+ <tp:docstring>
+ The presence type, e.g. Connection_Presence_Type_Away.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Status">
+ <tp:docstring>
+ The string identifier of the status, e.g. "brb", as defined in the
+ <tp:member-ref>Statuses</tp:member-ref> property.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Status_Message">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The user-defined status message, e.g. "Back soon!".</p>
+
+ <p>Clients SHOULD set the status message for the local
+ user to the empty string, unless the user has actually provided
+ a specific message (i.e. one that conveys more information than the
+ Status).</p>
+
+ <p>User interfaces SHOULD regard an empty status message as unset,
+ and MAY replace it with a localized string corresponding to the
+ Status or Type.</p>
+
+ <tp:rationale>
+ Use case: Daf sets his status in Empathy by choosing the Welsh
+ translation of "Available" from a menu.
+ It is more informative for his English-speaking colleagues
+ to see the English translation of "Available" (as localized
+ by their own clients) than to see "Ar Gael" (which they don't
+ understand anyway).
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Simple_Contact_Presences">
+ <tp:docstring>
+ Mapping returned by <tp:member-ref>GetPresences</tp:member-ref>
+ and signalled by <tp:member-ref>PresencesChanged</tp:member-ref>,
+ indicating the presence of a number of contacts.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Contact_Handle" name="Contact">
+ <tp:docstring>
+ A contact
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="(uss)" tp:type="Simple_Presence" name="Presence">
+ <tp:docstring>
+ The contact's presence
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:struct name="Simple_Status_Spec">
+ <tp:docstring>
+ A struct containing information about a status.
+ </tp:docstring>
+ <tp:member type="u" tp:type="Connection_Presence_Type" name="Type">
+ <tp:docstring>
+ The type of a presence. This SHOULD NOT be used as a way to set
+ statuses that the client does not recognise (as explained in
+ <tp:member-ref>SetPresence</tp:member-ref>), but MAY be used to check
+ that the client's assumptions about a particular status name
+ match the connection manager's.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="b" name="May_Set_On_Self">
+ <tp:docstring>
+ If true, the user can set this status on themselves using
+ <tp:member-ref>SetPresence</tp:member-ref>.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="b" name="Can_Have_Message">
+ <tp:docstring>
+ If true, a non-empty message can be set for this status. Otherwise,
+ the empty string is the only acceptable message.
+
+ <tp:rationale>
+ On IRC you can be Away with a status message, but if you are
+ available you cannot set a status message.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="Simple_Status_Spec_Map">
+ <tp:docstring>
+ A mapping describing possible statuses.
+ </tp:docstring>
+
+ <tp:member type="s" name="Identifier">
+ <tp:docstring>
+ The string identifier of this status.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="(ubb)" tp:type="Simple_Status_Spec" name="Spec">
+ <tp:docstring>
+ Details of this status.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <method name="SetPresence" tp:name-for-bindings="Set_Presence">
+ <arg direction="in" name="Status" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The string identifier of the desired status. Possible status
+ identifiers are defined in the
+ <tp:member-ref>Statuses</tp:member-ref> property.</p>
+
+ <p>Clients MUST NOT set a status whose string value they do not
+ recognise, even if its presence type in Statuses
+ matches what the user requested.</p>
+
+ <tp:rationale>
+ <p>Suppose a protocol has statuses that include 'phone' (of type
+ BUSY) and 'in-a-meeting' (of type BUSY), but there is no
+ generic 'busy' status.</p>
+
+ <p>If the user requests "Busy" status from a menu, a
+ client author might be tempted to pick an arbitrary status
+ that has type BUSY. However, on this protocol, neither of
+ the choices would be appropriate, and incorrect information
+ about the user would be conveyed.</p>
+ </tp:rationale>
+
+ <p>Statuses whose <tp:type>Connection_Presence_Type</tp:type>
+ is Offline, Error or Unknown MUST NOT be passed to this
+ function. Connection managers SHOULD reject these statuses.</p>
+
+ <tp:rationale>
+ <p>To go offline, call <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">Disconnect</tp:dbus-ref>
+ instead. The "error" and "unknown" statuses make no sense.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Status_Message" type="s">
+ <tp:docstring>
+ The status message associated with the current status.
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request that the presence status and status message are published for
+ the connection. Changes will be indicated by
+ <tp:member-ref>PresencesChanged</tp:member-ref>
+ signals being emitted.</p>
+
+ <p>This method may be called on a newly-created connection while it
+ is still in the DISCONNECTED state, to request that when the
+ connection connects, it will do so with the selected status.</p>
+
+ <p>In DISCONNECTED state the
+ <tp:member-ref>Statuses</tp:member-ref>
+ property will indicate which statuses are allowed to be set
+ while DISCONNECTED (none, if the Connection Manager doesn't allow
+ this). This value MUST NOT be cached, as the set of allowed
+ presences might change upon connecting.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Either the specified status is not supported, the specified
+ status cannot be set on the user themselves, or a non-empty
+ message was supplied for a status that does not
+ accept a message.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <method name="GetPresences" tp:name-for-bindings="Get_Presences">
+ <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
+ <tp:docstring>
+ An array of the contacts whose presence should be obtained.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Presence" type="a{u(uss)}"
+ tp:type="Simple_Contact_Presences">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Presence information in the same format as for the
+ <tp:member-ref>PresencesChanged</tp:member-ref> signal.
+ The returned mapping MUST include an entry for each contact
+ in the method's argument.</p>
+
+ <p>The definition of the connection presence types Unknown
+ and Offline means that if a connection manager will return
+ Unknown for contacts not on the subscribe list, it MUST delay
+ the reply to this method call until it has found out which
+ contacts are, in fact, on the subscribe list.</p>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get presence previously emitted by
+ <tp:member-ref>PresencesChanged</tp:member-ref> for the given
+ contacts. Data is returned in the same structure as the
+ PresencesChanged signal; no additional network requests are made.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError">
+ <tp:docstring>
+ While discovering the subscribe list in order to distinguish
+ between Unknown and Offline statuses, a network error occurred.
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ </tp:possible-errors>
+ </method>
+
+ <property name="Statuses" tp:name-for-bindings="Statuses" access="read"
+ type="a{s(ubb)}" tp:type="Simple_Status_Spec_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A dictionary where the keys are the presence statuses that are
+ available on this connection, and the values are the corresponding
+ presence types.</p>
+
+ <p>While the connection is in the DISCONNECTED state, it contains
+ the set of presence statuses allowed to be set before connecting.
+ The connection manager will attempt to set the appropriate status
+ when the connection becomes connected, but cannot necessarily
+ guarantee it. The available statuses cannot change until the
+ connection status changes, so there is no change notification.</p>
+
+ <p>While the connection is in the CONNECTED state, this property
+ contains the set of presence statuses which are actually available
+ on this protocol. This set is constant for the remaining lifetime
+ of the connection, so again, there is no change notification.</p>
+
+ <p>While the connection is in the CONNECTING state, the value of
+ this property is undefined and SHOULD NOT be used. It can change
+ at any time without notification (in particular, any cached values
+ from when the connection was in the DISCONNECTED or CONNECTING
+ state MUST NOT be assumed to still be correct when the state has
+ become CONNECTED).</p>
+
+ <p>This property MUST include the special statuses "unknown" and
+ "error" if and only if the connection manager can emit them
+ as a contact's status.</p>
+
+ <tp:rationale>
+ For instance, connection managers for local-xmpp (XEP-0174) would
+ omit "unknown" since there is no such concept.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumStatusMessageLength"
+ tp:name-for-bindings="Maximum_Status_Message_Length" access="read"
+ type="u">
+ <tp:added version="0.22.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The maximum length in characters for any individual status
+ message, or 0 if there is no limit.</p>
+
+ <p>While the connection is in the DISCONNECTED state, this property will
+ be 0. The connection manager will attempt to set the appropriate value
+ when the connection becomes connected, but cannot necessarily
+ guarantee it. The maximum length cannot change until the
+ connection status changes, so there is no change notification.</p>
+
+ <p>While the connection is in the CONNECTED state, this property
+ contains the maximum length in characters for any individual status
+ message which is actually allowed on this protocol.
+ This value is constant for the remaining lifetime
+ of the connection, so again, there is no change notification.</p>
+
+ <p>While the connection is in the CONNECTING state, the value of
+ this property is undefined and SHOULD NOT be used. It can change
+ at any time without notification (in particular, any cached values
+ from when the connection was in the DISCONNECTED or CONNECTING
+ state MUST NOT be assumed to still be correct when the state has
+ become CONNECTED).</p>
+
+ <p>If a message passed to <tp:member-ref>SetPresence</tp:member-ref> is
+ longer than allowed by this property, the connection manager MUST
+ truncate the supplied message; when emitting
+ <tp:member-ref>PresencesChanged</tp:member-ref>, the truncated version
+ of the message MUST be used.</p>
+
+ <tp:rationale>
+ <p>Some XMPP servers, like Google Talk, define a maximum length for
+ status messages. Whether the user's server is one of
+ these cannot be detected until quite late in the connection
+ process.</p>
+ </tp:rationale>
+
+ </tp:docstring>
+ </property>
+
+ <signal name="PresencesChanged" tp:name-for-bindings="Presences_Changed">
+ <arg name="Presence" type="a{u(uss)}" tp:type="Simple_Contact_Presences">
+ <tp:docstring>
+ A dictionary of contact handles mapped to the status,
+ presence type and status message.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ This signal should be emitted when your own presence has been changed,
+ or the presence of the member of any of the connection's channels has
+ been changed.
+ </tp:docstring>
+ </signal>
+
+ <tp:enum name="Connection_Presence_Type" type="u">
+ <tp:enumvalue suffix="Unset" value="0">
+ <tp:docstring>
+ An invalid presence type used as a null value. This value MUST NOT
+ appear in the <tp:member-ref>Statuses</tp:member-ref> property,
+ or in the result of <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Presence">GetStatuses</tp:dbus-ref>
+ on the deprecated <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Presence</tp:dbus-ref>
+ interface.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Offline" value="1">
+ <tp:docstring>
+ Offline
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Available" value="2">
+ <tp:docstring>
+ Available
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Away" value="3">
+ <tp:docstring>
+ Away
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Extended_Away" value="4">
+ <tp:docstring>
+ Away for an extended time
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Hidden" value="5">
+ <tp:docstring>
+ Hidden (invisible)
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Busy" value="6">
+ <tp:added version="0.17.0"/>
+ <tp:docstring>
+ Busy, Do Not Disturb.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Unknown" value="7">
+ <tp:added version="0.17.8"/>
+ <tp:docstring>
+ Unknown, unable to determine presence for this contact, for example
+ if the protocol only allows presence of subscribed contacts.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Error" value="8">
+ <tp:added version="0.17.8"/>
+ <tp:docstring>
+ Error, an error occurred while trying to determine presence. The
+ message, if set, is an error from the server.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Access_Control_Type" type="u"
+ array-name="Access_Control_Type_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A type for communication access control. These control
+ policies are used in
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">CommunicationPolicy.DRAFT</tp:dbus-ref>
+ as well as most rich presence interfaces.</p>
+
+ <p>New interfaces should use this type, and NOT
+ <tp:type>Rich_Presence_Access_Control_Type</tp:type>.</p>
+ </tp:docstring>
+ <tp:enumvalue suffix="Whitelist" value="0">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Only allow contacts that are in a certain whitelist.</p>
+
+ <p>The associated variant
+ in <tp:type>Access_Control</tp:type> is a list of
+ <tp:type>Contact_Handle</tp:type> representing
+ the whitelist, with signature <code>au</code>.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Publish_List" value="1">
+ <tp:docstring>
+ Allow contacts in the user's 'publish' list. The associated
+ variant in <tp:type>Access_Control</tp:type> is ignored.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Group" value="2">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Only allow contacts that are in a certain group.</p>
+
+ <p>The associated variant in <tp:type>Access_Control</tp:type> is a
+ <tp:type>Group_Handle</tp:type> representing the permitted
+ group.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Open" value="3">
+ <tp:docstring>
+ Allow all contacts. The associated
+ variant in <tp:type>Access_Control</tp:type> is ignored.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Subscribe_Or_Publish_List" value="4">
+ <tp:docstring>
+ Allow all contacts in the user's 'subscribe' or 'publish'
+ list. The associated variant in <tp:type>Access_Control</tp:type> is
+ ignored.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Closed" value="5">
+ <tp:docstring>
+ Forbid all contacts. The associated variant in
+ <tp:type>Access_Control</tp:type> is ignored.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Not_Understood" value="6">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The access control rule is too complex to be represented
+ in the current Telepathy API. The associated variant is
+ meaningless. Setting this mode is never valid; the
+ connection manager MUST raise an error if this is attempted.</p>
+
+ <tp:rationale>
+ XEP-0016 Privacy Lists can easily produce access control
+ mechanisms that can't be expressed in a simpler API. We
+ need to be able to at least indicate that fact.
+ </tp:rationale>
+
+ <p>The associated variant in <tp:type>Access_Control</tp:type> is
+ ignored.</p>
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:enum name="Rich_Presence_Access_Control_Type" type="u"
+ array-name="Rich_Presence_Access_Control_Type_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A type of access control for Rich_Presence_Access_Control.
+ For most types, the exact access control is given by an associated
+ variant.</p>
+
+ <tp:rationale>
+ <p>These are the access control types from XMPP publish/subscribe
+ (XEP-0060).</p>
+ </tp:rationale>
+
+ <p><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Location</tp:dbus-ref>
+ uses this for historical reasons, new interfaces will use
+ <tp:type>Access_Control_Type</tp:type>.</p>
+ </tp:docstring>
+
+ <tp:enumvalue suffix="Whitelist" value="0">
+ <tp:docstring>
+ The associated variant is a list of contacts (signature 'au',
+ Contact_Handle[]) who can see the extended presence information.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Publish_List" value="1">
+ <tp:docstring>
+ All contacts in the user's 'publish' contact list can see the
+ extended presence information. The associated variant is ignored.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Group" value="2">
+ <tp:docstring>
+ The associated variant is a handle of type Group (signature 'u',
+ Group_Handle) representing a group of contacts who can see the
+ extended presence information.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Open" value="3">
+ <tp:docstring>
+ Anyone with access to the service can see the extended presence
+ information.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Access_Control">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An access control mode for extended presence items like geolocation.
+ This type isn't actually used by the SimplePresence interface, but
+ it's included here so it can be referenced by rich presence
+ interfaces.</p>
+
+ <p>New interfaces should use this type, and NOT
+ <tp:type>Rich_Presence_Access_Control</tp:type>.</p>
+ </tp:docstring>
+
+ <tp:member name="Type" type="u" tp:type="Access_Control_Type">
+ <tp:docstring>
+ The type of access control to apply.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Detail" type="v">
+ <tp:docstring>
+ Any additional information required by the Type. The required
+ type and semantics are defined for each
+ <tp:type>Access_Control_Type</tp:type>.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Rich_Presence_Access_Control">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An access control mode for extended presence items like geolocation.
+ This type isn't actually used by the SimplePresence interface, but
+ it's included here so it can be referenced by rich presence interfaces
+ such as <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Location</tp:dbus-ref>.</p>
+
+ <p><tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Location</tp:dbus-ref>
+ uses this for historical reasons, new interfaces will use
+ <tp:type>Access_Control_Type</tp:type>.</p>
+ </tp:docstring>
+
+ <tp:member name="Type" type="u" tp:type="Rich_Presence_Access_Control_Type">
+ <tp:docstring>
+ The type of access control to apply.
+ </tp:docstring>
+ </tp:member>
+ <tp:member name="Detail" type="v">
+ <tp:docstring>
+ Any additional information required by the Type. The required
+ type and semantics are defined for each
+ <tp:type>Rich_Presence_Access_Control_Type</tp:type>.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:contact-attribute name="presence"
+ type="(uss)" tp:type="Simple_Presence">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same struct that would be returned by
+ <tp:member-ref>GetPresences</tp:member-ref>
+ (always present with some value if information from the
+ SimplePresence interface was requested)</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This interface is for services which have a concept of presence which
+ can be published for yourself and monitored on your contacts.</p>
+
+ <p>Presence on an individual (yourself or one of your contacts) is
+ modelled as a status and a status message. Valid statuses are defined
+ per connection, and a list of those that can be set on youself
+ can be obtained from the
+ <tp:member-ref>Statuses</tp:member-ref>
+ property.</p>
+
+ <p>Each status has an arbitrary string identifier which should have an
+ agreed meaning between the connection manager and any client which is
+ expected to make use of it. The following well-known values should be
+ used where possible to allow clients to identify common choices:</p>
+
+ <table>
+ <tr>
+ <th>Status identifier</th>
+ <th><tp:type>Connection_Presence_Type</tp:type></th>
+ <th>Remarks</th>
+ </tr>
+ <tr>
+ <td><code>"available"</code></td>
+ <td>Available</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>"chat"</code></td>
+ <td>Available</td>
+ <td>Actively interested in chatting, as opposed to merely
+ available.</td>
+ </tr>
+ <tr>
+ <td><code>"pstn"</code></td>
+ <td>Available</td>
+ <td>This contact is actually a phone number, not an IM account. As
+ such, the contact is conceptually always available, but not in the
+ same way that a contact can set their IM status to “available”.
+ It does not make sense to allow the user to set this status on
+ herself; hence, on protocols where this status is supported, its
+ entry in <tp:member-ref>Statuses</tp:member-ref> SHOULD have
+ <var>May_Set_On_Self</var> set to <code>False</code>.</td>
+ </tr>
+ <tr>
+ <td><code>"away"</code></td>
+ <td>Away</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>"brb"</code></td>
+ <td>Away</td>
+ <td>Be Right Back (a more specific form of Away)</td>
+ </tr>
+ <tr>
+ <td><code>"busy"</code></td>
+ <td>Busy</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>"dnd"</code></td>
+ <td>Busy</td>
+ <td>Do Not Disturb (a more specific form of Busy)</td>
+ </tr>
+ <tr>
+ <td><code>"xa"</code></td>
+ <td>Extended_Away</td>
+ <td>Extended Away</td>
+ </tr>
+ <tr>
+ <td><code>"hidden"</code></td>
+ <td>Hidden</td>
+ <td>Also known as "Invisible" or "Appear Offline"</td>
+ </tr>
+ <tr>
+ <td><code>"offline"</code></td>
+ <td>Offline</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><code>"unknown"</code></td>
+ <td>Unknown</td>
+ <td>special, see below</td>
+ </tr>
+ <tr>
+ <td><code>"error"</code></td>
+ <td>Error</td>
+ <td>special, see below</td>
+ </tr>
+ </table>
+
+ <p>As well as these well-known status identifiers, every status also has
+ a numerical type value chosen from
+ <tp:type>Connection_Presence_Type</tp:type> which can be
+ used by the client to classify even unknown statuses into different
+ fundamental types.</p>
+
+ <p>These numerical types exist so that even if a client does not
+ understand the string identifier being used, and hence cannot present
+ the presence to the user to set on themselves, it may display an
+ approximation of the presence if it is set on a contact.</p>
+
+ <p>As well as the normal status identifiers, there are two special ones
+ that may be present: 'unknown' with type Unknown and 'error' with type
+ Error. 'unknown' indicates that it is impossible to determine the
+ presence of a contact at this time, for example because it's not on the
+ 'subscribe' list and the protocol only allows one to determine the
+ presence of contacts you're subscribed to. 'error' indicates that there
+ was a failure in determining the status of a contact.</p>
+
+ <p>If the connection has a 'subscribe' contact list,
+ <tp:member-ref>PresencesChanged</tp:member-ref>
+ signals should be emitted to indicate changes of contacts on this list,
+ and should also be emitted for changes in your own presence. Depending
+ on the protocol, the signal may also be emitted for others such as
+ people with whom you are communicating, and any user interface should
+ be updated accordingly.</p>
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Manager.xml b/spec/spec/Connection_Manager.xml
new file mode 100644
index 000000000..10ade57e8
--- /dev/null
+++ b/spec/spec/Connection_Manager.xml
@@ -0,0 +1,631 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Manager" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2005-2008 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright (C) 2005-2008 Nokia Corporation</tp:copyright>
+ <tp:copyright>Copyright (C) 2006 INdT</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.ConnectionManager">
+
+ <tp:simple-type name="Connection_Manager_Name" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of a connection manager, found in its well-known
+ bus name and object path. This must be a non-empty string of
+ ASCII letters, digits and underscores, starting with a letter.
+ This is typically the name of the executable with any "telepathy-"
+ prefix removed, and any hyphen/minus signs replaced by
+ underscores.</p>
+
+ <p>Connection manager names SHOULD NOT be the same as the name of
+ the protocol they implement.</p>
+
+ <tp:rationale>
+ <p>This is likely to lead to conflicts between different
+ implementations of the same protocol (or indeed inability
+ to distinguish between the different implementations!). The
+ Telepathy project traditionally uses some sort of pun (Haze is
+ based on libpurple, Salut implements a protocol often called
+ Bonjour, and Wilde implements the OSCAR protocol).</p>
+ </tp:rationale>
+
+ <p>Connection manager names SHOULD NOT be the same as the name of
+ a library on which they are based.</p>
+
+ <tp:rationale>
+ <p>We often abbreviate, for instance, <i>telepathy-haze</i> as
+ “Haze”, but abbreviating <i>telepathy-sofiasip</i>—since renamed to
+ <i>telepathy-rakia</i> for exactly this reason—to “Sofia-SIP”
+ caused confusion between the connection manager and the library it
+ uses. Please don't repeat that mistake.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:changed version="0.17.1">Prior to version 0.17.1, the allowed
+ characters were not specified</tp:changed>
+ </tp:simple-type>
+
+ <tp:simple-type name="Protocol" type="s" array-name="Protocol_List">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An instant messaging protocol. It must consist only of ASCII
+ letters, digits and hyphen/minus signs (U+002D "-"), and must start
+ with a letter. Where possible, this SHOULD be
+ chosen from the following well-known values:</p>
+
+ <ul>
+ <li>aim - AOL Instant Messenger (OSCAR or TOC)</li>
+ <li>gadugadu - Gadu-Gadu</li>
+ <li>groupwise - Novell Groupwise</li>
+ <li>icq - ICQ (OSCAR)</li>
+ <li>irc - Internet Relay Chat (RFC 1459, 2810-2813)</li>
+ <li>jabber - XMPP (RFC 3920, 3921) or Jabber</li>
+ <li>local-xmpp - Link-local XMPP (XEP-0174) (Bonjour, Salut)</li>
+ <li>msn - MSNP (Windows Live Messenger)</li>
+ <li>myspace - MySpaceIM</li>
+ <li>mxit - MXit</li>
+ <li>napster - Napster</li>
+ <li>qq - Tencent QQ</li>
+ <li>sametime - IBM Lotus Sametime</li>
+ <li>silc - SILC</li>
+ <li>sip - Session Initiation Protocol (SIP), with or without
+ SIMPLE support</li>
+ <li>skype - Skype</li>
+ <li>tel - telephony (the
+ <abbr title="Public Switched Telephone Network">PSTN</abbr>,
+ including GSM, CDMA and fixed-line telephony)</li>
+ <li>trepia - Trepia</li>
+ <li>yahoo - YMSG (Yahoo! Messenger)</li>
+ <li>yahoojp - Japanese version of YMSG</li>
+ <li>zephyr - Zephyr</li>
+ </ul>
+ </tp:docstring>
+ <tp:changed version="0.17.1">Prior to version 0.17.1, the allowed
+ characters were not specified</tp:changed>
+ </tp:simple-type>
+
+ <tp:struct name="Param_Spec" array-name="Param_Spec_List">
+ <tp:docstring>A struct representing an allowed parameter, as returned
+ by GetParameters on the ConnectionManager interface.</tp:docstring>
+ <tp:member type="s" name="Name">
+ <tp:docstring>A string parameter name</tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Conn_Mgr_Param_Flags" name="Flags">
+ <tp:docstring>A bitwise OR of the parameter flags</tp:docstring>
+ </tp:member>
+ <tp:member type="s" tp:type="DBus_Signature" name="Signature">
+ <tp:docstring>A string containing the D-Bus type signature
+ for this parameter</tp:docstring>
+ </tp:member>
+ <tp:member type="v" name="Default_Value">
+ <tp:docstring>The default value (if the Has_Default flag is not
+ present, there is no default and this takes some dummy value,
+ which SHOULD be of the appropriate D-Bus type)</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:flags name="Conn_Mgr_Param_Flags" value-prefix="Conn_Mgr_Param_Flag" type="u">
+ <tp:flag suffix="Required" value="1">
+ <tp:docstring>
+ This parameter is required for connecting to the server.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Register" value="2">
+ <tp:docstring>
+ This parameter is required for registering an account on the
+ server.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Has_Default" value="4">
+ <tp:docstring>
+ This parameter has a default value, which is returned in
+ GetParameters; not providing this parameter is equivalent to
+ providing the default.
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Secret" value="8">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This parameter should be considered private or secret; for
+ instance, clients should store it in a "password safe" like
+ gnome-keyring or kwallet, omit it from debug logs, and use a
+ text input widget that hides the value of the parameter.</p>
+
+ <p>(Clients that support older connection managers may also treat
+ any parameter whose name contains "password" as though it had this
+ flag.)</p>
+ </tp:docstring>
+ <tp:added version="0.17.2"/>
+ </tp:flag>
+ <tp:flag suffix="DBus_Property" value="16">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>This parameter is also a D-Bus property on the resulting
+ <tp:dbus-ref
+ namespace="ofdT">Connection</tp:dbus-ref>; a
+ parameter named <code>com.example.Duck.Macaroni</code> with this
+ flag corresponds to the <code>Macaroni</code> property on the
+ <code>com.example.Duck</code> interface. Its value can be queried
+ and possibly changed on an existing Connection using methods on the
+ <code>org.freedesktop.DBus.Properties</code> interface.</p>
+
+ <p>When a new value for a parameter with this flag is passed to
+ <tp:dbus-ref namespace="ofdT">Account.UpdateParameters</tp:dbus-ref>,
+ the account manager will attempt to update its value on any running
+ connections. Similarly, if the parameter also has the
+ <code>Has_Default</code> flag, and is passed in the second argument
+ to <code>UpdateParameters</code>, the default value will be applied
+ to any running
+ connections. Thus, clients generally do not need to directly access
+ or update the connection property; instead, they SHOULD manipulate
+ <tp:dbus-ref namespace="ofdT">Account.Parameters</tp:dbus-ref>.</p>
+
+ <tp:rationale>
+ <p>This allows runtime-configurable options to be stored and
+ maintained by the <tp:dbus-ref
+ namespace='ofdT'>AccountManager</tp:dbus-ref>, without needing to
+ invent a separate account preference for “properties that should
+ be set on the connection as soon as it is created”. It was
+ originally invented to manage <tp:dbus-ref
+ namespace='ofdT.Connection.Interface'>Cellular</tp:dbus-ref>
+ preferences.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:added version="0.17.16"/>
+ </tp:flag>
+ </tp:flags>
+
+ <method name="GetParameters" tp:name-for-bindings="Get_Parameters">
+ <arg direction="in" name="Protocol" type="s" tp:type="Protocol">
+ <tp:docstring>
+ The required protocol name
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="a(susv)" tp:type="Param_Spec[]"
+ name="Parameters">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of structs representing possible parameters.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get a list of the parameters which may be specified in the
+ <tp:dbus-ref namespace='ofdT.Account'>Parameters</tp:dbus-ref> of an
+ <tp:dbus-ref namespace='ofdT'>Account</tp:dbus-ref> (or, for
+ specialised applications which do not use the account manager, passed
+ to <tp:member-ref>RequestConnection</tp:member-ref>). Some parameters
+ are mandatory, and some parameters only make sense when registering new
+ accounts with the server; see the <tp:type>Param_Spec</tp:type>
+ documentation for more details.
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The requested protocol is not supported by this manager
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:mapping name="Protocol_Properties_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from protocol identifiers supported by a connection
+ manager to the immutable properties of the corresponding
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Protocol</tp:dbus-ref> objects.</p>
+ </tp:docstring>
+
+ <tp:member name="Protocol" type="s" tp:type="Protocol">
+ <tp:docstring>A protocol name</tp:docstring>
+ </tp:member>
+
+ <tp:member name="Properties" type="a{sv}"
+ tp:type="Qualified_Property_Value_Map">
+ <tp:docstring>The immutable properties of the corresponding
+ Protocol object</tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <property name="Protocols" tp:name-for-bindings="Protocols"
+ access="read" type="a{sa{sv}}" tp:type="Protocol_Properties_Map">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A map from protocol identifiers supported by this connection
+ manager to the immutable properties of the corresponding
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Protocol</tp:dbus-ref> objects.</p>
+
+ <tp:rationale>
+ <p>Providing the immutable properties here means that
+ when the API of Protocol objects has been finalized,
+ most clients will only need one D-Bus round trip to interrogate
+ the ConnectionManager about all its protocols.</p>
+ </tp:rationale>
+
+ <p>If this map is empty or missing, clients SHOULD fall back to
+ calling <tp:member-ref>ListProtocols</tp:member-ref> and
+ <tp:member-ref>GetParameters</tp:member-ref>.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="ListProtocols" tp:name-for-bindings="List_Protocols">
+ <arg direction="out" type="as" tp:type="Protocol[]" name="Protocols">
+ <tp:docstring>
+ The keys of the <tp:member-ref>Protocols</tp:member-ref> map.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get a list of protocol identifiers that are implemented by this
+ connection manager.
+ </tp:docstring>
+ </method>
+
+ <signal name="NewConnection" tp:name-for-bindings="New_Connection">
+ <arg name="Bus_Name" type="s" tp:type="DBus_Bus_Name">
+ <tp:docstring>
+ The D-Bus service where the connection object can be found
+ </tp:docstring>
+ </arg>
+ <arg name="Object_Path" type="o">
+ <tp:docstring>
+ The object path of the Connection object on this service
+ </tp:docstring>
+ </arg>
+ <arg name="Protocol" type="s" tp:type="Protocol">
+ <tp:docstring>
+ The identifier for the protocol this connection uses
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a new <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref> object
+ is created.
+ </tp:docstring>
+ </signal>
+
+ <method name="RequestConnection" tp:name-for-bindings="Request_Connection">
+ <arg direction="in" name="Protocol" type="s" tp:type="Protocol">
+ <tp:docstring>
+ The protocol identifier
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Parameters" type="a{sv}"
+ tp:type="String_Variant_Map">
+ <tp:docstring>
+ A dictionary mapping parameter names to values of the appropriate
+ type, as indicated by <tp:member-ref>GetParameters</tp:member-ref>
+ and the well-known list of names and value types documented on the
+ <tp:type>Connection_Parameter_Name</tp:type> type.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="s" tp:type="DBus_Bus_Name" name="Bus_Name">
+ <tp:docstring>
+ A D-Bus service name where the new Connection object can be found
+ </tp:docstring>
+ </arg>
+ <arg direction="out" type="o" name="Object_Path">
+ <tp:docstring>
+ The D-Bus object path to the Connection on this service
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Request a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>
+ object representing a given account on a given
+ protocol with the given parameters. The method returns the bus name
+ and the object path where the new Connection object can be found,
+ which should have the status of Connection_Status_Disconnected, to
+ allow signal handlers to be attached before connecting is started
+ with the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection">Connect</tp:dbus-ref>
+ method.</p>
+
+ <p><strong>Most applications should not use this method</strong>: they
+ should instead use the the <tp:dbus-ref
+ namespace='ofdT.Account'>Connection</tp:dbus-ref> property on an
+ <tp:dbus-ref namespace='ofdT'>Account</tp:dbus-ref> object obtained
+ from the <tp:dbus-ref
+ namespace='ofdT'>AccountManager</tp:dbus-ref>. This method is used
+ internally by the account manager to create connections when
+ needed.</p>
+
+ <p>The parameters which must and may be provided in the parameters
+ dictionary can be discovered with the
+ <tp:member-ref>GetParameters</tp:member-ref> method. These
+ parameters, their types, and their default values may be cached
+ in files so that all available connection managers do not need to be
+ started to discover which protocols are available.</p>
+
+ <p>To request values for these parameters from the user, a client must
+ have prior knowledge of the meaning of the parameter names, so the
+ well-known names and types defined by the
+ <tp:type>Connection_Parameter_Name</tp:type> type should be used where
+ appropriate.</p>
+
+ <p>Connection manager authors SHOULD avoid introducing parameters
+ whose default values would not be serializable in a
+ <code>.manager</code> file.</p>
+
+ <tp:rationale>
+ <p>The same serialization format is used in Mission Control
+ to store accounts.</p>
+ </tp:rationale>
+
+ <p>Every successful RequestConnection call will cause the emission of a
+ <tp:member-ref>NewConnection</tp:member-ref> signal for the same newly
+ created connection. The
+ requester can use the returned object path and service name
+ independently of the emission of that signal. In that case this signal
+ emission is most useful for, e.g. other processes that are monitoring
+ the creation of new connections.</p>
+ </tp:docstring>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The requested protocol is not supported by this manager
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
+ <tp:docstring>
+ The requested connection already appears to exist
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Unrecognised connection parameters
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <tp:simple-type name="Connection_Parameter_Name" type="s">
+ <tp:added version="0.21.2"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Well-known connection parameter names, along with their expected
+ type. Where possible, connection managers should use names and types
+ from this list in the <tp:dbus-ref
+ namespace='ofdT.Protocol'>Parameters</tp:dbus-ref> that may be passed
+ to <tp:member-ref>RequestConnection</tp:member-ref>.</p>
+
+ <dl>
+ <dt>account (s)</dt>
+ <dd>The identifier for the user's account on the server</dd>
+
+ <dt>server (s)</dt>
+ <dd>A fully qualified domain name or numeric IPv4 or IPv6 address.
+ Using the fully-qualified domain name form is recommended whenever
+ possible. If this parameter is specified and the account for that
+ protocol also specifies a server, this parameter should override
+ that in the user id.</dd>
+
+ <dt>port (q)</dt>
+ <dd>A TCP or UDP port number. If this parameter is specified and the
+ account for that protocol also specifies a port, this parameter
+ should override that in the account.</dd>
+
+ <dt>password (s)</dt>
+ <dd>A password associated with the account.</dd>
+
+ <dt>require-encryption (b)</dt>
+ <dd>Require encryption for this connection. A connection should fail
+ to connect if require-encryption is set and an encrypted connection
+ is not possible.</dd>
+
+ <dt>register (b)</dt>
+ <dd>This account should be created on the server if it does not
+ already exist.</dd>
+
+ <dt>ident (s)</dt>
+ <dd>The local username to report to the server if necessary, such as
+ in IRC.</dd>
+
+ <dt>fullname (s)</dt>
+ <dd>The user's full name if the service requires this when
+ authenticating or registering.</dd>
+
+ <dt>stun-server (s)</dt>
+ <dd>The IP address or FQDN of a STUN server to use for NAT traversal,
+ without any ":port" suffix.</dd>
+
+ <dt>stun-port (q)</dt>
+ <dd>The UDP port number on the stun-server to use for STUN. Only
+ significant if the stun-server is also supplied.</dd>
+
+ <dt>keepalive-interval (u)</dt>
+ <dd>
+ <p>The time in seconds between pings sent to the server to ensure
+ that the connection is still alive, or <tt>0</tt> to disable such
+ pings.</p>
+
+ <p>This parameter is superseded by the <tp:dbus-ref
+ namespace='ofdT.Connection.Interface.Keepalive.DRAFT'>KeepaliveInterval</tp:dbus-ref>
+ property, which can be updated on an already-established
+ connection as well as being specified when requesting the
+ connection. Clients SHOULD provide that parameter instead, if
+ allowed; new connection managers SHOULD implement it in
+ preference to this one.</p>
+ </dd>
+ </dl>
+
+ <p>The following well-known parameter names correspond to D-Bus
+ properties, and thus their <tp:type>Conn_Mgr_Param_Flags</tp:type>
+ should include DBus_Property. See that flag for more details on this
+ kind of parameter.</p>
+
+ <tp:list-dbus-property-parameters/>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ type="as" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of the extra interfaces provided by this connection manager
+ (i.e. extra functionality that can be provided even before a
+ connection has been created).</p>
+
+ <p>No interfaces suitable for listing in this property are currently
+ defined; it's provided as a hook for possible future
+ functionality.</p>
+
+ <p>To be compatible with older connection managers, if retrieving
+ this property fails, clients SHOULD assume that its value is
+ an empty list.</p>
+
+ <p>Connection managers with a non-empty list of Interfaces MUST
+ represent them in the <code>.manager</code> file, if they have one,
+ as an <code>Interfaces</code> key in the
+ group headed <code>[ConnectionManager]</code>, whose value is a list
+ of strings each followed by a semicolon.</p>
+ </tp:docstring>
+ <tp:added version="0.17.8"/>
+ </property>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A D-Bus service which allows connections to be created. The manager
+ processes are intended to be started by D-Bus service activation.</p>
+
+ <p>For service discovery, each Telepathy connection manager must have
+ a <em>connection manager name</em> (see
+ <tp:type>Connection_Manager_Name</tp:type> for syntax).</p>
+
+ <p>The connection manager must then provide a well-known bus name of
+ <code>org.freedesktop.Telepathy.ConnectionManager.<em>cmname</em></code>
+ where <em>cmname</em> is its connection manager name. If it makes sense
+ to start the connection manager using D-Bus service activation, it
+ must register that well-known name for service activation by installing
+ a .service file.</p>
+
+ <p>Clients can list the running connection managers by calling the
+ ListNames method on the D-Bus daemon's org.freedesktop.DBus interface
+ and looking for names matching the above pattern; they can list the
+ activatable connection managers by calling ListActivatableNames, and
+ they should usually combine the two lists to get a complete list of
+ running or activatable connection managers.</p>
+
+ <p>When the connection manager is running, it must have an object
+ implementing the ConnectionManager interface at the object path
+ <code>/org/freedesktop/Telepathy/ConnectionManager/<em>cmname</em></code>.
+ </p>
+
+ <p>Connection managers' capabilities can be determined dynamically by
+ calling their <tp:member-ref>ListProtocols</tp:member-ref> method, then
+ for each protocol of interest, calling
+ <tp:member-ref>GetParameters</tp:member-ref> to discover the required and
+ optional parameters.
+ However, since it is inefficient to activate all possible connection
+ managers on the system just to find out what they can do, there
+ is a standard mechanism to store static information about CMs in
+ ".manager files".</p>
+
+ <p>To look up a connection manager's supported protocols, clients
+ should search the data directories specified by
+ <a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">the
+ freedesktop.org XDG Base Directory Specification</a> ($XDG_DATA_HOME,
+ defaulting to $HOME/.local/share if unset, followed by
+ colon-separated paths from $XDG_DATA_DIRS, defaulting to
+ /usr/local/share:/usr/share if unset) for the first file named
+ <code>telepathy/managers/<em>cmname</em>.manager</code> that can be
+ read without error. This file has the same syntax as a
+ <a href="http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">freedesktop.org Desktop Entry file</a>.</p>
+
+ <p>Clients must still support connection managers for which no
+ <code>.manager</code> file can be found, which they can do by activating
+ the connection manager and calling its methods; the
+ <code>.manager</code> file is merely an optimization. Connection managers
+ whose list of protocols can change at any time (for instance, via
+ a plugin architecture) should not install a <code>.manager</code>
+ file.</p>
+
+ <p>The <code>.manager</code> file SHOULD have a group headed
+ <code>[ConnectionManager]</code>, containing a key
+ <code>Interfaces</code> representing
+ <tp:member-ref>Interfaces</tp:member-ref> as a sequence of strings
+ each followed by a semicolon (the "localestrings" type from the Desktop
+ Entry Specification).</p>
+
+ <p>The <code>[ConnectionManager]</code> group SHOULD NOT contain keys
+ <code>ObjectPath</code> or <code>BusName</code>. If it does, they MUST
+ be ignored.</p>
+
+ <tp:rationale>
+ <p>The object path and bus name are derivable from the connection
+ manager's name, which is part of the filename, so these keys are
+ redundant. They were required in very old versions of Telepathy.</p>
+ </tp:rationale>
+
+ <p>For each protocol name <em>proto</em> that would be returned by
+ ListProtocols, the .manager file contains a group
+ headed <code>[Protocol <em>proto</em>]</code>. For each parameter
+ <em>p</em> that would be returned by GetParameters(<em>proto</em>), the
+ .manager file contains a key <code>param-<em>p</em></code> with a value
+ consisting of a D-Bus signature (a single complete type), optionally
+ followed by a space and a space-separated list of flags. The supported
+ flags are:</p>
+
+ <ul>
+ <li><code>required</code>, corresponding to
+ Conn_Mgr_Param_Flag_Required</li>
+ <li><code>register</code>, corresponding
+ to Conn_Mgr_Param_Flag_Register</li>
+ <li><code>secret</code>, corresponding
+ to Conn_Mgr_Param_Flag_Secret</li>
+ <li><code>dbus-property</code>, corresponding
+ to Conn_Mgr_Param_Flag_DBus_Property</li>
+ </ul>
+
+ <p>The group may also contain a key <code>default-<em>p</em></code>
+ whose value is a string form of the default value for the parameter.
+ If this key exists, it sets the default, and also sets the flag
+ Conn_Mgr_Param_Flag_Has_Default. The default value is formatted
+ according to the D-Bus signature as follows:</p>
+
+ <dl>
+ <dt>s (string)</dt>
+ <dd>The UTF-8 string, with the standard backslash escape
+ sequences supported by the Desktop Entry Specification
+ (the "localestring" type from the Desktop Entry Specification)</dd>
+ <dt>o (object path)</dt>
+ <dd>The object path as an ASCII string</dd>
+ <dt>b (boolean)</dt>
+ <dd>"true" (case-insensitively) or "1" means True, "false"
+ (case-insensitively) or "0" means False; when writing a file,
+ "true" and "false" SHOULD be used</dd>
+ <dt>y, q, u, t (8-, 16-, 32-, 64-bit unsigned integer)</dt>
+ <dd>ASCII decimal integer</dd>
+ <dt>n, i, x (16-, 32-, 64-bit signed integer)</dt>
+ <dd>ASCII decimal integer, optionally prefixed with "-"</dd>
+ <dt>d (double-precision floating point)</dt>
+ <dd>ASCII decimal number</dd>
+ <dt>as (array of string)</dt>
+ <dd>A sequence of UTF-8 strings each followed by a semicolon, with
+ any semicolons they contain escaped with a backslash
+ (the "localestrings" type from the Desktop Entry Specification)</dd>
+ </dl>
+
+ <p>Currently, no other D-Bus signatures are allowed to have default values,
+ but clients parsing the .manager file MUST ignore defaults
+ that they cannot parse, and treat them as if the
+ <code>default-<em>p</em></code> key was not present at all.</p>
+
+ <p>It is not required that a connection manager be able to support multiple
+ protocols, or even multiple connections. When a connection is made, a
+ service name where the connection object can be found is returned. A
+ manager which can only make one connection may then remove itself from its
+ well-known bus name, causing a new connection manager to be activated when
+ somebody attempts to make a new connection.</p>
+ </tp:docstring>
+
+ <tp:changed version="0.17.2">Prior to version 0.17.2, support for
+ CMs with no .manager file was not explicitly required.</tp:changed>
+ <tp:changed version="0.17.16">Prior to version 0.17.16 the serialization
+ of string arrays (signature 'as') was not defined</tp:changed>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Connection_Manager_Interface_Account_Storage.xml b/spec/spec/Connection_Manager_Interface_Account_Storage.xml
new file mode 100644
index 000000000..2f4f4bf78
--- /dev/null
+++ b/spec/spec/Connection_Manager_Interface_Account_Storage.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" ?>
+<node name="/Connection_Manager_Interface_Account_Storage"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.ConnectionManager.Interface.AccountStorage.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.21.10">(draft 1)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.ConnectionManager"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for connection managers that store account details
+ internally. At the moment this consists only of storing an account's
+ credentials, but other functionality may be added in the future.</p>
+
+ <p><tp:dbus-ref namespace="ofdT">Account</tp:dbus-ref> objects
+ representing accounts on a connection manager that implements this
+ interface should implement the
+ <tp:dbus-ref namespace="ofdT.Account.Interface">ExternalPasswordStorage.DRAFT</tp:dbus-ref>
+ interface.</p>
+ </tp:docstring>
+
+ <tp:flags name="Account_Flags" value-prefix="Account_Flag" type="u">
+ <tp:docstring>
+ A set of flags representing the status of the Account stored in the
+ Connection Manager.
+ </tp:docstring>
+
+ <tp:flag suffix="Credentials_Stored" value="1">
+ <tp:docstring>
+ The associated account has its authentication credentials (password)
+ stored in the connection manager
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:mapping name="Account_Flags_Map" array-name="Account_Flags_Map_List">
+ <tp:docstring>A mapping from Account_Ids to account flags.
+ </tp:docstring>
+ <tp:member type="s" name="Account_Id"/>
+ <tp:member type="u" tp:type="Account_Flags" name="Flags"/>
+ </tp:mapping>
+
+ <property name="Accounts"
+ tp:name-for-bindings="Accounts"
+ type="a{su}" tp:type="Account_Flags_Map" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The set of Accounts stored in this Connection Manager, and flags
+ indicating their status.</p>
+
+ <p>Change notification for this property is provided by the standard
+ D-Bus <code>PropertiesChanged</code> signal.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="ForgetCredentials" tp:name-for-bindings="Forget_Credentials">
+ <tp:docstring>
+ Clears any saved credentials associated with the specified Account_Id.
+ Any other saved data related to the account will be unaffected.
+ </tp:docstring>
+
+ <arg direction="in" name="Account_Id"
+ type="s">
+ <tp:docstring>
+ An account id as returned from
+ <tp:dbus-ref namespace="ofdT">Protocol.IdentifyAccount</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The account id is invalid.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="RemoveAccount" tp:name-for-bindings="Remove_Account">
+ <tp:docstring>
+ Completely removes all data associated with an account from the
+ connection manager's internal storage.
+ </tp:docstring>
+
+ <arg direction="in" name="Account_Id"
+ type="s">
+ <tp:docstring>
+ An account id as returned from
+ <tp:dbus-ref namespace="ofdT">Protocol.IdentifyAccount</tp:dbus-ref>.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The account id is invalid.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
diff --git a/spec/spec/Debug.xml b/spec/spec/Debug.xml
new file mode 100644
index 000000000..70a82e903
--- /dev/null
+++ b/spec/spec/Debug.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" ?>
+<node name="/Debug"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2009 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Debug">
+ <tp:added version="0.17.27">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for providing debug messages.</p>
+
+ <p>This interface is primarily provided by one object per
+ service, at the path <tt>/org/freedesktop/Telepathy/debug</tt>.</p>
+ </tp:docstring>
+
+ <property name="Enabled" type="b" access="readwrite"
+ tp:name-for-bindings="Enabled">
+ <tp:docstring>
+ TRUE if the <tp:member-ref>NewDebugMessage</tp:member-ref> signal
+ should be emitted when a new debug message is generated.
+ </tp:docstring>
+ </property>
+
+ <method name="GetMessages" tp:name-for-bindings="Get_Messages">
+ <tp:docstring>
+ Retrieve buffered debug messages. An implementation could have a
+ limit on how many message it keeps and so the array returned from
+ this method should not be assumed to be all of the messages in
+ the lifetime of the service.
+ </tp:docstring>
+
+ <arg direction="out" name="Messages" type="a(dsus)"
+ tp:type="Debug_Message[]">
+ <tp:docstring>
+ A list of debug messages.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <signal name="NewDebugMessage" tp:name-for-bindings="New_Debug_Message">
+ <tp:docstring>
+ Emitted when a debug messages is generated if the
+ <tp:member-ref>Enabled</tp:member-ref> property is set to TRUE.
+ </tp:docstring>
+
+ <arg name="time" type="d">
+ <tp:docstring>
+ Timestamp of the debug message.
+ </tp:docstring>
+ </arg>
+ <arg name="domain" type="s">
+ <tp:docstring>
+ Domain of the debug message, as described in the Debug_Message struct.
+ </tp:docstring>
+ </arg>
+ <arg name="level" type="u" tp:type="Debug_Level">
+ <tp:docstring>
+ Level of the debug message.
+ </tp:docstring>
+ </arg>
+ <arg name="message" type="s">
+ <tp:docstring>
+ The text of the debug message.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:enum name="Debug_Level" type="u">
+ <tp:enumvalue suffix="Error" value="0">
+ <tp:docstring>
+ Log level for errors. Error messages are always fatal, resulting
+ in the service terminating after something completely
+ unexpected occurred.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Critical" value="1">
+ <tp:docstring>
+ Log level for critical messages. Critical messages are messages
+ that the service might predict and it is up to the service itself
+ to decide whether to terminate following a critical message.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Warning" value="2">
+ <tp:docstring>
+ Log level for warnings.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Message" value="3">
+ <tp:docstring>
+ Log level for messages.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Info" value="4">
+ <tp:docstring>
+ Log level for information messages.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Debug" value="5">
+ <tp:docstring>
+ Log level for debug messages.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:struct name="Debug_Message" array-name="Debug_Message_List">
+ <tp:docstring>
+ A struct representing a debug message, as returned by
+ <tp:member-ref>GetMessages</tp:member-ref>.
+ </tp:docstring>
+
+ <tp:member type="d" name="Timestamp">
+ <tp:docstring>
+ Timestamp of the debug message. This is a double to allow
+ more accuracy in the time the message was logged.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="s" name="Domain">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Domain of the debug message. This is used to identify
+ the source of debug messages. For example, debug messages
+ from a connection manager could have this Domain struct
+ member be the name of the connection manager, and logs
+ from any helper library could have the name of the helper
+ library.</p>
+
+ <p>The domain could also contain a category as to where
+ the log message originated separated by a forward-slash.
+ For example, if a debug message was output in a connection
+ manager called "dummy", in the file-transfer code, this
+ Domain struct member might be <tt>dummy/file-transfer</tt>.</p>
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="u" tp:type="Debug_Level" name="Level">
+ <tp:docstring>
+ Level of the debug message. This states the severity of the
+ debug message.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member type="s" name="Message">
+ <tp:docstring>
+ The text of the debug message.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Media_Session_Handler.xml b/spec/spec/Media_Session_Handler.xml
new file mode 100644
index 000000000..70aa75073
--- /dev/null
+++ b/spec/spec/Media_Session_Handler.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" ?>
+<node name="/Media_Session_Handler" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005, 2006 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Media.SessionHandler">
+ <method name="Error" tp:name-for-bindings="Error">
+ <arg direction="in" name="Error_Code" type="u"
+ tp:type="Media_Stream_Error"/>
+ <arg direction="in" name="Message" type="s"/>
+ <tp:deprecated version="0.13.4">
+ Use <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media">StreamHandler.Error</tp:dbus-ref>
+ on each StreamHandler object instead.
+ </tp:deprecated>
+ <tp:docstring>
+ Informs the connection manager that an error occured in this session.
+ If used, the connection manager must terminate the session and all of
+ the streams within it, and may also emit a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Channel.Type.StreamedMedia">StreamError</tp:dbus-ref>
+ signal on the channel for each stream within the session.
+ </tp:docstring>
+ </method>
+ <signal name="NewStreamHandler" tp:name-for-bindings="New_Stream_Handler">
+ <arg name="Stream_Handler" type="o">
+ <tp:docstring>
+ The path of a new object implementing the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Media">StreamHandler</tp:dbus-ref>
+ interface.
+ </tp:docstring>
+ </arg>
+ <arg name="ID" type="u">
+ <tp:docstring>
+ The unique ID of the new stream
+ </tp:docstring>
+ </arg>
+ <arg name="Media_Type" type="u" tp:type="Media_Stream_Type">
+ <tp:docstring>
+ Type of media that this stream should handle
+ </tp:docstring>
+ </arg>
+ <arg name="Direction" type="u" tp:type="Media_Stream_Direction">
+ <tp:docstring>
+ Direction of this stream
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a new stream handler has been created for this
+ session.
+ </tp:docstring>
+ </signal>
+ <method name="Ready" tp:name-for-bindings="Ready">
+ <tp:docstring>
+ Inform the connection manager that a client is ready to handle
+ this session handler (i.e. that it has connected to the
+ <tp:member-ref>NewStreamHandler</tp:member-ref> signal and done any
+ other necessary setup).
+ </tp:docstring>
+ </method>
+ <tp:docstring>
+ An media session handler is an object that handles a number of synchronised
+ media streams.
+ </tp:docstring>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Media_Stream_Handler.xml b/spec/spec/Media_Stream_Handler.xml
new file mode 100644
index 000000000..0a833709a
--- /dev/null
+++ b/spec/spec/Media_Stream_Handler.xml
@@ -0,0 +1,906 @@
+<?xml version="1.0" ?>
+<node name="/Media_Stream_Handler" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005-2008 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005-2008 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Media.StreamHandler">
+
+ <tp:docstring>
+ Handles signalling the information pertaining to a specific media stream.
+ A client should provide information to this handler as and when it is
+ available.
+ </tp:docstring>
+
+ <tp:struct name="Media_Stream_Handler_Candidate"
+ array-name="Media_Stream_Handler_Candidate_List">
+ <tp:member type="s" name="Name"/>
+ <tp:member type="a(usuussduss)" name="Transports"
+ tp:type="Media_Stream_Handler_Transport[]"/>
+ </tp:struct>
+
+ <tp:struct name="Media_Stream_Handler_Transport"
+ array-name="Media_Stream_Handler_Transport_List">
+ <tp:member type="u" name="Component_Number"/>
+ <tp:member type="s" name="IP_Address"/>
+ <tp:member type="u" name="Port"/>
+ <tp:member type="u" tp:type="Media_Stream_Base_Proto" name="Protocol"/>
+ <tp:member type="s" name="Subtype"/>
+ <tp:member type="s" name="Profile"/>
+ <tp:member type="d" name="Preference_Value"/>
+ <tp:member type="u" tp:type="Media_Stream_Transport_Type"
+ name="Transport_Type"/>
+ <tp:member type="s" name="Username"/>
+ <tp:member type="s" name="Password"/>
+ </tp:struct>
+
+ <tp:struct name="Media_Stream_Handler_Codec"
+ array-name="Media_Stream_Handler_Codec_List">
+ <tp:docstring>
+ Information about a codec supported by a client or a peer's client.
+ </tp:docstring>
+
+ <tp:member type="u" name="Codec_ID">
+ <tp:docstring>
+ The codec's payload identifier, as per RFC 3551 (static or dynamic)
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Name">
+ <tp:docstring>The codec's name</tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Media_Stream_Type" name="Media_Type">
+ <tp:docstring>Type of stream this codec supports</tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Clock_Rate">
+ <tp:docstring>Sampling frequency in Hertz</tp:docstring>
+ </tp:member>
+ <tp:member type="u" name="Number_Of_Channels">
+ <tp:docstring>Number of supported channels</tp:docstring>
+ </tp:member>
+ <tp:member type="a{ss}" name="Parameters" tp:type="String_String_Map">
+ <tp:docstring>Codec-specific optional parameters</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <property name="STUNServers" tp:name-for-bindings="STUN_Servers"
+ type="a(sq)" tp:type="Socket_Address_IP[]" access="read">
+ <tp:added version="0.17.22"/>
+ <tp:docstring>
+ The IP addresses of possible STUN servers to use for NAT traversal, as
+ dotted-quad IPv4 address literals or RFC2373 IPv6 address literals.
+ This property cannot change once the stream has been created, so there
+ is no change notification. The IP addresses MUST NOT be given as DNS
+ hostnames.
+
+ <tp:rationale>
+ High-quality connection managers already need an asynchronous
+ DNS resolver, so they might as well resolve this name to an IP
+ to make life easier for streaming implementations.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="CreatedLocally" tp:name-for-bindings="Created_Locally"
+ type="b" access="read">
+ <tp:added version="0.17.22"/>
+ <tp:docstring>
+ True if we were the creator of this stream, false otherwise.
+ <tp:rationale>
+ This information is needed for some nat traversal mechanisms, such
+ as ICE-UDP, where the creator gets the role of the controlling agent.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <property name="NATTraversal" tp:name-for-bindings="NAT_Traversal"
+ type="s" access="read">
+ <tp:added version="0.17.22"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The transport (NAT traversal technique) to be used for this
+ stream. Well-known values include:</p>
+
+ <dl>
+ <dt>none</dt>
+ <dd>Raw UDP, with or without STUN, should be used. If the
+ <tp:member-ref>STUNServers</tp:member-ref> property is non-empty,
+ STUN SHOULD be used.</dd>
+
+ <dt>stun</dt>
+ <dd>A deprecated synonym for 'none'.</dd>
+
+ <dt>gtalk-p2p</dt>
+ <dd>Google Talk peer-to-peer connectivity establishment should be
+ used, as implemented in libjingle 0.3.</dd>
+
+ <dt>ice-udp</dt>
+ <dd>Interactive Connectivity Establishment should be used,
+ as defined by the IETF MMUSIC working group.</dd>
+
+ <dt>wlm-8.5</dt>
+ <dd>The transport used by Windows Live Messenger 8.5 or later,
+ which resembles ICE draft 6, should be used.</dd>
+
+ <dt>wlm-2009</dt>
+ <dd>The transport used by Windows Live Messenger 2009 or later,
+ which resembles ICE draft 19, should be used.</dd>
+ </dl>
+
+ <p>This property cannot change once the stream has been created, so
+ there is no change notification.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="RelayInfo" type="aa{sv}" access="read"
+ tp:type="String_Variant_Map[]" tp:name-for-bindings="Relay_Info">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of mappings describing TURN or Google relay servers
+ available for the client to use in its candidate gathering, as
+ determined from the protocol. Map keys are:</p>
+
+ <dl>
+ <dt><code>ip</code> - s</dt>
+ <dd>The IP address of the relay server as a dotted-quad IPv4
+ address literal or an RFC2373 IPv6 address literal. This MUST NOT
+ be a DNS hostname.
+
+ <tp:rationale>
+ High-quality connection managers already need an asynchronous
+ DNS resolver, so they might as well resolve this name to an IP
+ and make life easier for streaming implementations.
+ </tp:rationale>
+ </dd>
+
+ <dt><code>type</code> - s</dt>
+ <dd>
+ <p>Either <code>udp</code> for UDP (UDP MUST be assumed if this
+ key is omitted), <code>tcp</code> for TCP, or
+ <code>tls</code>.</p>
+
+ <p>The precise meaning of this key depends on the
+ <tp:member-ref>NATTraversal</tp:member-ref> property: if
+ NATTraversal is <code>ice-udp</code>, <code>tls</code> means
+ TLS over TCP as referenced by ICE draft 19, and if
+ NATTraversal is <code>gtalk-p2p</code>, <code>tls</code> means
+ a fake SSL session over TCP as implemented by libjingle.</p>
+ </dd>
+
+ <dt><code>port</code> - q</dt>
+ <dd>The UDP or TCP port of the relay server as an ASCII unsigned
+ integer</dd>
+
+ <dt><code>username</code> - s</dt>
+ <dd>The username to use</dd>
+
+ <dt><code>password</code> - s</dt>
+ <dd>The password to use</dd>
+
+ <dt><code>component</code> - u</dt>
+ <dd>The component number to use this relay server for, as an
+ ASCII unsigned integer; if not included, this relay server
+ may be used for any or all components.
+
+ <tp:rationale>
+ In ICE draft 6, as used by Google Talk, credentials are only
+ valid once, so each component needs relaying separately.
+ </tp:rationale>
+ </dd>
+ </dl>
+
+ <tp:rationale>
+ <p>An equivalent of the gtalk-p2p-relay-token property on
+ MediaSignalling channels is not included here. The connection
+ manager should be responsible for making the necessary HTTP
+ requests to turn the token into a username and password.</p>
+ </tp:rationale>
+
+ <p>The type of relay server that this represents depends on
+ the value of the <tp:member-ref>NATTraversal</tp:member-ref>
+ property. If NATTraversal is ice-udp, this is a TURN server;
+ if NATTraversal is gtalk-p2p, this is a Google relay server;
+ otherwise, the meaning of RelayInfo is undefined.</p>
+
+ <p>If relaying is not possible for this stream, the list is empty.</p>
+
+ <p>This property cannot change once the stream has been created, so
+ there is no change notification.</p>
+ </tp:docstring>
+ </property>
+
+ <signal name="AddRemoteCandidate"
+ tp:name-for-bindings="Add_Remote_Candidate">
+ <arg name="Candidate_ID" type="s">
+ <tp:docstring>
+ String identifier for this candidate
+ </tp:docstring>
+ </arg>
+ <arg name="Transports" type="a(usuussduss)"
+ tp:type="Media_Stream_Handler_Transport[]">
+ <tp:docstring>
+ Array of transports for this candidate with fields,
+ as defined in NewNativeCandidate
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client of a new remote candidate.
+ </tp:docstring>
+ </signal>
+ <signal name="Close" tp:name-for-bindings="Close">
+ <tp:docstring>
+ Signal emitted when the connection manager wishes the stream to be
+ closed.
+ </tp:docstring>
+ </signal>
+ <method name="CodecChoice" tp:name-for-bindings="Codec_Choice">
+ <arg direction="in" name="Codec_ID" type="u"/>
+ <tp:docstring>
+ Inform the connection manager of codec used to receive data.
+ </tp:docstring>
+ </method>
+ <method name="Error" tp:name-for-bindings="Error">
+ <arg direction="in" name="Error_Code" type="u" tp:type="Media_Stream_Error">
+ <tp:docstring>
+ ID of error, from the MediaStreamError enumeration
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Message" type="s">
+ <tp:docstring>
+ String describing the error
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager that an error occured in this stream. The
+ connection manager should emit the StreamError signal for the stream on
+ the relevant channel, and remove the stream from the session.
+ </tp:docstring>
+ </method>
+ <tp:enum name="Media_Stream_Error" type="u">
+ <tp:enumvalue suffix="Unknown" value="0">
+ <tp:docstring>
+ An unknown error occured.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="EOS" value="1">
+ <tp:docstring>
+ The end of the stream was reached.
+ </tp:docstring>
+ <tp:deprecated version="0.17.27">
+ This error has no use anywhere. In Farsight 1 times, it was used to
+ indicate a GStreamer EOS (when the end of a file is reached). But
+ since this is for live calls, it makes no sense.
+ </tp:deprecated>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Codec_Negotiation_Failed" value="2">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ There are no common codecs between the local side
+ and the other particpants in the call. The possible codecs are not
+ signalled here: the streaming implementation is assumed to report
+ them in an implementation-dependent way, e.g. Farsight should use
+ GstMissingElement.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Connection_Failed" value="3">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ A network connection for the Media could not be established or was
+ lost.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Network_Error" value="4">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ There was an error in the networking stack
+ (other than the connection failure).
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="No_Codecs" value="5">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ There are no installed codecs for this media type.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Invalid_CM_Behavior" value="6">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ The CM is doing something wrong.
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Media_Error" value="7">
+ <tp:added version="0.17.27"/>
+ <tp:docstring>
+ There was an error in the media processing stack.
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ <method name="NativeCandidatesPrepared"
+ tp:name-for-bindings="Native_Candidates_Prepared">
+ <tp:docstring>
+ Informs the connection manager that all possible native candisates
+ have been discovered for the moment.
+ </tp:docstring>
+ </method>
+ <method name="NewActiveCandidatePair"
+ tp:name-for-bindings="New_Active_Candidate_Pair">
+ <arg direction="in" name="Native_Candidate_ID" type="s"/>
+ <arg direction="in" name="Remote_Candidate_ID" type="s"/>
+ <tp:docstring>
+ Informs the connection manager that a valid candidate pair
+ has been discovered and streaming is in progress.
+ </tp:docstring>
+ </method>
+ <method name="NewActiveTransportPair"
+ tp:name-for-bindings="New_Active_Transport_Pair">
+ <arg direction="in" name="Native_Candidate_ID" type="s"/>
+ <arg direction="in" name="Native_Transport" type="(usuussduss)"
+ tp:type="Media_Stream_Handler_Transport"/>
+ <arg direction="in" name="Remote_Candidate_ID" type="s"/>
+ <arg direction="in" name="Remote_Transport" type="(usuussduss)"
+ tp:type="Media_Stream_Handler_Transport"/>
+ <tp:docstring>
+ <p>Informs the connection manager that a valid transport pair
+ has been discovered and streaming is in progress. Component
+ id MUST be the same for both transports and the pair is
+ only valid for that component.</p>
+
+ <tp:rationale>
+ <p>The connection manager might need to send the details of
+ the active transport pair (e.g. c and o parameters of SDP
+ body need to contain address of selected native RTP transport
+ as stipulated by RFC 5245). However, the candidate ID might
+ not be enough to determine these info if the transport was
+ found after <tp:member-ref>NativeCandidatesPrepared</tp:member-ref>
+ has been called (e.g. peer reflexive ICE candidate). </p>
+ </tp:rationale>
+
+ <p>This method must be called before
+ <tp:member-ref>NewActiveCandidatePair</tp:member-ref>.</p>
+
+ <tp:rationale>
+ <p>This way, connection managers supporting this method can
+ safely ignore subsequent
+ <tp:member-ref>NewActiveCandidatePair</tp:member-ref> call.</p>
+ </tp:rationale>
+
+ <p>Connection managers SHOULD NOT implement this method unless
+ they need to inform the peer about selected transports. As a
+ result, streaming implementations MUST NOT treat errors raised
+ by this method as fatal.</p>
+
+ <tp:rationale>
+ <p>Usually, connection managers only need to do one answer/offer
+ round-trip. However, some protocols give the possibility to
+ to send an updated offer (e.g. ICE defines such mechanism to
+ avoid some race conditions and to properly set the state of
+ gateway devices).</p>
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+ <tp:enum name="Media_Stream_Base_Proto" type="u">
+ <tp:enumvalue suffix="UDP" value="0">
+ <tp:docstring>UDP (User Datagram Protocol)</tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="TCP" value="1">
+ <tp:docstring>TCP (Transmission Control Protocol)</tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ <method name="NewNativeCandidate"
+ tp:name-for-bindings="New_Native_Candidate">
+ <arg direction="in" name="Candidate_ID" type="s">
+ <tp:docstring>
+ String identifier for this candidate
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Transports" type="a(usuussduss)"
+ tp:type="Media_Stream_Handler_Transport[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Array of transports for this candidate, with fields:
+ <ul>
+ <li>component number</li>
+ <li>IP address (as a string)</li>
+ <li>port</li>
+ <li>base network protocol (one of the values of MediaStreamBaseProto)</li>
+ <li>proto subtype (e.g. RTP)</li>
+ <li>proto profile (e.g. AVP)</li>
+ <li>our preference value of this transport (double in range 0.0-1.0
+ inclusive); 1 signals the most preferred transport</li>
+ <li>transport type, one of the values of MediaStreamTransportType</li>
+ <li>username if authentication is required</li>
+ <li>password if authentication is required</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform this MediaStreamHandler that a new native transport candidate
+ has been ascertained.
+ </tp:docstring>
+ </method>
+ <tp:enum name="Media_Stream_Transport_Type" type="u">
+ <tp:enumvalue suffix="Local" value="0">
+ <tp:docstring>
+ A local address
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Derived" value="1">
+ <tp:docstring>
+ An external address derived by a method such as STUN
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Relay" value="2">
+ <tp:docstring>
+ An external stream relay
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+ <method name="Ready" tp:name-for-bindings="Ready">
+ <arg direction="in" name="Codecs" type="a(usuuua{ss})"
+ tp:type="Media_Stream_Handler_Codec[]">
+ <tp:docstring>
+ Locally-supported codecs.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager that a client is ready to handle
+ this StreamHandler. Also provide it with info about all supported
+ codecs.
+ </tp:docstring>
+ </method>
+ <method name="SetLocalCodecs" tp:name-for-bindings="Set_Local_Codecs">
+ <arg name="Codecs" type="a(usuuua{ss})" direction="in"
+ tp:type="Media_Stream_Handler_Codec[]">
+ <tp:docstring>
+ Locally-supported codecs
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Used to provide codecs after Ready(), so the media client can go
+ ready for an incoming call and exchange candidates/codecs before
+ knowing what local codecs are available.</p>
+
+ <p>This is useful for gatewaying calls between two connection managers.
+ Given an incoming call, you need to call
+ <tp:member-ref>Ready</tp:member-ref> to get the remote codecs before
+ you can use them as the "local" codecs to place the outgoing call,
+ and hence receive the outgoing call's remote codecs to use as the
+ incoming call's "local" codecs.</p>
+
+ <p>In this situation, you would pass an empty list of codecs to the
+ incoming call's Ready method, then later call SetLocalCodecs on the
+ incoming call in order to respond to the offer.</p>
+ </tp:docstring>
+ </method>
+ <signal name="RemoveRemoteCandidate"
+ tp:name-for-bindings="Remove_Remote_Candidate">
+ <arg name="Candidate_ID" type="s">
+ <tp:docstring>
+ String identifier for remote candidate to drop
+ </tp:docstring>
+ </arg>
+ <tp:deprecated version="0.17.18">
+ There is no case where you want to release candidates (except
+ for an ICE reset, and there you'd want to replace then all,
+ using <tp:member-ref>SetRemoteCandidateList</tp:member-ref>).
+ </tp:deprecated>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client that the remote end has removed a previously usable
+ candidate.
+
+ <tp:rationale>
+ It seemed like a good idea at the time, but wasn't.
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+ <signal name="SetActiveCandidatePair"
+ tp:name-for-bindings="Set_Active_Candidate_Pair">
+ <arg name="Native_Candidate_ID" type="s"/>
+ <arg name="Remote_Candidate_ID" type="s"/>
+ <tp:docstring>
+ Emitted by the connection manager to inform the client that a
+ valid candidate pair has been discovered by the remote end
+ and streaming is in progress.
+ </tp:docstring>
+ </signal>
+ <signal name="SetRemoteCandidateList"
+ tp:name-for-bindings="Set_Remote_Candidate_List">
+ <arg name="Remote_Candidates" type="a(sa(usuussduss))"
+ tp:type="Media_Stream_Handler_Candidate[]">
+ <tp:docstring>
+ A list of candidate id and a list of transports
+ as defined in NewNativeCandidate
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client of all the available remote candidates at once.
+ </tp:docstring>
+ </signal>
+ <signal name="SetRemoteCodecs" tp:name-for-bindings="Set_Remote_Codecs">
+ <arg name="Codecs" type="a(usuuua{ss})"
+ tp:type="Media_Stream_Handler_Codec[]">
+ <tp:docstring>
+ Codecs supported by the remote peer.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client of the codecs supported by the remote end.
+ If these codecs are compatible with the remote codecs, then the client
+ must call <tp:member-ref>SupportedCodecs</tp:member-ref>,
+ otherwise call <tp:member-ref>Error</tp:member-ref>.
+ </tp:docstring>
+ </signal>
+ <signal name="SetStreamPlaying" tp:name-for-bindings="Set_Stream_Playing">
+ <arg name="Playing" type="b"/>
+ <tp:docstring>
+ If emitted with argument TRUE, this means that the connection manager
+ wishes to set the stream playing; this means that the streaming
+ implementation should expect to receive data. If emitted with argument
+ FALSE this signal is basically meaningless and should be ignored.
+
+ <tp:rationale>
+ We're very sorry.
+ </tp:rationale>
+ </tp:docstring>
+ </signal>
+ <signal name="SetStreamSending" tp:name-for-bindings="Set_Stream_Sending">
+ <arg name="Sending" type="b"/>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to set whether or not
+ the stream sends to the remote end.
+ </tp:docstring>
+ </signal>
+ <signal name="StartTelephonyEvent"
+ tp:name-for-bindings="Start_Telephony_Event">
+ <arg name="Event" type="y" tp:type="DTMF_Event">
+ <tp:docstring>
+ A telephony event code.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that a telephony event (as defined by RFC 4733) is transmitted
+ over this stream until StopTelephonyEvent is called.
+ </tp:docstring>
+ </signal>
+ <signal name="StartNamedTelephonyEvent"
+ tp:name-for-bindings="Start_Named_Telephony_Event">
+ <tp:added version="0.21.2"/>
+ <arg name="Event" type="y" tp:type="DTMF_Event">
+ <tp:docstring>
+ A telephony event code as defined by RFC 4733.
+ </tp:docstring>
+ </arg>
+ <arg name="Codec_ID" type="u">
+ <tp:docstring>
+ The payload type to use when sending events. The value 0xFFFFFFFF
+ means to send with the already configured event type instead of using
+ the specified one.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that a telephony event (as defined by RFC 4733) is transmitted
+ over this stream until StopTelephonyEvent is called. This differs from
+ StartTelephonyEvent in that you force the event to be transmitted
+ as a RFC 4733 named event, not as sound. You can also force a specific
+ Codec ID.
+ </tp:docstring>
+ </signal>
+ <signal name="StartSoundTelephonyEvent"
+ tp:name-for-bindings="Start_Sound_Telephony_Event">
+ <tp:added version="0.21.2"/>
+ <arg name="Event" type="y" tp:type="DTMF_Event">
+ <tp:docstring>
+ A telephony event code as defined by RFC 4733.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Request that a telephony event (as defined by RFC 4733) is transmitted
+ over this stream until StopTelephonyEvent is called. This differs from
+ StartTelephonyEvent in that you force the event to be transmitted
+ as sound instead of as a named event.
+ </tp:docstring>
+ </signal>
+ <signal name="StopTelephonyEvent"
+ tp:name-for-bindings="Stop_Telephony_Event">
+ <tp:docstring>
+ Request that any ongoing telephony events (as defined by RFC 4733)
+ being transmitted over this stream are stopped.
+ </tp:docstring>
+ </signal>
+ <method name="StreamState" tp:name-for-bindings="Stream_State">
+ <arg direction="in" name="State" type="u" tp:type="Media_Stream_State"/>
+ <tp:docstring>
+ Informs the connection manager of the stream's current state, as
+ as specified in Channel.Type.StreamedMedia::ListStreams.
+ </tp:docstring>
+ </method>
+
+ <method name="SupportedCodecs" tp:name-for-bindings="Supported_Codecs">
+ <arg direction="in" name="Codecs" type="a(usuuua{ss})"
+ tp:type="Media_Stream_Handler_Codec[]">
+ <tp:docstring>
+ Locally supported codecs.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager of the supported codecs for this session.
+ This is called after the connection manager has emitted SetRemoteCodecs
+ to notify what codecs are supported by the peer, and will thus be an
+ intersection of all locally supported codecs (passed to Ready)
+ and those supported by the peer.
+ </tp:docstring>
+ </method>
+
+ <method name="CodecsUpdated" tp:name-for-bindings="Codecs_Updated">
+ <arg direction="in" name="Codecs" type="a(usuuua{ss})"
+ tp:type="Media_Stream_Handler_Codec[]">
+ <tp:docstring>
+ Locally supported codecs, which SHOULD be the same as were previously
+ in effect, but possibly with different parameters.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager that the parameters of the supported
+ codecs for this session have changed. The connection manager should
+ send the new parameters to the remote contact.
+
+ <tp:rationale>
+ This is required for H.264 and Theora, for example.
+ </tp:rationale>
+ </tp:docstring>
+ </method>
+
+ <signal name="SetStreamHeld" tp:name-for-bindings="Set_Stream_Held">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Emitted when the connection manager wishes to place the stream on
+ hold (so the streaming client should free hardware or software
+ resources) or take the stream off hold (so the streaming client
+ should reacquire the necessary resources).</p>
+
+ <p>When placing a channel's streams on hold, the connection manager
+ SHOULD notify the remote contact that this will be done (if
+ appropriate in the protocol) before it emits this signal.</p>
+
+ <tp:rationale>
+ <p>It is assumed that relinquishing a resource will not fail.
+ If it does, the call is probably doomed anyway.</p>
+ </tp:rationale>
+
+ <p>When unholding a channel's streams, the connection manager
+ SHOULD emit this signal and wait for success to be indicated
+ via HoldState before it notifies the remote contact that the
+ channel has been taken off hold.</p>
+
+ <tp:rationale>
+ <p>This means that if a resource is unavailable, the remote
+ contact will never even be told that we tried to acquire it.</p>
+ </tp:rationale>
+ </tp:docstring>
+ <tp:added version="0.17.3"/>
+
+ <arg name="Held" type="b">
+ <tp:docstring>
+ If true, the stream is to be placed on hold.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <method name="HoldState" tp:name-for-bindings="Hold_State">
+ <tp:docstring>
+ Notify the connection manager that the stream's hold state has
+ been changed successfully in response to SetStreamHeld.
+ </tp:docstring>
+ <tp:added version="0.17.3"/>
+ <arg direction="in" name="Held" type="b">
+ <tp:docstring>
+ If true, the stream is now on hold.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="UnholdFailure" tp:name-for-bindings="Unhold_Failure">
+ <tp:docstring>
+ Notify the connection manager that an attempt to reacquire the
+ necessary hardware or software resources to unhold the stream,
+ in response to SetStreamHeld, has failed.
+ </tp:docstring>
+ <tp:added version="0.17.3"/>
+ </method>
+
+ <tp:struct name="RTCP_Feedback_Message_Properties">
+ <tp:added version="0.22.1"/>
+ <tp:changed version="0.23.4">This struct is also used by Call, but
+ in call, the CM should know about RTP profiles, and never use MAXUINT
+ as a default value, because it complicates things unnecessarily.
+ </tp:changed>
+ <tp:member type="u" name="RTCPMinimumInterval">
+ <tp:docstring>
+ The minimum interval between two regular RTCP packets in
+ milliseconds for this content. If no special value is desired, one
+ should put MAXUINT (0xFFFFFFFF).
+
+ Implementors and users of Call's <tp:dbus-ref
+ namespace="ofdT.Call1.Content.MediaDescription.Interface"
+ >RTCPFeedback</tp:dbus-ref> should not use the MAXUINT default.
+ Instead, in RTP/AVP, the default should be 5000 (5 seconds).
+ If using the RTP/AVPF profile, it can be set to a lower value,
+ the default being 0.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="a(sss)" tp:type="RTCP_Feedback_Message[]"
+ name="Messages">
+ <tp:docstring>
+ The RTCP feedback messages for this codec.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="RTCP_Feedback_Message"
+ array-name="RTCP_Feedback_Message_List">
+ <tp:added version="0.22.1"/>
+ <tp:docstring>
+ A struct defining an RTCP feedback message.
+ </tp:docstring>
+ <tp:member type="s" name="Type">
+ <tp:docstring>
+ Feedback type, for example "ack", "nack", or "ccm".
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Subtype">
+ <tp:docstring>
+ Feedback subtype, according to the Type, can be an empty string (""),
+ if there is no subtype.
+ For example, generic nack is Type="nack" Subtype="".
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Parameters">
+ <tp:docstring>
+ Feedback parameters as a string. Format is defined in the relevant RFC
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:mapping name="RTCP_Feedback_Message_Map">
+ <tp:added version="0.22.1"/>
+ <tp:docstring>
+ A map of codec and its feedback properties.
+ </tp:docstring>
+ <tp:member type="u" name="Codec_Identifier">
+ <tp:docstring>
+ Numeric identifier for the codec. This will be used as the
+ PT in the SDP or content description.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="(ua(sss))" tp:type="RTCP_Feedback_Message_Properties"
+ name="Properties">
+ <tp:docstring>
+ The RTCP feedback properties for this codec.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <signal name="SetRemoteFeedbackMessages"
+ tp:name-for-bindings="Set_Remote_Feedback_Messages">
+ <tp:added version="0.22.1"/>
+ <arg name="Messages" type="a{u(ua(sss))}"
+ tp:type="RTCP_Feedback_Message_Map">
+ <tp:docstring>
+ Remote Feedback messages desired by the remote side
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client of the feedback messages supported by the remote end.
+ This signal is emitted before
+ <tp:member-ref>SetRemoteCodecs</tp:member-ref>. If the client
+ supports any of these messages, it must call
+ <tp:member-ref>SupportedFeedbackMessages</tp:member-ref> before calling
+ <tp:member-ref>SupportedCodecs</tp:member-ref>.
+ </tp:docstring>
+ </signal>
+
+ <method name="SupportedFeedbackMessages"
+ tp:name-for-bindings="Supported_Feedback_Messages">
+ <tp:added version="0.22.1"/>
+ <arg name="Messages" direction="in" type="a{u(ua(sss))}"
+ tp:type="RTCP_Feedback_Message_Map">
+ <tp:docstring>
+ Locally supported feedback messages.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager of the supported feedback messages
+ for this session.
+ This is called a before calling
+ <tp:member-ref>SupportedCodecs</tp:member-ref>,
+ <tp:member-ref>Ready</tp:member-ref> or
+ <tp:member-ref>CodecsUpdated</tp:member-ref> to indicate the local,
+ or negotiated feedback messages.
+ </tp:docstring>
+ </method>
+
+ <tp:struct name="RTP_Header_Extension"
+ array-name="RTP_Header_Extensions_List">
+ <tp:added version="0.22.1"/>
+ <tp:docstring>
+ A struct defining a RTP Header extension
+ </tp:docstring>
+ <tp:member type="u" name="ID">
+ <tp:docstring>
+ Identifier to be negotiated
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="u" tp:type="Media_Stream_Direction" name="Direction">
+ <tp:docstring>
+ Direction in which the Header Extension is negotiated.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="URI">
+ <tp:docstring>
+ URI defining the extension
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="s" name="Parameters">
+ <tp:docstring>
+ Feedback parameters as a string. Format is defined in the relevant RFC
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <signal name="SetRemoteHeaderExtensions"
+ tp:name-for-bindings="Set_Remote_Header_Extensions">
+ <tp:added version="0.22.1"/>
+ <arg name="Header_Extensions" type="a(uuss)"
+ tp:type="RTP_Header_Extension[]">
+ <tp:docstring>
+ Header extensions desired by the remote side
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Signal emitted when the connection manager wishes to inform the
+ client of the RTP header extensions supported by the remote end.
+ This signal is emitted before
+ <tp:member-ref>SetRemoteCodecs</tp:member-ref>. If the client
+ supports any of these messages, it must call
+ <tp:member-ref>SupportedHeaderExtensions</tp:member-ref> before calling
+ <tp:member-ref>SupportedCodecs</tp:member-ref>.
+ </tp:docstring>
+ </signal>
+
+ <method name="SupportedHeaderExtensions"
+ tp:name-for-bindings="Supported_Header_Extensions">
+ <tp:added version="0.22.1"/>
+ <arg name="Header_Extensions" direction="in" type="a(uuss)"
+ tp:type="RTP_Header_Extension[]">
+ <tp:docstring>
+ Locally supported RTP header extensions.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Inform the connection manager of the supported RTP header extensions
+ for this session.
+ This is called before calling
+ <tp:member-ref>SupportedCodecs</tp:member-ref>,
+ <tp:member-ref>Ready</tp:member-ref> or
+ <tp:member-ref>CodecsUpdated</tp:member-ref> to indicate the local
+ or negotiated RTP header extensions.
+ </tp:docstring>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Properties_Interface.xml b/spec/spec/Properties_Interface.xml
new file mode 100644
index 000000000..09ce3b9c2
--- /dev/null
+++ b/spec/spec/Properties_Interface.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" ?>
+<node name="/Properties_Interface" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright> Copyright (C) 2005-2007 Collabora Limited </tp:copyright>
+ <tp:copyright> Copyright (C) 2005, 2006 Nokia Corporation </tp:copyright>
+ <tp:copyright> Copyright (C) 2006 INdT </tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Properties">
+ <tp:deprecated version="0.24.0">All uses of this interface have been
+ expunged, and it may now be laid to rest.</tp:deprecated>
+
+ <tp:struct name="Property_Spec" array-name="Property_Spec_List">
+ <tp:docstring>A struct (property ID, property name, D-Bus signature,
+ flags) representing a property, as returned by ListProperties on the
+ Properties interface.</tp:docstring>
+ <tp:member type="u" name="Property_ID"/>
+ <tp:member type="s" name="Name"/>
+ <tp:member type="s" tp:type="DBus_Signature" name="Signature"/>
+ <tp:member type="u" tp:type="Property_Flags" name="Flags"/>
+ </tp:struct>
+
+ <tp:struct name="Property_Flags_Change"
+ array-name="Property_Flags_Change_List">
+ <tp:docstring>A struct (property ID, flags) representing a change to
+ a property's flags, as seen in the PropertyFlagsChanged signal on
+ the Properties interface.</tp:docstring>
+ <tp:member type="u" name="Property_ID"/>
+ <tp:member type="u" name="New_Flags"/>
+ </tp:struct>
+
+ <tp:simple-type name="Property_ID" type="u" array-name="Property_ID_List">
+ <tp:docstring>
+ An unsigned integer used to represent a Telepathy property.
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:struct name="Property_Value" array-name="Property_Value_List">
+ <tp:docstring>A struct (property ID, value) representing a
+ property's value, as seen in the PropertiesChanged signal on
+ the Properties interface, returned by the GetProperties method
+ and passed to the SetProperties method.</tp:docstring>
+ <tp:member type="u" tp:type="Property_ID" name="Identifier"/>
+ <tp:member type="v" name="Value"/>
+ </tp:struct>
+
+ <method name="GetProperties" tp:name-for-bindings="Get_Properties">
+ <tp:docstring>
+ Returns an array of (identifier, value) pairs containing the current
+ values of the given properties.
+ </tp:docstring>
+ <arg direction="in" name="Properties" type="au" tp:type="Property_ID[]">
+ <tp:docstring>An array of property identifiers</tp:docstring>
+ </arg>
+ <arg direction="out" type="a(uv)" tp:type="Property_Value[]"
+ name="Values">
+ <!-- XXX: if we're ever breaking API compatibility, make this a{uv} -->
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of structs containing:</p>
+ <ul>
+ <li>integer identifiers</li>
+ <li>variant boxed values</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ Some property identifier requested is invalid
+ </tp:docstring>
+ </tp:error>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied">
+ <tp:docstring>
+ Some property requested does not have the PROPERTY_FLAG_READ flag
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+ <method name="ListProperties" tp:name-for-bindings="List_Properties">
+ <tp:docstring>
+ Returns a dictionary of the properties available on this channel.
+ </tp:docstring>
+ <arg direction="out" type="a(ussu)" tp:type="Property_Spec[]"
+ name="Available_Properties">
+ <!-- XXX: if we're ever breaking API compatibility, make this
+ a{u(ssu)} ? -->
+ <tp:docstring>
+ An array of structs containing:
+ <ul>
+ <li>an integer identifier</li>
+ <li>a string property name</li>
+ <li>a string representing the D-Bus signature of this property</li>
+ <li>a bitwise OR of the flags applicable to this property</li>
+ </ul>
+ </tp:docstring>
+ </arg>
+ </method>
+ <signal name="PropertiesChanged" tp:name-for-bindings="Properties_Changed">
+ <tp:docstring>
+ Emitted when the value of readable properties has changed.
+ </tp:docstring>
+ <arg name="Properties" type="a(uv)" tp:type="Property_Value[]">
+ <!-- XXX: if we're ever breaking API compatibility, make this a{uv} -->
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of structs containing:</p>
+ <ul>
+ <li>integer identifiers</li>
+ <li>variant boxed values</li>
+ </ul>
+ <p>The array should contain only properties whose values have
+ actually changed.</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+ <signal name="PropertyFlagsChanged"
+ tp:name-for-bindings="Property_Flags_Changed">
+ <tp:docstring>
+ Emitted when the flags of some room properties have changed.
+ </tp:docstring>
+ <arg name="Properties" type="a(uu)" tp:type="Property_Flags_Change[]">
+ <!-- XXX: if we're ever breaking API compatibility, make this a{uu} -->
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An array of structs containing:</p>
+ <ul>
+ <li>integer identifiers</li>
+ <li>a bitwise OR of the current flags</li>
+ </ul>
+ <p>The array should contain only properties whose flags have actually
+ changed.</p>
+ </tp:docstring>
+ </arg>
+ </signal>
+ <method name="SetProperties" tp:name-for-bindings="Set_Properties">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Takes an array of (identifier, value) pairs containing desired
+ values to set the given properties. In the case of any errors, no
+ properties will be changed. When the changes have been acknowledged
+ by the server, the PropertiesChanged signal will be emitted.</p>
+
+ <p>All properties given must have the PROPERTY_FLAG_WRITE flag, or
+ PermissionDenied will be returned. If any variants are of the wrong
+ type, NotAvailable will be returned. If any given property identifiers
+ are invalid, InvalidArgument will be returned.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="Properties" type="a(uv)"
+ tp:type="Property_Value[]">
+ <!-- XXX: if we're ever breaking API compatibility, make this a{uv} -->
+ <tp:docstring>
+ An array mapping integer property identifiers to boxed values
+ </tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
+ <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
+ </tp:possible-errors>
+ </method>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Interface for channels and other objects, to allow querying and setting
+ properties. ListProperties returns which properties are valid for
+ the given channel, including their type, and an integer handle used to
+ refer to them in GetProperties, SetProperties, and the PropertiesChanged
+ signal. The values are represented by D-Bus variant types, and are
+ accompanied by flags indicating whether or not the property is readable or
+ writable.</p>
+
+ <p>Each property also has a flags value to indicate what methods are
+ available. This is a bitwise OR of PropertyFlags values.</p>
+ </tp:docstring>
+ <tp:flags name="Property_Flags" value-prefix="Property_Flag" type="u">
+ <tp:flag suffix="Read" value="1">
+ <tp:docstring>The property can be read</tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="Write" value="2">
+ <tp:docstring>The property can be written</tp:docstring>
+ </tp:flag>
+ </tp:flags>
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Protocol.xml b/spec/spec/Protocol.xml
new file mode 100644
index 000000000..f779492f3
--- /dev/null
+++ b/spec/spec/Protocol.xml
@@ -0,0 +1,490 @@
+<?xml version="1.0" ?>
+<node name="/Protocol"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Protocol">
+ <tp:added version="0.19.10">(as stable API)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An object representing a protocol for which this <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ConnectionManager</tp:dbus-ref>
+ can create <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>s.</p>
+
+ <p>Each Protocol object has the same well-known bus name as its parent
+ ConnectionManager. Its object path is formed by taking the
+ ConnectionManager's object path and appending '/', followed by the
+ <tp:type>Protocol</tp:type> name with any hyphen/minus '-' converted
+ to underscores '_'.</p>
+
+ <tp:rationale>
+ <p>This is the same as the representation of protocol names
+ in Account object paths, and in Connection object paths and bus
+ names. For instance, telepathy-gabble and telepathy-salut would
+ implement objects at
+ <code>/org/freedesktop/Telepathy/ConnectionManager/gabble/jabber</code>
+ and
+ <code>/org/freedesktop/Telepathy/ConnectionManager/salut/local_xmpp</code>,
+ respectively.</p>
+ </tp:rationale>
+
+ <p>If the ConnectionManager has a <tt>.manager</tt> file, each
+ Protocol's immutable properties must be represented in that file;
+ the representation is described as part of the documentation for
+ each property. For instance, a very simple ConnectionManager with one
+ Protocol might be represented like this:</p>
+
+<pre>
+[ConnectionManager]
+Interfaces=
+
+[Protocol example]
+Interfaces=
+ConnectionInterfaces=org.freedesktop.Telepathy.Connection.Interface.Requests;
+param-account=s required
+param-password=s required secret
+RequestableChannelClasses=text;
+VCardField=x-example
+EnglishName=Example
+Icon=im-example
+AuthenticationTypes=org.freedesktop.Telepathy.Channel.Type.ServerTLSConnection;org.freedesktop.Telepathy.Channel.Interface.SASLAuthentication;
+
+[text]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;
+</pre>
+ </tp:docstring>
+
+ <property name="Interfaces" tp:name-for-bindings="Interfaces"
+ access="read" type="as" tp:type="DBus_Interface[]"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of interfaces supported by this Protocol object.</p>
+
+ <p>This property should not be confused with
+ <tp:member-ref>ConnectionInterfaces</tp:member-ref>,
+ which refers to the interfaces of <em>connections</em> to this
+ protocol.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ (as described as part of the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >ConnectionManager</tp:dbus-ref> interface) MUST cache this
+ property in the protocol's section of the <code>.manager</code>
+ file, using the key <code>Interfaces</code>. The corresponding value
+ is a list of D-Bus interface names, each followed by a semicolon.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Parameters" tp:name-for-bindings="Parameters"
+ access="read" type="a(susv)" tp:type="Param_Spec[]"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The parameters which may be specified in the
+ <tp:dbus-ref namespace='ofdT.Account'>Parameters</tp:dbus-ref> of an
+ <tp:dbus-ref namespace='ofdT'>Account</tp:dbus-ref> (or, for
+ specialised applications which do not use the account manager, passed
+ to <tp:dbus-ref
+ namespace='ofdT.ConnectionManager'>RequestConnection</tp:dbus-ref>).
+ Some parameters are mandatory, and some parameters only make sense
+ when registering new accounts with the server; see the
+ <tp:type>Param_Spec</tp:type> documentation for more details.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ (as described as part of the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >ConnectionManager</tp:dbus-ref> interface) MUST cache this
+ property in the protocol's section of the <code>.manager</code>
+ file via keys of the form <code>param-<em>p</em></code> and
+ <code>default-<em>p</em></code>, as documented in the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >ConnectionManager</tp:dbus-ref> interface.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="ConnectionInterfaces"
+ tp:name-for-bindings="Connection_Interfaces"
+ access="read" type="as" tp:type="DBus_Interface[]"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of interface names which might be in the
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection"
+ >Interfaces</tp:dbus-ref> property of a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection</tp:dbus-ref> to this protocol. Whether a Connection
+ will have all, some or none of these interfaces depends on server
+ capabilities.</p>
+
+ <p>This property should not be confused with
+ <tp:member-ref>Interfaces</tp:member-ref>.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file, using the key
+ <code>ConnectionInterfaces</code>. The corresponding value
+ is a list of D-Bus interface names, each followed by a semicolon.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="RequestableChannelClasses"
+ tp:name-for-bindings="Requestable_Channel_Classes"
+ access="read" type="a(a{sv}as)" tp:type="Requestable_Channel_Class[]"
+ tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of channel classes which might be requestable from a
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection</tp:dbus-ref> to this protocol (i.e. they will,
+ or might, appear in the Connection's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+ >RequestableChannelClasses</tp:dbus-ref> property).</p>
+
+ <p>Whether a Connection will have all, some or none of these
+ requestable channel classes depends on server capabilities;
+ similarly, individual contacts are not guaranteed to support
+ all of these channel classes.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file, using the key
+ <code>RequestableChannelClasses</code>. The corresponding value
+ is a list of opaque strings, each followed by a semicolon; each
+ of those strings is the name of a group in the <code>.manager</code>
+ file which represents a channel class.</p>
+
+ <p>The names of the groups representing channel classes are not
+ significant, and MUST NOT be interpreted. When writing
+ <tt>.manager</tt> files, authors MAY choose mnemonic group names,
+ generate group names mechanically (e.g. with an incrementing
+ integer), or use some combination of these.</p>
+
+ <p>Each group representing a channel class has a key
+ <code>allowed</code> which is a list of D-Bus property names
+ representing allowed parameters. Any other keys that do not contain
+ a space MUST be ignored. Any key containing a space represents
+ a fixed property; the key has the form
+ "<code><em>propertyname</em> <em>type</em></code>", and the value
+ is encoded in the same way as for the <code>default-<em>p</em></code>
+ keys described in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >ConnectionManager</tp:dbus-ref> documentation.</p>
+
+ <p>Connection managers that have channel classes whose fixed
+ properties are not representable in this form SHOULD NOT have
+ <code>.manager</code> files.</p>
+
+ <p>For instance, this <code>.manager</code> file could represent
+ a connection manager that supports 1-1 Text messages and
+ StreamedMedia audio calls:</p>
+
+<pre>[Protocol jabber]
+param-account=s required
+param-password=s required
+RequestableChannelClasses=rcc0;rcc1;
+
+[rcc0]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;
+
+[rcc1]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.StreamedMedia
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio;
+</pre>
+ </tp:docstring>
+ </property>
+
+ <property name="VCardField" tp:name-for-bindings="VCard_Field"
+ access="read" type="s" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the most common vCard field used for this protocol's
+ contact identifiers, normalized to lower case, or the empty string
+ if there is no such field.</p>
+
+ <p>For example, this would be <code>x-jabber</code> for
+ Jabber/XMPP (including Google Talk), or <code>tel</code> for
+ the <abbr title="Public Switched Telephone Network">PSTN</abbr>.</p>
+
+ <p>A more exhaustive list of addressable vCard fields can be found in
+ the Protocol's Addressing interface's
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Protocol.Interface.Addressing">AddressableVCardFields</tp:dbus-ref>.</p>
+
+ <p>It is not necessarily valid to interpret contacts' identifiers
+ as values of this vCard field. For instance, telepathy-sofiasip
+ supports contacts whose identifiers are of the form
+ sip:jenny@example.com or tel:8675309, which would not normally
+ both be represented by any single vCard field. Arbitrary
+ handles/identifiers as vCard fields are represented
+ through the Connection's
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Addressing.DRAFT</tp:dbus-ref>
+ contact attributes.</p>
+
+ <tp:rationale>
+ <p>This is taken from Mission Control profiles as used on Maemo 5.
+ One valid use of this field is to answer the question: given a
+ contact's vCard containing an X-JABBER field, how can you
+ communicate with the contact? By iterating through protocols
+ looking for an x-jabber VCardField, one can build up a list of
+ protocols that handle x-jabber, then offer the user a list of
+ accounts for those protocols and/or the option to create a new
+ account for one of those protocols.</p>
+ </tp:rationale>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file if it is non-empty, using the key
+ <code>VCardField</code>. The corresponding value
+ is a string, following the syntax of the "localestring" type from
+ the Desktop Entry Specification.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="EnglishName" tp:name-for-bindings="English_Name"
+ access="read" type="s" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the protocol in a form suitable for display to users,
+ such as "AIM" or "Yahoo!", or the empty string if none is
+ available.</p>
+
+ <p>This is effectively in the C locale (international English);
+ user interfaces requiring a localized protocol name SHOULD look
+ one up in their own message catalog based on either the Telepathy
+ <tp:type>Protocol</tp:type> name or this property, but SHOULD use
+ this English version as a fallback if no translated version can be
+ found.</p>
+
+ <tp:rationale>
+ <p>Many protocols are named after a company or product which isn't
+ translated in non-English locales. This also provides a fallback
+ display name, for UIs with no prior knowledge of a particular
+ protocol.</p>
+ </tp:rationale>
+
+ <p>If this property's value is empty, clients MAY fall back to using
+ the Telepathy <tp:type>Protocol</tp:type> name, possibly with its
+ capitalization adjusted.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file if it is non-empty, using the key
+ <code>EnglishName</code>. The corresponding value
+ is a string, following the syntax of the "localestring" type from
+ the Desktop Entry Specification.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="Icon" tp:name-for-bindings="Icon"
+ access="read" type="s" tp:immutable="yes">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of an icon in the system's icon theme, such as "im-msn", or
+ the empty string.</p>
+
+ <tp:rationale>
+ <p>This can be used as a default if the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account">Icon</tp:dbus-ref>
+ property is not set on an Account, or used by the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">AccountManager</tp:dbus-ref>
+ to choose a default icon if none is set during account
+ creation.</p>
+ </tp:rationale>
+
+ <p>If this property's value is empty, clients MAY fall back to
+ generating a name based on the <tp:type>Protocol</tp:type> name.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file if it is non-empty, using the key
+ <code>Icon</code>. The corresponding value
+ is a string, following the syntax of the "localestring" type from
+ the Desktop Entry Specification.</p>
+ </tp:docstring>
+ </property>
+
+ <method name="IdentifyAccount"
+ tp:name-for-bindings="Identify_Account">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Return a string which uniquely identifies the account to which the
+ given parameters would connect.</p>
+
+ <tp:rationale>
+ <p>For many protocols, this would return the well-known 'account'
+ parameter. However, for IRC the returned string would be composed
+ from the 'account' (i.e. nickname) and 'server' parameters.
+ AccountManager implementations can use this to form the
+ account-specific part of an Account's object path.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Parameters"
+ type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring>
+ A set of parameters as would be provided to <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.ConnectionManager"
+ >RequestConnection</tp:dbus-ref>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Account_ID" type="s">
+ <tp:docstring>
+ <p>An opaque string suitable for use as the account-specific part of
+ an <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Account</tp:dbus-ref>'s object path. This is not necessarily
+ globally unique, but should represent a "best-effort"
+ identification of the account.</p>
+
+ <tp:rationale>
+ <p>For a pathological case, consider a user signing in as
+ 'me@example.com' with 'server' set to either jabber1.example.com
+ or jabber2.example.com. Both of these should result in
+ me@example.com being returned from this method, even if the user
+ can actually be signed in to those two servers
+ simultaneously.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The IdentifyAccount method is not supported by this connection
+ manager. The caller SHOULD fall back to deriving identification
+ from the parameters.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="NormalizeContact"
+ tp:name-for-bindings="Normalize_Contact">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Attempt to normalize the given contact ID. Where possible, this
+ SHOULD return the same thing that would be returned by
+ InspectHandles(RequestHandles(CONTACT, [Contact_ID])) on a connected
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection</tp:dbus-ref>.</p>
+
+ <p>If full normalization requires network activity or is otherwise
+ impossible to do without a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>,
+ this method SHOULD perform a best-effort normalization.</p>
+
+ <tp:rationale>
+ <p>One common example of a best-effort offline normalization
+ differing from the ideal normalization is XMPP.</p>
+
+ <p>On XMPP, contacts' JIDs should normally have the resource removed
+ during normalization, but for contacts in a MUC (chatroom), the
+ resource is an integral part of the JID - so the contact JID
+ alice@example.com/Empathy should normalize to alice@example.com,
+ but the in-MUC JID wonderland@conference.example.com/Alice should
+ normalize to itself.</p>
+
+ <p>While online, the connection manager has enough context to know
+ which chatrooms the user is in, and can infer from that whether
+ to remove resources, but the best-effort normalization performed
+ while offline does not have this context, so the best that can be
+ done is to remove the resource from all JIDs.</p>
+ </tp:rationale>
+
+ <p>This method MAY simply raise NotImplemented on some protocols.</p>
+
+ <tp:rationale>
+ <p>In link-local XMPP, you can't talk to someone who isn't present
+ on your local network, so normalizing identifiers in advance is
+ meaningless.</p>
+ </tp:rationale>
+ </tp:docstring>
+
+ <arg direction="in" name="Contact_ID" type="s">
+ <tp:docstring>
+ The identifier of a contact in this protocol
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Normalized_Contact_ID" type="s">
+ <tp:docstring>
+ The identifier of a contact in this protocol, normalized as much
+ as possible
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The NormalizeContact method is not supported by this connection
+ manager. The caller MAY recover by using the contact ID as-is.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <property name="AuthenticationTypes"
+ tp:name-for-bindings="Authentication_Types" access="read" type="as"
+ tp:type="DBus_Interface[]" tp:immutable="yes">
+ <tp:added version="0.21.7"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A list of D-Bus interfaces which provide information as to
+ what kind of authentication channels can possibly appear
+ before the connection reaches the CONNECTED state.</p>
+
+ <p>These can either be channel types, or where the channel
+ type isn't enough information to be useful, interfaces
+ indicating a specific use of a channel type. For example,
+ <tp:dbus-ref namespace="ofdT.Channel.Type">ServerTLSConnection</tp:dbus-ref>
+ channels are obviously about TLS certificates so the channel
+ type would appear in this list. However, a
+ <tp:dbus-ref namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channel type alone does not explain enough about the authentication type
+ in use as it is merely a base for the channel interfaces that appear in
+ said channels. In this case, CMs should use the value of the
+ <tp:dbus-ref namespace="ofdT.Channel.Type">ServerAuthentication.AuthenticationMethod</tp:dbus-ref>
+ property in this list.</p>
+
+ <p>For example, if a protocol's
+ <tp:member-ref>AuthenticationTypes</tp:member-ref> contains
+ two values:</p>
+
+ <blockquote>
+ <pre>
+[ ...<tp:dbus-ref namespace="ofdT">Channel.Type.ServerTLSConnection</tp:dbus-ref>,
+ ...<tp:dbus-ref namespace="ofdT">Channel.Interface.SASLAuthentication</tp:dbus-ref> ]</pre></blockquote>
+
+ <p>This tells a client that before the connection status
+ reached CONNECTED, a <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerTLSConnection</tp:dbus-ref>
+ could appear carrying a TLS certificate. It also tells the
+ client that before the connection status reaches CONNECTED, a
+ <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref>
+ channel could also appear, where <tp:dbus-ref
+ namespace="ofdT.Channel.Type">ServerAuthentication.AuthenticationMethod</tp:dbus-ref>=<tp:dbus-ref
+ namespace="ofdT.Channel.Interface">SASLAuthentication</tp:dbus-ref>. A
+ hypothetical future Channel.Interface.Captcha interface would
+ also appear in this list if the CM might require the user
+ solve a captcha before connecting.</p>
+
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Protocol_Interface_Addressing.xml b/spec/spec/Protocol_Interface_Addressing.xml
new file mode 100644
index 000000000..0c62e1bd9
--- /dev/null
+++ b/spec/spec/Protocol_Interface_Addressing.xml
@@ -0,0 +1,335 @@
+<?xml version="1.0" ?>
+<node name="/Protocol_Interface_Addressing"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface
+ name="org.freedesktop.Telepathy.Protocol.Interface.Addressing">
+ <tp:added version="0.25.1">(as stable API). From the draft,
+ NormalizeURI was renamed to NormalizeContactURI, clarifying that
+ it removes any actions from the URI.</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for protocols that support multiple forms of
+ addressing contacts, for example through vCard addresses and URIs.</p>
+
+ <p>If the ConnectionManager has a <tt>.manager</tt> file, and it
+ supports this interface, the interface's immutable properties
+ must be represented in the file; the representation is described as
+ part of the documentation for each property.</p>
+
+ <p>For instance, a SIP connection manager might have the
+ following lines in the <tt>.manager</tt> file.</p>
+
+<pre>
+[Protocol sip]
+AddressableVCardFields=tel;x-sip;
+AddressableURISchemes=tel;sip;
+</pre>
+ </tp:docstring>
+
+ <property name="AddressableVCardFields"
+ tp:name-for-bindings="Addressable_VCard_Fields"
+ access="read" type="as">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The vCard fields that can be used to request a contact with
+ normalized to lower case. If the <code>URL</code> vCard
+ field is addressable, a colon, followed by the supported URI
+ schemes will be concatenated.</p>
+
+ <p>For example: <code>["tel", "x-sip"]</code>.</p>
+
+ <p>The <code>url</code> vCard field MUST NOT appear here; see
+ <tp:member-ref>AddressableURISchemes</tp:member-ref> instead.</p>
+
+ <tp:rationale>
+ <p>In practice, protocols have a limited set of URI
+ schemes that make sense to resolve as a contact.</p>
+ </tp:rationale>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file if it is non-empty, using the key
+ <code>AddressableVCardFields</code>. The corresponding value
+ is a list of strings, each followed with a semicolon and in the
+ syntax of the "localestring" type from the Desktop Entry
+ Specification.</p>
+
+ <p>Well-known vCard fields:</p>
+
+ <dl>
+ <dt><code>tel</code></dt>
+ <dd>The TEL vCard field. Used for phone numbers.</dd>
+ <dt><code>x-sip</code></dt>
+ <dd>The X-SIP vCard field. Used for SIP addresses.</dd>
+ <dt><code>x-aim</code></dt>
+ <dd>The X-AIM vCard field. Used for AIM user IDs.</dd>
+ <dt><code>x-icq</code></dt>
+ <dd>The X-ICQ vCard field. Used for ICQ UINs.</dd>
+ <dt><code>x-skype</code></dt>
+ <dd>The X-SKYPE vCard field. Used for Skype user names or
+ telephone numbers. There is also a X-SKYPE-USERNAME field,
+ but for Telepathy purposes, <code>x-skype</code> is preferred</dd>
+ <dt><code>x-groupwise</code></dt>
+ <dd>The X-GROUPWISE vCard field. Used for Groupwise contacts.</dd>
+ <dt><code>x-gadugadu</code></dt>
+ <dd>The X-GADUGADU vCard field. Used for Gadu-Gadu contacts.</dd>
+ <dt><code>x-jabber</code></dt>
+ <dd>The X-JABBER vCard field. Used for XMPP JIDs.</dd>
+ <dt><code>x-msn</code></dt>
+ <dd>The X-MSN vCard field. Used for MSN contacts.</dd>
+ <dt><code>x-yahoo</code></dt>
+ <dd>The X-YAHOO vCard field. Used for Yahoo! IDs.</dd>
+ <dt><code>x-facebook-id</code></dt>
+ <dd>Used for Facebook IDs in XMPP. If the user JID is
+ "-12345@chat.facebook.com" then the x-facebook-id is "12345"</dd>
+ </dl>
+
+ </tp:docstring>
+ </property>
+
+ <property name="AddressableURISchemes"
+ tp:name-for-bindings="Addressable_URI_Schemes"
+ access="read" type="as">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The URI schemes that are supported by this protocol.</p>
+
+ <p>For example: <code>["tel", "sip"]</code>.</p>
+
+ <p>This property should only be used when the connection is
+ offline. When it is connected the addressable URI schemes should be
+ retrieved from the
+ <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection.Interface">Requests.RequestableChannelClasses</tp:dbus-ref>'s
+ TargetURIScheme fixed-property instead.</p>
+
+ <p>Connection managers with a <code>.manager</code> file
+ MUST cache this property in the protocol's section of the
+ <code>.manager</code> file if it is non-empty, using the key
+ <code>AddressableURISchemes</code>. The corresponding value
+ is a list of strings, each followed with a semicolon and in the
+ syntax of the "localestring" type from the Desktop Entry
+ Specification.</p>
+
+ <p>Well-known URI schemes:</p>
+
+ <dl>
+ <dt><code>sip</code></dt>
+ <dd>SIP protocol.
+ For example: <code>sip:julien@example.com</code>.</dd>
+ <dt><code>sips</code></dt>
+ <dd>Secure (encrypted) SIP protocol.
+ For example: <code>sips:julien@example.com</code>.</dd>
+ <dt><code>tel</code></dt>
+ <dd>Used for telephone numbers.
+ For example: <code>tel:+12065551234</code>.</dd>
+ <dt><code>xmpp</code></dt>
+ <dd>XMPP protocol.
+ For example: <code>xmpp:julien@example.com</code>.</dd>
+ <dt><code>msnim</code></dt>
+ <dd>For the purposes of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Protocol.Interface.Addressing</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ the verb part is ignored, and SHOULD be <code>add</code>; the
+ <code>contact</code> field in the query string is used to
+ identify the contact.
+ For example: <code>msnim:add?contact=julien</code>.</dd>
+ <dt><code>aim</code></dt>
+ <dd>For the purposes of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Protocol.Interface.Addressing</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ the verb part is ignored, and SHOULD be <code>addbuddy</code>; the
+ <code>screenname</code> field in the query string is used to
+ identify the contact.
+ For example: <code>aim:addbuddy?screenname=julien</code>.</dd>
+ <dt><code>skype</code></dt>
+ <dd>Skype protocol.
+ For example: <code>skype:julien</code>.</dd>
+ <dt><code>ymsgr</code></dt>
+ <dd>For the purposes of
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Protocol.Interface.Addressing</tp:dbus-ref>,
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ and
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Channel.Interface.Addressing.DRAFT</tp:dbus-ref>,
+ the verb part is ignored, and SHOULD be <code>addfriend</code>; the
+ query string is used to identify the contact.
+ For example: <code>ymsgr:addfriend?julien</code>.</dd>
+ <dt><code>gg</code></dt>
+ <dd>Gadu-Gadu protocol.
+ For example: <code>gg:julien</code>.</dd>
+ </dl>
+ </tp:docstring>
+ </property>
+
+ <method name="NormalizeVCardAddress"
+ tp:name-for-bindings="Normalize_VCard_Address">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Attempt to normalize the given vCard address. Where possible, this
+ SHOULD return an address that would appear in the
+ <code>org.freedesktop.Telepathy.Connection.Interface.Addressing.DRAFT/addresses</code>
+ attribute for a contact on a connected
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>.
+ </p>
+
+ <p>If full normalization requires network activity or is otherwise
+ impossible to do without a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>,
+ this method SHOULD perform a best-effort normalization.</p>
+
+ <p>An example would be a vCard TEL field with a formatted
+ number in the form of <code>+1 (206) 555 1234</code>, this would be
+ normalized to <code>+12065551234</code>.</p>
+
+ <p>This method MAY simply raise NotImplemented on some
+ protocols, if it has no use.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="VCard_Field" type="s">
+ <tp:docstring>
+ The vCard field of the address we are normalizing. The
+ field name SHOULD be in lower case, and MUST appear in
+ <tp:member-ref>AddressableVCardFields</tp:member-ref>.
+ </tp:docstring>
+ </arg>
+
+ <arg direction="in" name="VCard_Address" type="s">
+ <tp:docstring>
+ The address to normalize, which is assumed to belong to a
+ contact (and not, for instance, a chatroom or server).
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Normalized_VCard_Address" type="s">
+ <tp:docstring>
+ The vCard address, normalized as much as possible.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The vCard field is not supported (it is not in
+ <tp:member-ref>AddressableVCardFields</tp:member-ref>).
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ The address is syntactically incorrect.
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ <method name="NormalizeContactURI"
+ tp:name-for-bindings="Normalize_Contact_URI">
+ <tp:added version="0.25.1">(renamed from NormalizeURI)</tp:added>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Attempt to normalize the given contact URI. Where possible, this
+ SHOULD return an address that would appear in the
+ <code>org.freedesktop.Telepathy.Connection.Interface.Addressing.DRAFT/uris</code>
+ attribute for a contact on a connected
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>.
+ </p>
+
+ <p>If full normalization requires network activity or is otherwise
+ impossible to do without a <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Connection</tp:dbus-ref>,
+ this method SHOULD perform a best-effort normalization.</p>
+
+ <p>If the URI has extra information beyond what's necessary to
+ identify a particular contact, such as an XMPP resource or an
+ action to carry out, this extra information SHOULD be removed.
+ If all URIs in a scheme contain a verb or action
+ (like <code>aim</code>, <code>ymsgr</code> and
+ <code>msnim</code> URIs), then the verb SHOULD be replaced
+ with the one specified in
+ <tp:member-ref>AddressableURISchemes</tp:member-ref>.</p>
+
+ <tp:rationale>
+ <p>This method is intended to normalize URIs stored in address
+ books, for instance. In protocols like XMPP, if you
+ vary the resource or action (query string), the URI still
+ refers to the same high-level contact.</p>
+ </tp:rationale>
+
+ <p>For instance,
+ <code>xmpp:romeo@Example.Com/Empathy?message;body=Hello</code>
+ would be normalized to <code>xmpp:romeo@example.com</code>,
+ and <code>aim:goim?screenname=Romeo%20M&amp;message=Hello</code>
+ would be normalized to
+ <code>aim:addbuddy?screenname=romeom</code>.</p>
+
+ <p>This method MAY simply raise NotImplemented on some
+ protocols, if it has no use.</p>
+ </tp:docstring>
+
+ <arg direction="in" name="URI" type="s">
+ <tp:docstring>
+ <p>The URI to normalize, which is assumed to refer to a contact
+ (as opposed to, for instance, a chatroom or a server).</p>
+
+ <tp:rationale>
+ <p>In some protocols, like XMPP, there is no way to tell whether
+ a given URI refers to a contact or a chatroom by looking at
+ its syntax.</p>
+ </tp:rationale>
+
+ <p>The URI's scheme (i.e. the part before
+ the first colon) MUST appear in
+ <tp:member-ref>AddressableURISchemes</tp:member-ref>.</p>
+ </tp:docstring>
+ </arg>
+
+ <arg direction="out" name="Normalized_URI" type="s">
+ <tp:docstring>
+ A URI, normalized as much as possible.
+ </tp:docstring>
+ </arg>
+
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
+ <tp:docstring>
+ The URI scheme is not supported (it is not in
+ <tp:member-ref>AddressableURISchemes</tp:member-ref>).
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
+ <tp:docstring>
+ <p>The URI is syntactically incorrect or cannot be interpreted
+ as a reference to a contact.</p>
+
+ <tp:rationale>
+ <p>For instance, <code>aim:!?</code> is not a valid AIM URI,
+ while <code>aim:goaway?message=Absent</code> is a
+ valid AIM URI, but not a contact.</p>
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/spec/Protocol_Interface_Avatars.xml b/spec/spec/Protocol_Interface_Avatars.xml
new file mode 100644
index 000000000..1bf0515ef
--- /dev/null
+++ b/spec/spec/Protocol_Interface_Avatars.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" ?>
+<node name="/Protocol_Interface_Avatars"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Protocol.Interface.Avatars">
+ <tp:added version="0.21.5">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Protocol"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for protocols where it might be possible to set the
+ user's avatar, and the expected size limits and supported MIME types
+ are known before connecting.</p>
+
+ <tp:rationale>
+ <p>If the avatar requirements cannot be discovered while offline,
+ it's impossible to avoid setting the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Account</tp:dbus-ref>'s <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Account.Interface.Avatar"
+ >Avatar</tp:dbus-ref> property to an unsupported avatar.</p>
+ </tp:rationale>
+
+ <p>Each property on this interface SHOULD be cached in the
+ <code>.manager</code> file, using a key of the same name as the
+ property in the <code>[Protocol <em>proto</em>]</code>
+ group. All properties are encoded in ASCII decimal in the obvious
+ way, except for
+ <tp:member-ref>SupportedAvatarMIMETypes</tp:member-ref> which is
+ encoded as a sequence of strings each followed by a semicolon
+ (as for the "localestrings" type in the Desktop Entry
+ Specification).</p>
+
+ <p>For instance, an XMPP connection manager might have this
+ <code>.manager</code> file:</p>
+
+<pre>[Protocol jabber]
+Interfaces=org.freedesktop.Telepathy.Protocol.Interface.Avatars;
+param-account=s required
+param-password=s required
+SupportedAvatarMIMETypes=image/png;image/jpeg;image/gif;
+MinimumAvatarHeight=32
+RecommendedAvatarHeight=64
+MaximumAvatarHeight=96
+MinimumAvatarWidth=32
+RecommendedAvatarWidth=64
+MaximumAvatarWidth=96
+MaximumAvatarBytes=8192
+</pre>
+ </tp:docstring>
+
+ <property name="SupportedAvatarMIMETypes"
+ tp:name-for-bindings="Supported_Avatar_MIME_Types"
+ type="as" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.SupportedAvatarMIMETypes</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="MinimumAvatarHeight"
+ tp:name-for-bindings="Minimum_Avatar_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.MinimumAvatarHeight</tp:dbus-ref>
+ property on connections to this protocol.
+</tp:docstring>
+ </property>
+
+ <property name="MinimumAvatarWidth"
+ tp:name-for-bindings="Minimum_Avatar_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.MinimumAvatarWidth</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedAvatarHeight"
+ tp:name-for-bindings="Recommended_Avatar_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.RecommendedAvatarHeight</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="RecommendedAvatarWidth"
+ tp:name-for-bindings="Recommended_Avatar_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.RecommendedAvatarWidth</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarHeight"
+ tp:name-for-bindings="Maximum_Avatar_Height"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.MaximumAvatarHeight</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarWidth"
+ tp:name-for-bindings="Maximum_Avatar_Width"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.MaximumAvatarWidth</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+
+ <property name="MaximumAvatarBytes"
+ tp:name-for-bindings="Maximum_Avatar_Bytes"
+ type="u" access="read" tp:immutable="yes">
+ <tp:docstring>
+ The expected value of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Avatars.MaximumAvatarBytes</tp:dbus-ref>
+ property on connections to this protocol.
+ </tp:docstring>
+ </property>
+ </interface>
+</node>
diff --git a/spec/spec/Protocol_Interface_Presence.xml b/spec/spec/Protocol_Interface_Presence.xml
new file mode 100644
index 000000000..ddff33263
--- /dev/null
+++ b/spec/spec/Protocol_Interface_Presence.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" ?>
+<node name="/Protocol_Interface_Presence"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2009-2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Protocol.Interface.Presence">
+ <tp:added version="0.21.3">(as stable API)</tp:added>
+ <tp:requires interface="org.freedesktop.Telepathy.Protocol"/>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>An interface for protocols where it might be possible to set the
+ user's presence, and the supported presence types can be predicted
+ before connecting.</p>
+
+ <tp:rationale>
+ <p>This allows UIs to show or hide presence types that aren't
+ always supported, such as "invisible", while not online.</p>
+ </tp:rationale>
+
+ <p>The properties on this interface SHOULD be cached in the
+ <code>.manager</code> file, in the
+ <code>[Protocol <em>proto</em>]</code>
+ group. For each status <em>s</em> in
+ <tp:member-ref>Statuses</tp:member-ref>, that group should
+ contain a key of the form <code>status-<em>s</em></code> whose value
+ is the <tp:type>Connection_Presence_Type</tp:type> as an ASCII
+ decimal integer, followed by a space-separated sequence of tokens
+ from the following set:</p>
+
+ <dl>
+ <dt>settable</dt>
+ <dd>If present, the user can set this status on themselves using
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface.SimplePresence"
+ >SetPresence</tp:dbus-ref>; this corresponds to May_Set_On_Self
+ in the <tp:type>Simple_Status_Spec</tp:type> struct.</dd>
+
+ <dt>message</dt>
+ <dd>If present, the user can set a non-empty message for this status;
+ this corresponds to Can_Have_Message in the
+ <tp:type>Simple_Status_Spec</tp:type> struct.</dd>
+ </dl>
+
+ <p>Unrecognised tokens MUST be ignored.</p>
+
+ <p>For instance, an XMPP connection manager might have this
+ <code>.manager</code> file:</p>
+
+<pre>[Protocol jabber]
+Interfaces=org.freedesktop.Telepathy.Protocol.Interface.Presence;
+param-account=s required
+param-password=s required
+status-offline=1
+status-unknown=7
+status-error=8
+status-hidden=5 settable message
+status-xa=4 settable message
+status-away=3 settable message
+status-dnd=6 settable message
+status-available=2 settable message
+status-chat=2 settable message
+</pre>
+
+ <p>which corresponds to these property values (using a Python-like
+ syntax):</p>
+
+<pre>Statuses = {
+ 'offline': (OFFLINE, False, False),
+ 'unknown': (UNKNOWN, False, False),
+ 'error': (ERROR, False, False),
+ 'hidden': (HIDDEN, True, True),
+ 'xa': (EXTENDED_AWAY, True, True),
+ 'away': (AWAY, True, True),
+ 'dnd': (BUSY, True, True),
+ 'available': (AVAILABLE, True, True),
+ 'chat': (AVAILABLE, True, True),
+}
+</pre>
+ </tp:docstring>
+
+ <property name="Statuses"
+ tp:name-for-bindings="Statuses"
+ type="a{s(ubb)}" tp:type="Simple_Status_Spec_Map" access="read">
+ <tp:docstring>
+ <p>The statuses that might appear in the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.SimplePresence.Statuses</tp:dbus-ref>
+ property on a connection to this protocol that supports
+ SimplePresence. This property is immutable.</p>
+
+ <p>Depending on server capabilities, it is possible that not all
+ of these will actually appear on the Connection.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
diff --git a/spec/spec/all.xml b/spec/spec/all.xml
new file mode 100644
index 000000000..87bcf75b5
--- /dev/null
+++ b/spec/spec/all.xml
@@ -0,0 +1,321 @@
+<tp:spec
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<tp:title>Telepathy D-Bus Interface Specification</tp:title>
+<tp:version>0.25.1.1</tp:version>
+
+<tp:copyright>Copyright © 2005-2011 Collabora Limited</tp:copyright>
+<tp:copyright>Copyright © 2005-2011 Nokia Corporation</tp:copyright>
+<tp:copyright>Copyright © 2006 INdT</tp:copyright>
+
+<tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+</tp:license>
+
+<tp:section name="Connection Managers">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ A Connection Manager is a factory for connections.
+ </p>
+ </tp:docstring>
+ <xi:include href="Connection_Manager.xml"/>
+ <xi:include href="Connection_Manager_Interface_Account_Storage.xml"/>
+ <xi:include href="Protocol.xml"/>
+ <xi:include href="Protocol_Interface_Addressing.xml"/>
+ <xi:include href="Protocol_Interface_Avatars.xml"/>
+ <xi:include href="Protocol_Interface_Presence.xml"/>
+
+ <tp:section name="Connection Object">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Connections represent active protocol sessions. There are a number of core
+ interfaces which all connections should implement, and a number of optional
+ interfaces which provide various functionality related to contacts and to
+ the connection itself.
+ </p>
+ </tp:docstring>
+ <xi:include href="Connection.xml"/>
+ <xi:include href="Connection_Future.xml"/>
+ <xi:include href="Connection_Interface_Contacts.xml"/>
+ <xi:include href="Connection_Interface_Requests.xml"/>
+
+ <tp:section name="Contact list interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ On protocols that support contact lists, these interface expose the user's
+ contact lists, along with presence subscription information, contact
+ list groups (if supported), and the ability to block and unblock contacts
+ (if supported).
+ </p>
+ </tp:docstring>
+
+ <xi:include href="Connection_Interface_Contact_List.xml"/>
+ <xi:include href="Connection_Interface_Contact_Groups.xml"/>
+ <xi:include href="Connection_Interface_Contact_Blocking.xml"/>
+ </tp:section>
+
+ <tp:section name="Contact metadata interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ These optional Connection interfaces expose metadata about contacts on
+ this connection—from their current presence through to the type of client
+ they're connected with—and allow the local user to publish such metadata
+ back to their contacts.
+ </p>
+ </tp:docstring>
+
+ <xi:include href="Connection_Interface_Aliasing.xml"/>
+ <xi:include href="Connection_Interface_Avatars.xml"/>
+ <xi:include href="Connection_Interface_Capabilities.xml"/>
+ <xi:include href="Connection_Interface_Client_Types.xml"/>
+ <xi:include href="Connection_Interface_Contact_Capabilities.xml"/>
+ <xi:include href="Connection_Interface_Contact_Info.xml"/>
+ <xi:include href="Connection_Interface_Location.xml"/>
+ <xi:include href="Connection_Interface_Presence.xml"/>
+ <xi:include href="Connection_Interface_Renaming.xml"/>
+ <xi:include href="Connection_Interface_Resources.xml"/>
+ <xi:include href="Connection_Interface_Simple_Presence.xml"/>
+ </tp:section>
+
+ <tp:section name="Connection feature interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ These optional Connection interfaces expose protocol-specific features,
+ and allow configuring the running connection.
+ </p>
+ </tp:docstring>
+
+ <xi:include href="Connection_Interface_Addressing.xml"/>
+ <xi:include href="Connection_Interface_Anonymity.xml"/>
+ <xi:include href="Connection_Interface_Balance.xml"/>
+ <xi:include href="Connection_Interface_Cellular.xml"/>
+ <xi:include href="Connection_Interface_Communication_Policy.xml"/>
+ <xi:include href="Connection_Interface_Forwarding.xml"/>
+ <xi:include href="Connection_Interface_Keepalive.xml"/>
+ <xi:include href="Connection_Interface_Mail_Notification.xml"/>
+ <xi:include href="Connection_Interface_Power_Saving.xml"/>
+ <xi:include href="Connection_Interface_Service_Point.xml"/>
+ </tp:section>
+ </tp:section>
+
+ <xi:include href="Channel_Bundle.xml"/>
+
+ <tp:section name="Channel Object">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ A Channel is used by Telepathy to exchange data between local
+ applications and remote servers. A given connection will have many
+ channels, each one represented by a D-Bus object.
+ </p>
+ <p>
+ Each Channel has a type, represented by a D-Bus interface, and may
+ implement one or more additional interfaces from the list of channel
+ interfaces below.
+ </p>
+ </tp:docstring>
+ <xi:include href="Channel.xml"/>
+ <xi:include href="Channel_Future.xml"/>
+
+ <tp:section name="Channel Types">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Each Channel implements one of the following types:
+ </p>
+ </tp:docstring>
+ <xi:include href="Channel_Type_Call.xml"/>
+ <xi:include href="Channel_Type_Contact_List.xml"/>
+ <xi:include href="Channel_Type_Contact_Search.xml"/>
+ <xi:include href="Channel_Type_DBus_Tube.xml"/>
+ <xi:include href="Channel_Type_File_Transfer.xml"/>
+ <xi:include href="Channel_Type_Room_List.xml"/>
+ <xi:include href="Channel_Type_Server_Authentication.xml"/>
+ <xi:include href="Channel_Type_Server_TLS_Connection.xml"/>
+ <xi:include href="Channel_Type_Stream_Tube.xml"/>
+ <xi:include href="Channel_Type_Streamed_Media.xml"/>
+ <xi:include href="Channel_Type_Text.xml"/>
+ <xi:include href="Channel_Type_Tubes.xml"/>
+ </tp:section>
+
+ <tp:section name="Channel Interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ A Channel may also implement one or more of the following interfaces,
+ depending on its type. Some interfaces are only applicable to particular
+ channel types, while others may (in principle) appear on any type of
+ channel.
+ </p>
+ </tp:docstring>
+
+ <xi:include href="Channel_Interface_Addressing.xml"/>
+ <xi:include href="Channel_Interface_Anonymity.xml"/>
+ <xi:include href="Channel_Interface_Destroyable.xml"/>
+ <xi:include href="Channel_Interface_File_Transfer_Metadata.xml"/>
+ <xi:include href="Channel_Interface_Group.xml"/>
+ <xi:include href="Channel_Interface_Password.xml"/>
+ <xi:include href="Channel_Interface_Room.xml"/>
+ <xi:include href="Channel_Interface_Room_Config.xml"/>
+ <xi:include href="Channel_Interface_SASL_Authentication.xml"/>
+ <xi:include href="Channel_Interface_Credentials_Storage.xml"/>
+ <xi:include href="Channel_Interface_Securable.xml"/>
+ <xi:include href="Channel_Interface_Service_Point.xml"/>
+ <xi:include href="Channel_Interface_Subject.xml"/>
+ <xi:include href="Channel_Interface_Picture.xml"/>
+ <xi:include href="Channel_Interface_Tube.xml"/>
+
+ <tp:section name="Text-specific interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>These interfaces may only appear on channels of type <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>.</p>
+ </tp:docstring>
+
+ <xi:include href="Channel_Interface_Chat_State.xml"/>
+ <xi:include href="Channel_Interface_HTML.xml"/>
+ <xi:include href="Channel_Interface_Messages.xml"/>
+ <xi:include href="Channel_Interface_SMS.xml"/>
+ </tp:section>
+
+ <tp:section name="Streamed Media/Call-related interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>These interfaces are only applicable to channels of type <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>StreamedMedia</tp:dbus-ref>, with the
+ exception of the <tp:dbus-ref
+ namespace='ofdT.Channel.Interface'>Hold</tp:dbus-ref> and
+ <tp:dbus-ref namespace="ofdT.Channel.Interface">DTMF</tp:dbus-ref>
+ interfaces, which may also appear on <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Call1</tp:dbus-ref> channels.</p>
+ </tp:docstring>
+
+ <xi:include href="Channel_Interface_Call_State.xml"/>
+ <xi:include href="Channel_Interface_DTMF.xml"/>
+ <xi:include href="Channel_Interface_Hold.xml"/>
+ <xi:include href="Channel_Interface_Media_Signalling.xml"/>
+ </tp:section>
+
+ <tp:section name="Conference-related interfaces">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>These interfaces provide functionality for ad-hoc conference calls and
+ chat rooms. They are primarily intended for <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>Text</tp:dbus-ref>, <tp:dbus-ref
+ namespace='ofdT.Channel.Type'>StreamedMedia</tp:dbus-ref> and
+ <tp:dbus-ref namespace='ofdT.Channel.Type'>Call1</tp:dbus-ref>
+ channels, but may also appear on other types of channel.</p>
+ </tp:docstring>
+
+ <xi:include href="Channel_Interface_Conference.xml"/>
+ <xi:include href="Channel_Interface_Splittable.xml"/>
+ <xi:include href="Channel_Interface_Mergeable_Conference.xml"/>
+ </tp:section>
+ </tp:section>
+ </tp:section>
+
+ <tp:section name="Authentication Objects">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ A set of objects to be used for authentication purposes, such
+ as TLS certificates or handshakes for negotiating end-to-end
+ security.
+ </p>
+ </tp:docstring>
+ <xi:include href="Authentication_TLS_Certificate.xml"/>
+ </tp:section>
+
+ <tp:section name="Media">
+ <xi:include href="Media_Session_Handler.xml"/>
+ <xi:include href="Media_Stream_Handler.xml"/>
+ </tp:section>
+
+ <tp:section name="Calls">
+ <xi:include href="Call_Content.xml"/>
+ <xi:include href="Call_Content_Interface_Media.xml"/>
+ <xi:include href="Call_Interface_Mute.xml"/>
+ <xi:include href="Call_Content_Interface_Video_Control.xml"/>
+ <xi:include href="Call_Content_Interface_Audio_Control.xml"/>
+ <xi:include href="Call_Content_Media_Description.xml"/>
+ <xi:include href="Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml"/>
+ <xi:include href="Call_Content_Media_Description_Interface_RTCP_Feedback.xml"/>
+ <xi:include
+ href="Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml"/>
+ <xi:include href="Call_Stream.xml"/>
+ <xi:include href="Call_Stream_Interface_Media.xml"/>
+ <xi:include href="Call_Stream_Endpoint.xml"/>
+ </tp:section>
+
+ <tp:section name="Debugging">
+ <xi:include href="Debug.xml"/>
+ </tp:section>
+</tp:section>
+
+<tp:section name="The Account Manager">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The Account Manager is a desktop service that provides account configuration
+ and can manage the connection managers. In general, clients will use the
+ account manager to find out about instant messaging accounts and their
+ associated connections.
+ </p>
+ </tp:docstring>
+ <xi:include href="Account_Manager.xml"/>
+ <xi:include href="Account_Manager_Interface_Hidden.xml"/>
+ <xi:include href="Account.xml"/>
+ <xi:include href="Account_Interface_Addressing.xml"/>
+ <xi:include href="Account_Interface_Avatar.xml"/>
+ <xi:include href="Account_Interface_Hidden.xml"/>
+ <xi:include href="Account_Interface_Storage.xml"/>
+ <xi:include href="Account_Interface_External_Password_Storage.xml"/>
+</tp:section>
+
+<tp:section name="The Channel Dispatcher">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The Channel Dispatcher is a desktop service whose purpose is to dispatch
+ incoming Telepathy Channels to the appropriate client (e.g. incoming text
+ chat, file transfer, tubes, etc.).
+ </p>
+ </tp:docstring>
+ <xi:include href="Channel_Dispatcher.xml"/>
+ <xi:include href="Channel_Dispatcher_Interface_Operation_List.xml"/>
+ <xi:include href="Channel_Dispatch_Operation.xml"/>
+ <xi:include href="Channel_Request.xml"/>
+</tp:section>
+
+<tp:section name="Clients">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Clients should implement one or more of these interfaces to be able to
+ handle channels coming in from the Channel Dispatcher.
+ </p>
+ </tp:docstring>
+ <xi:include href="Client.xml"/>
+ <xi:include href="Client_Observer.xml"/>
+ <xi:include href="Client_Approver.xml"/>
+ <xi:include href="Client_Handler.xml"/>
+ <xi:include href="Client_Handler_Future.xml"/>
+ <xi:include href="Client_Interface_Requests.xml"/>
+
+ <xi:include href="Channel_Handler.xml"/>
+</tp:section>
+
+<xi:include href="Properties_Interface.xml"/>
+
+<xi:include href="errors.xml"/>
+<xi:include href="generic-types.xml"/>
+
+<!-- Never implemented, vague
+<xi:include href="Connection_Interface_Privacy.xml"/> -->
+<!-- Causes havoc, never implemented, unclear requirements
+<xi:include href="Channel_Interface_Transfer.xml"/> -->
+
+</tp:spec>
diff --git a/spec/spec/errors.xml b/spec/spec/errors.xml
new file mode 100644
index 000000000..7726f3cfd
--- /dev/null
+++ b/spec/spec/errors.xml
@@ -0,0 +1,657 @@
+<?xml version="1.0" ?>
+<tp:errors xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" namespace="org.freedesktop.Telepathy.Error">
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The D-Bus errors used in Telepathy all start with
+ <code>org.freedesktop.Telepathy.Error.</code>. They are used in
+ D-Bus messages of type ERROR, and also as plain strings annotated with
+ the <tp:type>DBus_Error_Name</tp:type> type.</p>
+
+ <p>In principle, any method can raise any error (this is a general fact
+ of IPC). For instance, generic D-Bus errors starting with
+ <code>org.freedesktop.DBus.Error.</code> will occur in some
+ situations.</p>
+
+ <p>Telepathy methods can also raise implementation-specific errors to
+ indicate specialized failure conditions. For better interoperability,
+ if a suitable Telepathy error exists, it should be preferred.</p>
+
+ <p>The namespace <code>org.freedesktop.Telepathy.Qt4.Error.</code>
+ is reserved for use by the D-Bus client implementation in telepathy-qt4,
+ which uses it to represent certain error situations that did not involve
+ a D-Bus ERROR message. These errors are defined and documented as part of
+ telepathy-qt4's C++ API, and should not be used on D-Bus.</p>
+ </tp:docstring>
+
+ <tp:error name="Network Error">
+ <tp:docstring>
+ Raised when there is an error reading from or writing to the network.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Not Implemented">
+ <tp:docstring>
+ Raised when the requested method, channel, etc is not available on this connection.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Invalid Argument">
+ <tp:docstring>
+ Raised when one of the provided arguments is invalid.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Not Available">
+ <tp:docstring>
+ Raised when the requested functionality is temporarily unavailable.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Permission Denied">
+ <tp:docstring>
+ The user is not permitted to perform the requested operation.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Disconnected">
+ <tp:docstring>
+ The connection is not currently connected and cannot be used.
+ This error may also be raised when operations are performed on a
+ Connection for which
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection">StatusChanged</tp:dbus-ref>
+ has signalled status Disconnected for reason None.
+
+ <tp:rationale>
+ The second usage corresponds to None in the
+ <tp:type>Connection_Status_Reason</tp:type> enum; if a better reason
+ is available, the corresponding error should be used instead.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Invalid Handle">
+ <tp:docstring>
+ The handle specified is unknown on this channel or connection.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Channel.Banned">
+ <tp:docstring>
+ You are banned from the channel.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Channel.Full">
+ <tp:docstring>
+ The channel is full.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Channel.Invite Only">
+ <tp:docstring>
+ The requested channel is invite-only.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Not Yours">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The requested channel or other resource already exists, and another
+ user interface in this session is responsible for it.</p>
+
+ <p>User interfaces SHOULD handle this error unobtrusively, since it
+ indicates that some other user interface is already processing the
+ channel.</p>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cancelled">
+ <tp:docstring>
+ Raised by an ongoing request if it is cancelled by user request before
+ it has completed, or when operations are performed on an object which
+ the user has asked to close (for instance, a Connection where the user
+ has called Disconnect, or a Channel where the user has called Close).
+
+ <tp:rationale>
+ The second form can be used to correspond to the Requested member in
+ the <tp:type>Connection_Status_Reason</tp:type> enum, or to
+ to represent the situation where disconnecting a Connection,
+ closing a Channel, etc. has been requested by the user but this
+ request has not yet been acted on, for instance because the
+ service will only act on the request when it has finished processing
+ an event queue.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Authentication Failed">
+ <tp:docstring>
+ Raised when authentication with a service was unsuccessful.
+ <tp:rationale>
+ This corresponds to Authentication_Failed in the
+ <tp:type>Connection_Status_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Encryption Not Available">
+ <tp:docstring>
+ Raised if a user request insisted that encryption should be used,
+ but encryption was not actually available.
+
+ <tp:rationale>
+ This corresponds to part of Encryption_Error in the
+ <tp:type>Connection_Status_Reason</tp:type> enum. It's been separated
+ into a distinct error here because the two concepts that were part
+ of EncryptionError seem to be things that could reasonably appear
+ differently in the UI.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Encryption Error">
+ <tp:docstring>
+ Raised if encryption appears to be available, but could not actually be
+ used (for instance if SSL/TLS negotiation fails).
+ <tp:rationale>
+ This corresponds to part of Encryption_Error in the
+ <tp:type>Connection_Status_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Not Provided">
+ <tp:docstring>
+ Raised if the server did not provide a SSL/TLS certificate. This error
+ MUST NOT be used to represent the absence of a client certificate
+ provided by the Telepathy connection manager.
+ <tp:rationale>
+ This corresponds to Cert_Not_Provided in the
+ <tp:type>Connection_Status_Reason</tp:type> enum. That error
+ explicitly applied only to server SSL certificates, so this one
+ is similarly limited; having the CM present a client certificate
+ is a possible future feature, but it should have its own error
+ handling.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Untrusted">
+ <tp:docstring>
+ Raised if the server provided a SSL/TLS certificate signed by an
+ untrusted certifying authority. This error SHOULD NOT be used to
+ represent a self-signed certificate: see the Self Signed error for that.
+ <tp:rationale>
+ This corresponds to Cert_Untrusted in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Untrusted in the
+ <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum, with a clarification
+ to avoid ambiguity.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Expired">
+ <tp:docstring>
+ Raised if the server provided an expired SSL/TLS certificate.
+ <tp:rationale>
+ This corresponds to Cert_Expired in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Expired in
+ the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Not Activated">
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that will become
+ valid at some point in the future.
+ <tp:rationale>
+ This corresponds to Cert_Not_Activated in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to
+ Not_Activated in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Fingerprint Mismatch">
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that did not have
+ the expected fingerprint.
+ <tp:rationale>
+ This corresponds to Cert_Fingerprint_Mismatch in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to
+ Fingerprint_Mismatch in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Hostname Mismatch">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Raised if the server provided an SSL/TLS certificate that did not match
+ its hostname.</p>
+ <p>You MAY be able to get more details about the expected and certified
+ hostnames by looking up the 'expected-hostname' and 'certificate-hostname'
+ keys in the details map that came together with this error.</p>
+ <tp:rationale>
+ This corresponds to Cert_Hostname_Mismatch in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Hostname_Mismatch
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Self Signed">
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that is self-signed
+ and untrusted.
+ <tp:rationale>
+ This corresponds to Cert_Self_Signed in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Self_Signed
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Revoked">
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that has been
+ revoked.
+ <tp:rationale>
+ This corresponds to Cert_Revoked in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Revoked
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Insecure">
+ <tp:added version="0.19.11"/>
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that uses an
+ insecure cipher algorithm or is cryptographically weak.
+ <tp:rationale>
+ This corresponds to Cert_Insecure in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Insecure
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Invalid">
+ <tp:added version="0.19.11"/>
+ <tp:docstring>
+ Raised if the server provided an SSL/TLS certificate that is
+ unacceptable in some way that does not have a more specific error.
+ <tp:rationale>
+ This corresponds to Cert_Other_Error in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Unknown
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Cert.Limit Exceeded">
+ <tp:added version="0.19.11"/>
+ <tp:docstring>
+ Raised if the length in bytes of the server certificate, or the depth of the
+ server certificate chain exceeds the limits imposed by the crypto
+ library.
+ <tp:rationale>
+ This corresponds to Cert_Limit_Exceeded in the
+ <tp:type>Connection_Status_Reason</tp:type> enum and to Limit_Exceeded
+ in the <tp:type>TLS_Certificate_Reject_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Not Capable">
+ <tp:docstring>
+ Raised when requested functionality is unavailable due to contact
+ not having required capabilities.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Offline">
+ <tp:docstring>
+ Raised when requested functionality is unavailable because a contact is
+ offline.
+
+ <tp:rationale>
+ This corresponds to Offline in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Channel.Kicked">
+ <tp:docstring>
+ Used to represent a user being ejected from a channel by another user,
+ for instance being kicked from a chatroom.
+
+ <tp:rationale>
+ This corresponds to Kicked in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Busy">
+ <tp:docstring>
+ Used to represent a user being removed from a channel because of a
+ "busy" indication. This error SHOULD NOT be used to represent a server
+ or other infrastructure being too busy to process a request - for that,
+ see ServerBusy.
+
+ <tp:rationale>
+ This corresponds to Busy in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="No Answer">
+ <tp:docstring>
+ Used to represent a user being removed from a channel because they did
+ not respond, e.g. to a StreamedMedia call.
+
+ <tp:rationale>
+ This corresponds to No_Answer in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Does Not Exist">
+ <tp:docstring>
+ Raised when the requested user does not, in fact, exist.
+
+ <tp:rationale>
+ This corresponds to Invalid_Contact in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum, but can also be
+ used to represent other things not existing (like chatrooms, perhaps).
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Terminated">
+ <tp:docstring>
+ Raised when a channel is terminated for an unspecified reason. In
+ particular, this error SHOULD be used whenever normal termination of
+ a 1-1 StreamedMedia call by the remote user is represented as a D-Bus
+ error name.
+
+ <tp:rationale>
+ This corresponds to None in the
+ <tp:type>Channel_Group_Change_Reason</tp:type> enum.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Media.Codecs Incompatible">
+ <tp:added version="0.23.4"/>
+ <tp:docstring>
+ Raised when the local streaming implementation has no codecs in common
+ with the remote side.
+
+ <tp:rationale>
+ This corresponds to
+ <tp:value-ref type="Call_State_Change_Reason">Media_Error</tp:value-ref>.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Media.Unsupported Type">
+ <tp:added version="0.23.4"/>
+ <tp:docstring>
+ The media stream type requested is not supported by either the
+ local or remote side.
+
+ <tp:rationale>
+ This corresponds to
+ <tp:value-ref type="Call_State_Change_Reason">Media_Error</tp:value-ref>.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Media.Streaming Error">
+ <tp:added version="0.23.4"/>
+ <tp:docstring>
+ Raised when the call's streaming implementation has some kind of internal
+ error.
+
+ <tp:rationale>
+ This corresponds to
+ <tp:value-ref type="Call_State_Change_Reason">Internal_Error</tp:value-ref>.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Connection Refused">
+ <tp:docstring>
+ Raised when a connection is refused.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Connection Failed">
+ <tp:docstring>
+ Raised when a connection can't be established.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Connection Lost">
+ <tp:docstring>
+ Raised when a connection is broken.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Already Connected">
+ <tp:docstring>
+ Raised when the user attempts to connect to an account but they are
+ already connected (perhaps from another client or computer), and the
+ protocol or account settings do not allow this.
+
+ <tp:rationale>
+ XMPP can have this behaviour if the user chooses the same resource
+ in both clients (it is server-dependent whether the result is
+ AlreadyConnected on the new connection, ConnectionReplaced on the
+ old connection, or two successful connections).
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Connection Replaced">
+ <tp:docstring>
+ Raised by an existing connection to an account if it is replaced by
+ a new connection (perhaps from another client or computer).
+
+ <tp:rationale>
+ In MSNP, when connecting twice with the same Passport, the new
+ connection "wins" and the old one is automatically disconnected.
+ XMPP can also have this behaviour if the user chooses the same
+ resource in two clients (it is server-dependent whether the result is
+ AlreadyConnected on the new connection, ConnectionReplaced on the
+ old connection, or two successful connections).
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Registration Exists">
+ <tp:docstring>
+ Raised during in-band registration if the server indicates that the
+ requested account already exists.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Service Busy">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Raised if a server or some other piece of infrastructure cannot process
+ the request, e.g. due to resource limitations. Clients MAY try again
+ later.
+
+ <tp:rationale>
+ This is not the same error as Busy, which indicates that a
+ <em>user</em> is busy.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Resource Unavailable">
+ <tp:docstring>
+ Raised if a request cannot be satisfied because a process local to the
+ user has insufficient resources. Clients MAY try again
+ later.
+
+ <tp:rationale>
+ For instance, the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">ChannelDispatcher</tp:dbus-ref>
+ might raise this error for some or all channel requests if it has
+ detected that there is not enough free memory.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Would Break Anonymity">
+ <tp:added version="0.19.7"/>
+ <tp:docstring>
+ Raised if a request cannot be satisfied without violating an earlier
+ request for anonymity, and the earlier request specified that raising
+ an error is preferable to disclosing the user's identity (for instance
+ via <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Connection.Interface.Anonymity.AnonymityMandatory</tp:dbus-ref> or
+ <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+ >Channel.Interface.Anonymity.AnonymityMandatory</tp:dbus-ref>).
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Not Yet">
+ <tp:added version="0.19.12"/>
+ <tp:docstring>
+ Raised when the requested functionality is not yet available, but is
+ likely to become available after some time has passed.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Rejected">
+ <tp:added version="0.21.2"/>
+ <tp:docstring>
+ Raised when an incoming or outgoing <tp:dbus-ref
+ namespace="ofdT.Channel.Type">Call1</tp:dbus-ref> is
+ rejected by the the receiver.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Picked Up Elsewhere">
+ <tp:added version="0.21.3"/>
+ <tp:docstring>
+ Raised when a call was terminated as a result of the local user
+ picking up the call on a different resource.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Service Confused">
+ <tp:added version="0.21.5"/>
+ <tp:docstring>
+ Raised when a server or other piece of infrastructure indicates an
+ internal error, or when a message that makes no sense is received from
+ a server or other piece of infrastructure.
+
+ <tp:rationale>
+ For instance, this is appropriate for XMPP's
+ <code>internal-server-error</code>, and is also appropriate if
+ you receive sufficiently inconsistent information from a server that
+ you cannot continue.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Confused">
+ <tp:added version="0.21.5"/>
+ <tp:docstring>
+ Raised if a server rejects protocol messages from a connection manager
+ claiming that they do not make sense, two local processes fail to
+ understand each other, or an apparently impossible situation is
+ reached.
+
+ <tp:rationale>
+ For instance, this would be an appropriate mapping for XMPP's
+ errors bad-format, invalid-xml, etc., which can't happen unless
+ the local (or remote) XMPP implementation is faulty. This is
+ also analogous to
+ <tp:value-ref type="Media_Stream_Error">Invalid_CM_Behavior</tp:value-ref>,
+ <code>TP_DBUS_ERROR_INCONSISTENT</code> in telepathy-glib, and
+ <code>TELEPATHY_QT4_ERROR_INCONSISTENT</code> in telepathy-qt4.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Software Upgrade Required">
+ <tp:added version="0.21.12"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Raised as a
+ <tp:dbus-ref namespace="ofdT.Connection">ConnectionError</tp:dbus-ref>
+ when a Connection cannot be established because either the Connection
+ Manager or its support library (e.g. wocky, papyon, sofiasip) requires
+ upgrading to support a newer protocol version.</p>
+
+ <p>This error corresponds to the
+ <tp:type>Connection_Status_Reason</tp:type> of Network_Error.</p>
+
+ <tp:rationale>
+ Some protocols transmit a protocol or library version number to the
+ server, which will disconnect them if the version isn't appropriate.
+ This way we can report the error to the user, and if appropriate, the
+ user's client can check for updates.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Emergency Calls Not Supported">
+ <tp:added version="0.21.12"/>
+ <tp:docstring>
+ Raised if a client attempts to dial a number that is recognized as an
+ emergency number (e.g. '911' in the USA), but the Connection Manager or
+ provider does not support dialling emergency numbers.
+
+ <tp:rationale>
+ Many VOIP providers have the ability to dial traditional (PSTN)
+ telephone numbers, but do not provide the ability to dial emergency
+ numbers (for instance, Google Voice). This error provides additional
+ information about why such a call was unsuccessful.
+ </tp:rationale>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Insufficient Balance">
+ <tp:added version="0.22.1"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Raised if the user has insufficient
+ <tp:dbus-ref namespace="ofdT.Connection.Interface">Balance</tp:dbus-ref>
+ to place a call or send a message.</p>
+
+ <p>The key 'balance-required' MAY be included in
+ <tp:dbus-ref namespace="ofdT.Channel.Type.Call1">CallStateDetails</tp:dbus-ref>
+ or a delivery report's <tp:type>Message_Part</tp:type>
+ (with the same units and scale as
+ <tp:dbus-ref namespace="ofdT.Connection.Interface.Balance">AccountBalance</tp:dbus-ref>)
+ to indicate how much credit is required to make this call or send
+ this message.</p>
+ </tp:docstring>
+ </tp:error>
+
+ <tp:copyright>Copyright © 2005-2010 Collabora Limited</tp:copyright>
+ <tp:copyright>Copyright © 2005-2009 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+</tp:errors>
diff --git a/spec/spec/generic-types.xml b/spec/spec/generic-types.xml
new file mode 100644
index 000000000..014f8ada4
--- /dev/null
+++ b/spec/spec/generic-types.xml
@@ -0,0 +1,215 @@
+<tp:generic-types
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:simple-type name="Unix_Timestamp" type="u">
+ <tp:docstring>An unsigned 32-bit integer representing time as the number
+ of seconds elapsed since the Unix epoch
+ (1970-01-01T00:00:00Z)</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="Unix_Timestamp64" type="x">
+ <tp:docstring>An signed 64-bit integer representing time as the number
+ of seconds elapsed since the Unix epoch
+ (1970-01-01T00:00:00Z); negative for times before the epoch</tp:docstring>
+
+ <tp:rationale>The Text interface is the only user of Unix_Timestamp so
+ far, and we'd like to be Y2038 compatible in future
+ interfaces.</tp:rationale>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Bus_Name" type="s"
+ array-name="DBus_Bus_Name_List">
+ <tp:docstring>A string representing a D-Bus bus name - either a well-known
+ name like "org.freedesktop.Telepathy.MissionControl" or a unique name
+ like ":1.123"</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Well_Known_Name" type="s"
+ array-name="DBus_Well_Known_Name_List">
+ <tp:docstring>A string representing a D-Bus well-known
+ name like "org.freedesktop.Telepathy.MissionControl".</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Unique_Name" type="s"
+ array-name="DBus_Unique_Name_List">
+ <tp:docstring>A string representing a D-Bus unique name, such as
+ ":1.123"</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Interface" type="s"
+ array-name="DBus_Interface_List">
+ <tp:docstring>An ASCII string representing a D-Bus interface - two or more
+ elements separated by dots, where each element is a non-empty
+ string of ASCII letters, digits and underscores, not starting with
+ a digit. The maximum total length is 255 characters. For example,
+ "org.freedesktop.DBus.Peer".</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Error_Name" type="s">
+ <tp:docstring>An ASCII string representing a D-Bus error. This is
+ syntactically the same as a <tp:type>DBus_Interface</tp:type>, but the
+ meaning is different.</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Signature" type="s">
+ <tp:docstring>A string representing a D-Bus signature
+ (the 'g' type isn't used because of poor interoperability, particularly
+ with dbus-glib)</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Member" type="s">
+ <tp:docstring>An ASCII string representing a D-Bus method, signal
+ or property name - a non-empty string of ASCII letters, digits and
+ underscores, not starting with a digit, with a maximum length of 255
+ characters. For example, "Ping".</tp:docstring>
+ </tp:simple-type>
+
+ <tp:simple-type name="DBus_Qualified_Member" type="s"
+ array-name="DBus_Qualified_Member_List">
+ <tp:docstring>A string representing the full name of a D-Bus method,
+ signal or property, consisting of a DBus_Interface, followed by
+ a dot, followed by a DBus_Member. For example,
+ "org.freedesktop.DBus.Peer.Ping".</tp:docstring>
+ </tp:simple-type>
+
+ <tp:mapping name="Qualified_Property_Value_Map"
+ array-name="Qualified_Property_Value_Map_List">
+ <tp:docstring>A mapping from strings representing D-Bus
+ properties (by their namespaced names) to their values.</tp:docstring>
+ <tp:member type="s" name="Key" tp:type="DBus_Qualified_Member">
+ <tp:docstring>
+ A D-Bus interface name, followed by a dot and a D-Bus property name.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="v" name="Value">
+ <tp:docstring>
+ The value of the property.
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+ <tp:mapping name="String_Variant_Map" array-name="String_Variant_Map_List">
+ <tp:docstring>A mapping from strings to variants representing extra
+ key-value pairs.</tp:docstring>
+ <tp:member type="s" name="Key"/>
+ <tp:member type="v" name="Value"/>
+ </tp:mapping>
+
+ <tp:mapping name="String_String_Map" array-name="String_String_Map_List">
+ <tp:docstring>A mapping from strings to strings representing extra
+ key-value pairs.</tp:docstring>
+ <tp:member type="s" name="Key"/>
+ <tp:member type="s" name="Value"/>
+ </tp:mapping>
+
+ <tp:struct name="Socket_Address_IP" array-name="Socket_Address_IP_List">
+ <tp:docstring>An IP address and port.</tp:docstring>
+ <tp:member type="s" name="Address">
+ <tp:docstring>Either a dotted-quad IPv4 address literal as for
+ <tp:type>Socket_Address_IPv4</tp:type>, or an RFC2373 IPv6 address
+ as for <tp:type>Socket_Address_IPv6</tp:type>.
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="q" name="Port">
+ <tp:docstring>The TCP or UDP port number.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Socket_Address_IPv4">
+ <tp:docstring>An IPv4 address and port.</tp:docstring>
+ <tp:member type="s" name="Address">
+ <tp:docstring>A dotted-quad IPv4 address literal: four ASCII decimal
+ numbers, each between 0 and 255 inclusive, e.g.
+ "192.168.0.1".</tp:docstring>
+ </tp:member>
+ <tp:member type="q" name="Port">
+ <tp:docstring>The TCP or UDP port number.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Socket_Address_IPv6">
+ <tp:docstring>An IPv6 address and port.</tp:docstring>
+ <tp:member type="s" name="Address">
+ <tp:docstring>An IPv6 address literal as specified by RFC2373
+ section 2.2, e.g. "2001:DB8::8:800:200C:4171".</tp:docstring>
+ </tp:member>
+ <tp:member type="q" name="Port">
+ <tp:docstring>The TCP or UDP port number.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Socket_Netmask_IPv4">
+ <tp:docstring>An IPv4 network or subnet.</tp:docstring>
+ <tp:member type="s" name="Address">
+ <tp:docstring>A dotted-quad IPv4 address literal: four ASCII decimal
+ numbers, each between 0 and 255 inclusive, e.g.
+ "192.168.0.1".</tp:docstring>
+ </tp:member>
+ <tp:member type="y" name="Prefix_Length">
+ <tp:docstring>The number of leading bits of the address that must
+ match, for this netmask to be considered to match an
+ address.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:struct name="Socket_Netmask_IPv6">
+ <tp:docstring>An IPv6 network or subnet.</tp:docstring>
+ <tp:member type="s" name="Address">
+ <tp:docstring>An IPv6 address literal as specified by RFC2373
+ section 2.2, e.g. "2001:DB8::8:800:200C:4171".</tp:docstring>
+ </tp:member>
+ <tp:member type="y" name="Prefix_Length">
+ <tp:docstring>The number of leading bits of the address that must
+ match, for this netmask to be considered to match an
+ address.</tp:docstring>
+ </tp:member>
+ </tp:struct>
+
+ <tp:simple-type name="User_Action_Timestamp" type="x">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The time at which an user action occurred. This type has the 2
+ following special values:</p>
+
+ <p>0: the action doesn't involve any user action. Clients
+ SHOULD avoid stealing focus when presenting the channel.</p>
+
+ <p>MAX_INT64: clients SHOULD behave as though the user action happened
+ at the current time, e.g. a client MAY request that its window gains
+ focus.
+ </p>
+
+ <tp:rationale>
+ <p>This can be used by clients that can't know the X server time like
+ command line applications for example.</p>
+ </tp:rationale>
+
+ <p>For all the other values it corresponds to the time of the user
+ action. Clients SHOULD use this for focus-stealing prevention,
+ if applicable.
+ Note that the time is dependant on the local
+ environment and so is not necessarily a wall-clock time.
+ For example in an X environment it's expected to be the X timestamp
+ of events.
+ This corresponds to the _NET_WM_USER_TIME property in
+ <a href="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</a>.</p>
+ </tp:docstring>
+ </tp:simple-type>
+
+ <tp:mapping name="Object_Immutable_Properties_Map"
+ array-name="Object_Immutable_Properties_Map_List">
+ <tp:added version="0.19.12"/>
+ <tp:docstring>A mapping from object path to the immutable properties of
+ the object.</tp:docstring>
+ <tp:member type="o" name="Path">
+ <tp:docstring>
+ The object path of an object
+ </tp:docstring>
+ </tp:member>
+ <tp:member type="a{sv}" name="Immutable_Properties" tp:type="Qualified_Property_Value_Map">
+ <tp:docstring>
+ The immutable properties of the object
+ </tp:docstring>
+ </tp:member>
+ </tp:mapping>
+
+</tp:generic-types>
diff --git a/spec/spec/template.xml b/spec/spec/template.xml
new file mode 100644
index 000000000..283804a94
--- /dev/null
+++ b/spec/spec/template.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<node name="/Foo"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+
+ <tp:copyright>Copyright © 2010 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Foo.DRAFT"
+ tp:causes-havoc="experimental">
+ <tp:added version="0.UNRELEASED">(draft 1)</tp:added>
+
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Foo.</p>
+ </tp:docstring>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/test/input/_Test.xml b/spec/test/input/_Test.xml
new file mode 100644
index 000000000..891683ef8
--- /dev/null
+++ b/spec/test/input/_Test.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" ?>
+<node name="/_Test" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2006 Collabora Limited</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.SpecAutoGenTest">
+
+ <tp:client-interest/>
+ <tp:client-interest name="badgers"/>
+
+ <tp:struct name="UV" array-name="UV_List">
+ <tp:member name="Uint" type="u"/>
+ <tp:member name="Variant" type="v"/>
+ </tp:struct>
+
+ <method name="DoStuff" tp:name-for-bindings="Do_Stuff">
+ <arg direction="in" name="badger" type="b">
+ <tp:docstring>A badger, which MAY be breezy.</tp:docstring>
+ </arg>
+ <arg direction="in" name="mushroom" type="a{sv}">
+ <tp:docstring>Use of hallucinogenic mushrooms will lead to undefined behaviour.</tp:docstring>
+ </arg>
+ <arg direction="in" name="snake" type="s">
+ <tp:docstring>A snake, it's a snake.</tp:docstring>
+ </arg>
+ <arg direction="out" name="misc" type="a(uv)" tp:type="UV[]">
+ <tp:docstring>Array of structs containing whatever seems appropriate.</tp:docstring>
+ </arg>
+ <tp:possible-errors>
+ <tp:error name="org.freedesktop.Telepathy.SpecAutoGenTest.MiscError"/>
+ <tp:error name="org.freedesktop.Telepathy.SpecAutoGenTest.OtherError">
+ <tp:docstring>Raised if the badger or the snake eats the mushrooms</tp:docstring>
+ </tp:error>
+ </tp:possible-errors>
+ <tp:docstring>
+ Does stuff.
+ </tp:docstring>
+ </method>
+
+ <signal name="StuffHappened" tp:name-for-bindings="Stuff_Happened">
+ <arg name="stoat" type="ay">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <em>Mustela erminea</em>
+ </tp:docstring>
+ </arg>
+ <arg name="ferret" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <em>Mustela putorius furo</em>
+ </tp:docstring>
+ </arg>
+ <arg name="weasel" type="b">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <em>Mustela nivalis</em> (or compatible)
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when stuff happened.
+ </tp:docstring>
+ </signal>
+
+ <tp:property name="wobbly" type="b">
+ <tp:docstring>
+ Whether or not this badger is wobbly.
+ </tp:docstring>
+ </tp:property>
+
+ <property name="Introspective" tp:name-for-bindings="Introspective"
+ type="b" access="read">
+ <tp:docstring>
+ True if the badger is introspective.
+
+ <tp:rationale>
+ Goths can be mistaken for badgers in poor lighting conditions.
+ </tp:rationale>
+ </tp:docstring>
+ </property>
+
+ <tp:flags name="Test_Flags" value-prefix="Test" type="u">
+ <tp:docstring>A set of flags</tp:docstring>
+ <tp:flag suffix="LowBit" value="1">
+ <tp:docstring>
+ A bit
+ </tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="HighBit" value="128">
+ <tp:docstring>
+ Another bit
+ </tp:docstring>
+ </tp:flag>
+ </tp:flags>
+
+ <tp:enum name="Adjective" type="u">
+ <tp:docstring>Adjectives which may be applied to a specification</tp:docstring>
+ <tp:enumvalue suffix="Leveraging" value="0">
+ <tp:docstring>
+ Can leverage synergy
+ </tp:docstring>
+ </tp:enumvalue>
+ <tp:enumvalue suffix="Synergistic" value="1">
+ <tp:docstring>
+ Can synergize with leverage
+ </tp:docstring>
+ </tp:enumvalue>
+ </tp:enum>
+
+ <tp:docstring>
+ A test case for the spec processing.
+ </tp:docstring>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/spec/test/input/all.xml b/spec/test/input/all.xml
new file mode 100644
index 000000000..c96bff578
--- /dev/null
+++ b/spec/test/input/all.xml
@@ -0,0 +1,25 @@
+<tp:spec
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<tp:title>telepathy-spec tools test case</tp:title>
+<tp:version>0.1.2</tp:version>
+
+<tp:copyright>Copyright (C) 2006 Collabora Limited</tp:copyright>
+<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+<p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+</tp:docstring>
+
+<xi:include href="_Test.xml"/>
+
+<xi:include href="errors.xml"/>
+
+</tp:spec>
diff --git a/spec/test/input/errors.xml b/spec/test/input/errors.xml
new file mode 100644
index 000000000..7bfa1d66c
--- /dev/null
+++ b/spec/test/input/errors.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<tp:errors xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" namespace='org.freedesktop.Telepathy'>
+ <tp:error name="Spec AutoGen Test.Misc Error">
+ <tp:docstring>
+ Raised whenever appropriate.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:error name="Spec AutoGen Test.Other Error">
+ <tp:docstring>
+ Raised at all other times.
+ </tp:docstring>
+ </tp:error>
+
+ <tp:copyright>Copyright (C) 2006, 2007 Collabora Limited</tp:copyright>
+ <tp:license>
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+USA.
+ </tp:license>
+</tp:errors>
diff --git a/spec/test/test-specparser.py b/spec/test/test-specparser.py
new file mode 100755
index 000000000..164b4df8a
--- /dev/null
+++ b/spec/test/test-specparser.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+import sys
+import os.path
+
+test_dir = os.path.dirname (sys.argv[0])
+sys.path.insert (0, os.path.join (test_dir, '../tools/'))
+
+import specparser
+
+spec_path = os.path.join (test_dir, 'input/all.xml')
+
+def test_specparser ():
+ """
+>>> spec = specparser.parse (spec_path, 'org.freedesktop.Telepathy.SpecAutoGenTest')
+>>> spec
+Spec(telepathy-spec tools test case)
+
+>>> spec.interfaces
+[Interface(org.freedesktop.Telepathy.SpecAutoGenTest)]
+
+>>> spec.errors
+{u'org.freedesktop.Telepathy.SpecAutoGenTest.OtherError': Error(org.freedesktop.Telepathy.SpecAutoGenTest.OtherError), u'org.freedesktop.Telepathy.SpecAutoGenTest.MiscError': Error(org.freedesktop.Telepathy.SpecAutoGenTest.MiscError)}
+
+>>> spec.generic_types
+[]
+>>> spec.types
+{u'Adjective': Enum(Adjective), u'Test_Flags': Flags(Test_Flags), u'UV': Struct(UV)}
+
+>>> i = spec.interfaces[0]
+>>> i
+Interface(org.freedesktop.Telepathy.SpecAutoGenTest)
+
+>>> print i.causes_havoc
+None
+
+>>> i.methods
+[Method(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff)]
+
+>>> i.methods[0].args
+Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+AttributeError: 'Method' object has no attribute 'args'
+>>> i.methods[0].in_args
+[Arg(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff.badger:b), Arg(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff.mushroom:a{sv}), Arg(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff.snake:s)]
+>>> i.methods[0].out_args
+[Arg(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff.misc:a(uv))]
+
+>>> i.methods[0].possible_errors
+[PossibleError(org.freedesktop.Telepathy.SpecAutoGenTest.MiscError), PossibleError(org.freedesktop.Telepathy.SpecAutoGenTest.OtherError)]
+>>> map (lambda e: e.get_error (), i.methods[0].possible_errors)
+[Error(org.freedesktop.Telepathy.SpecAutoGenTest.MiscError), Error(org.freedesktop.Telepathy.SpecAutoGenTest.OtherError)]
+
+>>> i.signals
+[Signal(org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened)]
+
+>>> i.signals[0].args
+[Arg(org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened.stoat:ay), Arg(org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened.ferret:s), Arg(org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened.weasel:b)]
+
+>>> i.properties
+[Property(org.freedesktop.Telepathy.SpecAutoGenTest.Introspective:b)]
+
+>>> i.properties[0].type
+''
+>>> i.properties[0].dbus_type
+u'b'
+>>> print i.properties[0].get_type ()
+None
+
+>>> i.types
+[Enum(Adjective), Flags(Test_Flags), Struct(UV)]
+
+>>> i.types[0].values
+[EnumValue(Adjective.Leveraging), EnumValue(Adjective.Synergistic)]
+>>> map (lambda v: (v.short_name, v.value), i.types[0].values)
+[(u'Leveraging', u'0'), (u'Synergistic', u'1')]
+
+>>> i.types[1].values
+[EnumValue(Test_Flags.LowBit), EnumValue(Test_Flags.HighBit)]
+>>> map (lambda v: (v.short_name, v.value), i.types[1].values)
+[(u'LowBit', u'1'), (u'HighBit', u'128')]
+
+>>> sorted(spec.everything.items())
+[(u'org.freedesktop.Telepathy.SpecAutoGenTest', ClientInterest(org.freedesktop.Telepathy.SpecAutoGenTest)), (u'org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff', Method(org.freedesktop.Telepathy.SpecAutoGenTest.DoStuff)), (u'org.freedesktop.Telepathy.SpecAutoGenTest.Introspective', Property(org.freedesktop.Telepathy.SpecAutoGenTest.Introspective:b)), (u'org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened', Signal(org.freedesktop.Telepathy.SpecAutoGenTest.StuffHappened)), (u'org.freedesktop.Telepathy.SpecAutoGenTest.wobbly', AwkwardTelepathyProperty(org.freedesktop.Telepathy.SpecAutoGenTest.wobbly:b)), (u'org.freedesktop.Telepathy.SpecAutoGenTest/badgers', ClientInterest(org.freedesktop.Telepathy.SpecAutoGenTest/badgers))]
+
+
+>>> map (lambda o: i.added, spec.everything.values ())
+[None, None, None, None, None, None]
+>>> map (lambda o: i.deprecated, spec.everything.values ())
+[None, None, None, None, None, None]
+ """
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod ()
diff --git a/spec/tools/README b/spec/tools/README
new file mode 100644
index 000000000..5ffc9fd44
--- /dev/null
+++ b/spec/tools/README
@@ -0,0 +1,24 @@
+Some tools that used to be here are now maintained elsewhere.
+
+c-constants-generator.xsl
+ Now in telepathy-glib (with a modified version in libtelepathy, and a
+ copy in Gabble for its spec extensions)
+
+c-interfaces-generator.xsl
+ Now in telepathy-glib (with a modified version in libtelepathy, and a
+ copy in Gabble for its spec extensions)
+
+genginterface.py
+ Now in telepathy-glib (with a copy in Gabble for its spec extensions)
+
+python-constants-generator.xsl
+ Now in telepathy-python
+
+python-errors-generator.xsl
+ Now in telepathy-python
+
+python-interfaces-generator.xsl
+ Now in telepathy-python
+
+spec-to-python.xsl
+ Now in telepathy-python
diff --git a/spec/tools/doc-generator.py b/spec/tools/doc-generator.py
new file mode 100755
index 000000000..6117a6cad
--- /dev/null
+++ b/spec/tools/doc-generator.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# doc-generator.py
+#
+# Generates HTML documentation from the parsed spec using Cheetah templates.
+#
+# Copyright (C) 2009 Collabora Ltd.
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or (at
+# your option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
+#
+
+import sys
+import os
+import os.path
+import shutil
+
+try:
+ from Cheetah.Template import Template
+except ImportError, e:
+ print >> sys.stderr, e
+ print >> sys.stderr, "Install `python-cheetah'?"
+ sys.exit(-1)
+
+import specparser
+
+# one day, OptionParser
+allow_externals = False
+if '--allow-externals' in sys.argv:
+ allow_externals = True
+ sys.argv.remove('--allow-externals')
+
+program, spec_file, output_path, project, namespace = sys.argv
+
+template_path = os.path.join(os.path.dirname(program), '../doc/templates')
+
+# make the output path
+try:
+ os.mkdir(output_path)
+except OSError:
+ pass
+
+# copy in the static files
+static = [ 'style.css',
+ 'jquery.min.js',
+ 'ui-icons_222222_256x240.png',
+ 'magic.js',
+ 'favicon.png'
+ ]
+for s in static:
+ shutil.copy(os.path.join(template_path, s), output_path)
+
+def load_template(filename):
+ try:
+ file = open(os.path.join(template_path, filename))
+ template_def = file.read()
+ file.close()
+ except IOError, e:
+ print >> sys.stderr, "Could not load template file `%s'" % filename
+ print >> sys.stderr, e
+ sys.exit(-1)
+
+ return template_def
+
+spec = specparser.parse(spec_file, namespace, allow_externals=allow_externals)
+
+# write out HTML files for each of the interfaces
+
+# Not using render_template here to avoid recompiling it n times.
+namespace = { 'spec': spec }
+template_def = load_template('interface.html')
+t = Template(template_def, namespaces = [namespace])
+for interface in spec.interfaces:
+ namespace['interface'] = interface
+
+ # open the output file
+ out = open(os.path.join(output_path, '%s.html'
+ % interface.name_for_bindings), 'w')
+ print >> out, unicode(t).encode('utf-8')
+ out.close()
+
+def render_template(name, namespaces, target=None):
+ if target is None:
+ target = name
+
+ namespace = { 'spec': spec }
+ template_def = load_template(name)
+ t = Template(template_def, namespaces=namespaces)
+ out = open(os.path.join(output_path, target), 'w')
+ print >> out, unicode(t).encode('utf-8')
+ out.close()
+
+namespaces = { 'spec': spec }
+
+if len(spec.generic_types) > 0:
+ render_template('generic-types.html', namespaces)
+if len(spec.errors) > 0:
+ render_template('errors.html', namespaces)
+render_template('interfaces.html', namespaces)
+render_template('fullindex.html', namespaces)
+
+dh_namespaces = { 'spec': spec, 'name': project }
+render_template('devhelp.devhelp2', dh_namespaces,
+ target=('%s.devhelp2' % project))
+
+# write out the TOC last, because this is the file used as the target in the
+# Makefile.
+render_template('index.html', namespaces)
diff --git a/spec/tools/git-which-branch.sh b/spec/tools/git-which-branch.sh
new file mode 100644
index 000000000..b96b5d5e2
--- /dev/null
+++ b/spec/tools/git-which-branch.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# git-which-branch.sh - output the name of the current git branch
+#
+# The canonical location of this program is the telepathy-spec tools/
+# directory, please synchronize any changes with that copy.
+#
+# Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+default="$1"
+if { ref="`git symbolic-ref HEAD 2>/dev/null`"; }; then
+ echo ${ref#refs/heads/}
+ exit 0
+fi
+
+if test -n "$default"; then
+ echo "$default" >/dev/null
+ exit 0
+fi
+
+echo "no git branch found" >&2
+exit 1
diff --git a/spec/tools/specparser.py b/spec/tools/specparser.py
new file mode 100644
index 000000000..3ad1f9a34
--- /dev/null
+++ b/spec/tools/specparser.py
@@ -0,0 +1,1420 @@
+#
+# specparser.py
+#
+# Reads in a spec document and generates pretty data structures from it.
+#
+# Copyright (C) 2009-2010 Collabora Ltd.
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or (at
+# your option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
+#
+
+import sys
+import xml.dom.minidom
+
+import xincludator
+
+XMLNS_TP = 'http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0'
+
+class UnknownAccess(Exception): pass
+class UnknownDirection(Exception): pass
+class UnknownType(Exception): pass
+class UnnamedItem(Exception): pass
+class UntypedItem(Exception): pass
+class UnsupportedArray(Exception): pass
+class BadNameForBindings(Exception): pass
+class BrokenHTML(Exception): pass
+class WrongNumberOfChildren(Exception): pass
+class MismatchedFlagsAndEnum(Exception): pass
+class TypeMismatch(Exception): pass
+class MissingVersion(Exception): pass
+class DuplicateEnumValueValue(Exception): pass
+class BadFlagValue(Exception): pass
+class BadFlagsType(Exception): pass
+
+class Xzibit(Exception):
+ def __init__(self, parent, child):
+ self.parent = parent
+ self.child = child
+
+ def __str__(self):
+ print """
+ Nested <%s>s are forbidden.
+ Parent:
+ %s...
+ Child:
+ %s...
+ """ % (self.parent.nodeName, self.parent.toxml()[:100],
+ self.child.toxml()[:100])
+
+def getText(dom):
+ try:
+ if dom.childNodes[0].nodeType == dom.TEXT_NODE:
+ return dom.childNodes[0].data
+ else:
+ return ''
+ except IndexError:
+ return ''
+
+def getChildrenByName(dom, namespace, name):
+ return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
+ n.namespaceURI == namespace and \
+ n.localName == name,
+ dom.childNodes)
+
+def getChildrenByNameAndAttribute(dom, namespace, name, attribute, value):
+ return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
+ n.namespaceURI == namespace and \
+ n.localName == name and \
+ n.getAttribute(attribute) == value,
+ dom.childNodes)
+
+def getOnlyChildByName(dom, namespace, name):
+ kids = getChildrenByName(dom, namespace, name)
+
+ if len(kids) == 0:
+ return None
+
+ if len(kids) > 1:
+ raise WrongNumberOfChildren(
+ '<%s> node should have at most one <%s xmlns="%s"/> child' %
+ (dom.tagName, name, namespace))
+
+ return kids[0]
+
+def getAnnotationByName(dom, name):
+ kids = getChildrenByNameAndAttribute(dom, None, 'annotation', 'name', name)
+
+ if len(kids) == 0:
+ return None
+
+ if len(kids) > 1:
+ raise WrongNumberOfChildren(
+ '<%s> node should have at most one %s annotation' %
+ (dom.tagName, name))
+
+ return kids[0].getAttribute('value')
+
+def getNamespace(n):
+ if n.namespaceURI is not None:
+ return n.namespaceURI
+ ancestor = n.parentNode
+
+ while ancestor is not None and ancestor.nodeType == n.ELEMENT_NODE:
+ if n.prefix is None:
+ xmlns = ancestor.getAttribute('xmlns')
+ else:
+ xmlns = ancestor.getAttribute('xmlns:%s' % n.prefix)
+
+ if xmlns is not None:
+ return xmlns
+
+ ancestor = ancestor.parentNode
+
+def build_name(namespace, name):
+ """Returns a name by appending `name' to the namespace of this object.
+ """
+ return '.'.join(
+ filter(lambda n: n is not None and n != '',
+ [namespace, name.replace(' ', '')])
+ )
+
+class Base(object):
+ """The base class for any type of XML node in the spec that implements the
+ 'name' attribute.
+
+ Don't instantiate this class directly.
+ """
+ devhelp_name = ""
+
+ def __init__(self, parent, namespace, dom):
+ self.short_name = name = dom.getAttribute('name')
+ self.namespace = namespace
+ self.name = build_name(namespace, name)
+ self.parent = parent
+
+ for child in dom.childNodes:
+ if (child.nodeType == dom.TEXT_NODE and
+ child.data.strip() != ''):
+ raise BrokenHTML('Text found in node %s of %s, did you mean '
+ 'to use <tp:docstring/>? Offending text:\n\n%s' %
+ (self.__class__.__name__, self.parent, child.data.strip()))
+ elif child.nodeType == dom.ELEMENT_NODE:
+ if child.tagName in ('p', 'em', 'strong', 'ul', 'li', 'dl',
+ 'a', 'tt', 'code'):
+ raise BrokenHTML('HTML element <%s> found in node %s of '
+ '%s, did you mean to use <tp:docstring/>?' %
+ (child.tagName, self.__class__.__name__, self.parent))
+
+ self.docstring = getOnlyChildByName(dom, XMLNS_TP, 'docstring')
+ self.added = getOnlyChildByName(dom, XMLNS_TP, 'added')
+ self.deprecated = getOnlyChildByName(dom, XMLNS_TP, 'deprecated')
+ if self.deprecated is None:
+ self.is_deprecated = (getAnnotationByName(dom, 'org.freedesktop.DBus.Deprecated') == 'true')
+ else:
+ self.is_deprecated = True
+
+ self.changed = getChildrenByName(dom, XMLNS_TP, 'changed')
+
+ self.validate()
+
+ def validate(self):
+ if self.short_name == '':
+ raise UnnamedItem("Node %s of %s has no name" % (
+ self.__class__.__name__, self.parent))
+
+ def check_consistency(self):
+ pass
+
+ def get_type_name(self):
+ return self.__class__.__name__
+
+ def get_spec(self):
+ return self.parent.get_spec()
+
+ def get_root_namespace(self):
+ return self.get_interface().name
+
+ def get_interface(self):
+ return self.parent.get_interface()
+
+ def get_anchor(self):
+ return "%s:%s" % (
+ self.get_type_name().replace(' ', '-'),
+ self.short_name)
+
+ def get_url(self):
+ return "%s#%s" % (self.get_interface().get_url(), self.get_anchor())
+
+ def _get_generic_with_ver(self, nnode, htmlclass, txt):
+ if nnode is None:
+ return ''
+ else:
+ # make a copy of this node, turn it into a HTML <div> tag
+ node = nnode.cloneNode(True)
+ node.tagName = 'div'
+ node.baseURI = None
+ node.setAttribute('class', 'annotation %s' % htmlclass)
+
+ try:
+ node.removeAttribute('version')
+
+ doc = self.get_spec().document
+
+ span = doc.createElement('span')
+ span.setAttribute('class', 'version')
+
+ text = doc.createTextNode(
+ txt % nnode.getAttribute('version') + ' ')
+ span.appendChild(text)
+
+ node.insertBefore(span, node.firstChild)
+ except xml.dom.NotFoundErr:
+ raise MissingVersion(
+ '%s was %s, but gives no version' % (self, htmlclass))
+
+ self._convert_to_html(node)
+
+ return node.toxml().encode('ascii', 'xmlcharrefreplace')
+
+ def get_added(self):
+ return self._get_generic_with_ver(self.added, 'added',
+ "Added in %s.")
+
+ def get_deprecated(self):
+ if self.deprecated is None:
+ if self.is_deprecated:
+ return '<div class="annotation deprecated no-version">Deprecated.</div>'
+ else:
+ return ''
+ else:
+ return self._get_generic_with_ver(self.deprecated, 'deprecated',
+ "Deprecated since %s.")
+
+ def get_changed(self):
+ return '\n'.join(map(lambda n:
+ self._get_generic_with_ver(n, 'changed', "Changed in %s."),
+ self.changed))
+
+ def get_docstring(self):
+ """Get the docstring for this node, but do node substitution to
+ rewrite types, interfaces, etc. as links.
+ """
+ if self.docstring is None:
+ return ''
+ else:
+ # make a copy of this node, turn it into a HTML <div> tag
+ node = self.docstring.cloneNode(True)
+ node.tagName = 'div'
+ node.baseURI = None
+ node.setAttribute('class', 'docstring')
+
+ self._convert_to_html(node)
+
+ return node.toxml().encode('ascii', 'xmlcharrefreplace')
+
+ def _convert_to_html(self, node):
+ spec = self.get_spec()
+ doc = spec.document
+ root_namespace = self.get_root_namespace()
+
+ # rewrite <tp:rationale>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'rationale'):
+ nested = n.getElementsByTagNameNS(XMLNS_TP, 'rationale')
+ if nested:
+ raise Xzibit(n, nested[0])
+
+ """
+ <div class='rationale'>
+ <h5>Rationale:</h5>
+ <div/> <- inner_div
+ </div>
+ """
+ outer_div = doc.createElement('div')
+ outer_div.setAttribute('class', 'rationale')
+
+ h5 = doc.createElement('h5')
+ h5.appendChild(doc.createTextNode('Rationale:'))
+ outer_div.appendChild(h5)
+
+ inner_div = doc.createElement('div')
+ outer_div.appendChild(inner_div)
+
+ for rationale_body in n.childNodes:
+ inner_div.appendChild(rationale_body.cloneNode(True))
+
+ n.parentNode.replaceChild(outer_div, n)
+
+ # rewrite <tp:type>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'type'):
+ t = spec.lookup_type(getText(n))
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', t.get_url())
+
+ # rewrite <tp:value-ref>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'value-ref'):
+ if n.hasAttribute('type'):
+ type_name = n.getAttribute('type')
+ value_name = getText(n)
+ t = spec.lookup_type(type_name)
+ assert isinstance(t, EnumLike), ("%s is not an enum or flags type"
+ % type_name)
+ else:
+ type_name = getText(n)
+ value_name_parts = []
+ while type_name not in spec.types:
+ type_name, _, rest = type_name.rpartition('_')
+ value_name_parts.insert(0, rest)
+ if not type_name:
+ raise ValueError("No substrings of '%s' describe "
+ "a valid type." % getText(n))
+ value_name = '_'.join(value_name_parts)
+ t = spec.lookup_type(type_name)
+ assert isinstance(t, EnumLike), ("%s is not an enum or flags type"
+ % type_name)
+
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', t.get_url())
+ short_names = [val.short_name for val in t.values]
+ if value_name not in short_names:
+ raise ValueError("'%s' is not a valid value of '%s'. "
+ "Valid values are %s" %
+ (value_name, type_name, short_names))
+
+ # rewrite <tp:error-ref>
+ error_ns = spec.spec_namespace + '.Error.'
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'error-ref'):
+ try:
+ e = spec.errors[error_ns + getText(n)]
+ except KeyError:
+ print >> sys.stderr, """
+WARNING: Error '%s' not known in error namespace '%s'
+ (<tp:error-ref> in %s)
+ """.strip() % (getText(n), error_ns[:-1], self)
+ continue
+
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', e.get_url())
+ n.setAttribute('title', error_ns + getText(n))
+
+ # rewrite <tp:member-ref>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'member-ref'):
+ key = getText(n)
+ try:
+ o = spec.lookup(key, namespace=root_namespace)
+ except KeyError:
+ print >> sys.stderr, """
+WARNING: Key '%s' not known in namespace '%s'
+ (<tp:member-ref> in %s)
+ """.strip() % (key, root_namespace, self)
+ continue
+
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', o.get_url())
+ n.setAttribute('title', o.get_title())
+
+ # rewrite <tp:dbus-ref>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'dbus-ref'):
+ namespace = n.getAttribute('namespace')
+ key = getText(n)
+
+ if namespace.startswith('ofdT.') or namespace == 'ofdT':
+ namespace = namespace.replace('ofdT',
+ 'org.freedesktop.Telepathy')
+
+ try:
+ o = spec.lookup(key, namespace=namespace)
+ except KeyError:
+ print >> sys.stderr, """
+WARNING: Key '%s' not known in namespace '%s'
+ (<tp:dbus-ref> in %s)
+ """.strip() % (key, namespace, self)
+ continue
+
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', o.get_url())
+ n.setAttribute('title', o.get_title())
+
+ # rewrite <tp:token-ref>
+ for n in node.getElementsByTagNameNS(XMLNS_TP, 'token-ref'):
+ key = getText(n)
+ namespace = n.getAttribute('namespace')
+
+ if namespace:
+ if namespace.startswith('ofdT.'):
+ namespace = 'org.freedesktop.Telepathy.' + namespace[5:]
+ else:
+ namespace = root_namespace
+
+ try:
+ try:
+ if '/' in key:
+ sep = '.'
+ else:
+ sep = '/'
+
+ o = spec.lookup(namespace + sep + key, None)
+ except KeyError:
+ o = spec.lookup(key, None)
+ except KeyError:
+ print >> sys.stderr, """
+WARNING: Key '%s' not known in namespace '%s'
+ (<tp:dbus-ref> in %s)
+ """.strip() % (key, namespace, self)
+ continue
+
+ n.tagName = 'a'
+ n.namespaceURI = None
+ n.setAttribute('href', o.get_url())
+ n.setAttribute('title', o.get_title())
+
+ # Fill in <tp:list-dbus-property-parameters/> with a linkified list of
+ # properties which are also connection parameters
+ for n in node.getElementsByTagNameNS(XMLNS_TP,
+ 'list-dbus-property-parameters'):
+ n.tagName = 'ul'
+ n.namespaceURI = None
+
+ props = (p for interface in spec.interfaces
+ for p in interface.properties
+ if p.is_connection_parameter
+ )
+
+ for p in props:
+ link_text = doc.createTextNode(p.name)
+
+ a = doc.createElement('a')
+ a.setAttribute('href', p.get_url())
+ a.appendChild(link_text)
+
+ # FIXME: it'd be nice to include the rich type of the property
+ # here too.
+ type_text = doc.createTextNode(' (%s)' % p.dbus_type)
+
+ li = doc.createElement('li')
+ li.appendChild(a)
+ li.appendChild(type_text)
+
+ n.appendChild(li)
+
+ def get_title(self):
+ return '%s %s' % (self.get_type_name(), self.name)
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, self.name)
+
+ def get_index_entries(self):
+ context = self.parent.get_index_context()
+ return set([
+ '%s (%s in %s)' % (self.short_name, self.get_type_name(), context),
+ '%s %s' % (self.get_type_name(), self.name)])
+
+ def get_index_context(self):
+ return self.short_name
+
+class DBusConstruct(Base):
+ """Base class for signals, methods and properties."""
+
+ def __init__(self, parent, namespace, dom):
+ super(DBusConstruct, self).__init__(parent, namespace, dom)
+
+ self.name_for_bindings = dom.getAttributeNS(XMLNS_TP,
+ 'name-for-bindings')
+
+ if not self.name_for_bindings:
+ raise BadNameForBindings('%s has no name-for-bindings'
+ % self)
+
+ if self.name_for_bindings.replace('_', '') != self.short_name:
+ raise BadNameForBindings('%s name-for-bindings = %s does not '
+ 'match short_name = %s' % (self, self.name_for_bindings,
+ self.short_name))
+
+class PossibleError(Base):
+ def __init__(self, parent, namespace, dom):
+ super(PossibleError, self).__init__(parent, namespace, dom)
+
+ def get_error(self):
+ spec = self.get_spec()
+ try:
+ return spec.errors[self.name]
+ except KeyError:
+ if not spec.allow_externals:
+ print >> sys.stderr, """
+WARNING: Error not known: '%s'
+ (<tp:possible-error> in %s)
+ """.strip() % (self.name, self.parent)
+
+ return External(self.name)
+
+ def get_url(self):
+ return self.get_error().get_url()
+
+ def get_title(self):
+ return self.get_error().get_title()
+
+ def get_docstring(self):
+ d = super(PossibleError, self).get_docstring()
+ if d == '':
+ return self.get_error().get_docstring()
+ else:
+ return d
+
+class Method(DBusConstruct):
+ devhelp_name = "function"
+
+ def __init__(self, parent, namespace, dom):
+ super(Method, self).__init__(parent, namespace, dom)
+
+ args = build_list(self, Arg, self.name,
+ dom.getElementsByTagName('arg'))
+
+ # separate arguments as input and output arguments
+ self.in_args = filter(lambda a: a.direction == Arg.DIRECTION_IN, args)
+ self.out_args = filter(lambda a: a.direction == Arg.DIRECTION_OUT, args)
+
+ for arg in args:
+ if arg.direction == Arg.DIRECTION_IN or \
+ arg.direction == Arg.DIRECTION_OUT:
+ continue
+
+ raise UnknownDirection("'%s' of method '%s' does not specify a suitable direction" % (arg, self))
+
+ self.possible_errors = build_list(self, PossibleError, None,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'error'))
+
+ self.no_reply = (getAnnotationByName(dom, 'org.freedesktop.DBus.Method.NoReply') == 'true')
+
+ def get_in_args(self):
+ return ', '.join(map(lambda a: a.spec_name(), self.in_args))
+
+ def get_out_args(self):
+ if len(self.out_args) > 0:
+ return ', '.join(map(lambda a: a.spec_name(), self.out_args))
+ else:
+ return 'nothing'
+
+ def check_consistency(self):
+ for x in self.in_args:
+ x.check_consistency()
+
+ for x in self.out_args:
+ x.check_consistency()
+
+class Typed(Base):
+ """The base class for all typed nodes (i.e. Arg and Property).
+
+ Don't instantiate this class directly.
+ """
+
+ def __init__(self, parent, namespace, dom):
+ super(Typed, self).__init__(parent, namespace, dom)
+
+ self.type = dom.getAttributeNS(XMLNS_TP, 'type')
+ self.dbus_type = dom.getAttribute('type')
+
+ # check we have a dbus type
+ if self.dbus_type == '':
+ raise UntypedItem("Node referred to by '%s' has no type" % dom.toxml())
+
+ def get_type(self):
+ return self.get_spec().lookup_type(self.type)
+
+ def get_type_url(self):
+ t = self.get_type()
+ if t is None: return ''
+ else: return t.get_url()
+
+ def get_type_title(self):
+ t = self.get_type()
+ if t is None: return ''
+ else: return t.get_title()
+
+ def check_consistency(self):
+ t = self.get_type()
+ if t is None:
+ if self.dbus_type not in (
+ # Basic types
+ 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'v', 'o',
+ 'g',
+ # QtDBus generic support
+ 'as', 'ay', 'av', 'a{sv}',
+ # telepathy-qt4 generic support
+ 'ab', 'an', 'aq', 'ai', 'au', 'ax', 'at', 'ad', 'ao', 'ag',
+ ):
+ raise TypeMismatch('%r type %s needs to be a named tp:type '
+ 'for QtDBus interoperability'
+ % (self, self.dbus_type))
+ else:
+ if self.dbus_type != t.dbus_type:
+ raise TypeMismatch('%r type %s isn\'t tp:type %s\'s type %s'
+ % (self, self.dbus_type, t, t.dbus_type))
+
+ def spec_name(self):
+ return '%s: %s' % (self.dbus_type, self.short_name)
+
+ def __repr__(self):
+ return '%s(%s:%s)' % (self.__class__.__name__, self.name, self.dbus_type)
+
+class HasEmitsChangedAnnotation(object):
+ EMITS_CHANGED_UNKNOWN = 0
+ EMITS_CHANGED_NONE = 1
+ EMITS_CHANGED_UPDATES = 2
+ EMITS_CHANGED_INVALIDATES = 3
+
+ # According to the D-Bus specification, EmitsChangedSignal defaults
+ # to true, but - realistically - this cannot be assumed for old specs.
+ # As a result, we treat the absence of the annotation as "unknown".
+ __MAPPING = { None: EMITS_CHANGED_UNKNOWN,
+ 'false': EMITS_CHANGED_NONE,
+ 'invalidates': EMITS_CHANGED_INVALIDATES,
+ 'true': EMITS_CHANGED_UPDATES,
+ }
+
+ __ANNOTATION = 'org.freedesktop.DBus.Property.EmitsChangedSignal'
+
+ def _get_emits_changed(self, dom):
+ emits_changed = getAnnotationByName(dom, self.__ANNOTATION)
+
+ try:
+ return self.__MAPPING[emits_changed]
+ except KeyError:
+ print >> sys.stderr, """
+WARNING: <annotation name='%s'/> has unknown value '%s'
+ (in %s)
+ """.strip() % (self.__ANNOTATION, emits_changed, self)
+ return self.EMITS_CHANGED_UNKNOWN;
+
+class Property(DBusConstruct, Typed, HasEmitsChangedAnnotation):
+ ACCESS_READ = 1
+ ACCESS_WRITE = 2
+
+ ACCESS_READWRITE = ACCESS_READ | ACCESS_WRITE
+
+ def __init__(self, parent, namespace, dom):
+ super(Property, self).__init__(parent, namespace, dom)
+
+ access = dom.getAttribute('access')
+ if access == 'read':
+ self.access = self.ACCESS_READ
+ elif access == 'write':
+ self.access = self.ACCESS_WRITE
+ elif access == 'readwrite':
+ self.access = self.ACCESS_READWRITE
+ else:
+ raise UnknownAccess("Unknown access '%s' on %s" % (access, self))
+
+ is_cp = dom.getAttributeNS(XMLNS_TP, 'is-connection-parameter')
+ self.is_connection_parameter = is_cp != ''
+
+ immutable = dom.getAttributeNS(XMLNS_TP, 'immutable')
+ self.immutable = immutable != ''
+ self.sometimes_immutable = immutable == 'sometimes'
+
+ requestable = dom.getAttributeNS(XMLNS_TP, 'requestable')
+ self.requestable = requestable != ''
+ self.sometimes_requestable = requestable == 'sometimes'
+
+ self.emits_changed = self._get_emits_changed(dom)
+
+ if self.emits_changed == self.EMITS_CHANGED_UNKNOWN:
+ # If the <property> doesn't have the annotation, grab it from the
+ # interface.
+ self.emits_changed = parent.emits_changed
+
+ def get_access(self):
+ if self.access & self.ACCESS_READ and self.access & self.ACCESS_WRITE:
+ return 'Read/Write'
+ elif self.access & self.ACCESS_READ:
+ return 'Read only'
+ elif self.access & self.ACCESS_WRITE:
+ return 'Write only'
+
+ def get_flag_summary(self):
+ descriptions = []
+
+ if self.sometimes_immutable:
+ descriptions.append("Sometimes immutable")
+ elif self.immutable:
+ descriptions.append("Immutable")
+
+ if self.sometimes_requestable:
+ descriptions.append("Sometimes requestable")
+ elif self.requestable:
+ descriptions.append("Requestable")
+
+ return ', '.join(descriptions)
+
+class AwkwardTelepathyProperty(Typed):
+ def __init__(self, parent, namespace, dom):
+ Typed.__init__(self, parent, namespace, dom)
+
+ print >> sys.stderr, """
+WARNING: Old-style Telepathy properties are deprecated!
+ (<tp:property> in %s)
+ """.strip() % (parent)
+
+ def get_type_name(self):
+ return 'Telepathy Property'
+
+class Arg(Typed):
+ DIRECTION_IN, DIRECTION_OUT, DIRECTION_UNSPECIFIED = range(3)
+
+ def __init__(self, parent, namespace, dom):
+ super(Arg, self).__init__(parent, namespace, dom)
+
+ direction = dom.getAttribute('direction')
+ if direction == 'in':
+ self.direction = self.DIRECTION_IN
+ elif direction == 'out':
+ self.direction = self.DIRECTION_OUT
+ elif direction == '':
+ self.direction = self.DIRECTION_UNSPECIFIED
+ else:
+ raise UnknownDirection("Unknown direction '%s' on %s" % (
+ direction, self.parent))
+
+class Signal(DBusConstruct):
+ def __init__(self, parent, namespace, dom):
+ super(Signal, self).__init__(parent, namespace, dom)
+
+ self.args = build_list(self, Arg, self.name,
+ dom.getElementsByTagName('arg'))
+
+ for arg in self.args:
+ if arg.direction == Arg.DIRECTION_UNSPECIFIED:
+ continue
+
+ raise UnknownDirection("'%s' of signal '%s' does not specify a suitable direction" % (arg, self))
+
+ def get_args(self):
+ return ', '.join(map(lambda a: a.spec_name(), self.args))
+
+class External(object):
+ """External objects are objects that are referred to in another spec.
+
+ We have to attempt to look them up if at all possible.
+ """
+
+ def __init__(self, name):
+ self.name = self.short_name = name
+
+ def get_url(self):
+ return None
+
+ def get_title(self):
+ return 'External %s' % self.name
+
+ def get_docstring(self):
+ return None
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, self.name)
+
+class Interface(Base, HasEmitsChangedAnnotation):
+ def __init__(self, parent, namespace, dom, spec_namespace):
+ super(Interface, self).__init__(parent, namespace, dom)
+
+ # For code generation, the <node> provides a name to be used in
+ # C function names, etc.
+ parent = dom.parentNode
+ if parent.localName != 'node':
+ raise BadNameForBindings("%s's parent is not a <node>" % self)
+
+ node_name = parent.getAttribute('name')
+
+ if node_name[0] != '/' or not node_name[1:]:
+ raise BadNameForBindings("%s's parent <node> has bad name %s"
+ % (self, node_name))
+
+ self.name_for_bindings = node_name[1:]
+
+ # If you're writing a spec with more than one top-level namespace, you
+ # probably want to replace spec_namespace with a list.
+ if self.name.startswith(spec_namespace + "."):
+ self.short_name = self.name[len(spec_namespace) + 1:]
+ else:
+ self.short_name = self.name
+
+ # Bit of a hack, but... I want useful information about the current
+ # page to fit in a tab in Chromium. I'm prepared to be disagreed with.
+ self.really_short_name = (
+ ('.'+self.short_name).replace('.Interface.', '.I.')
+ .replace('.Channel.', '.Chan.')
+ .replace('.Connection.', '.Conn.')
+ .replace('.Type.', '.T.')[1:]
+ )
+
+ self.emits_changed = self._get_emits_changed(dom)
+
+ # build lists of methods, etc., in this interface
+ self.methods = build_list(self, Method, self.name,
+ dom.getElementsByTagName('method'))
+ self.properties = build_list(self, Property, self.name,
+ dom.getElementsByTagName('property'))
+ self.signals = build_list(self, Signal, self.name,
+ dom.getElementsByTagName('signal'))
+ self.tpproperties = build_list(self, AwkwardTelepathyProperty,
+ self.name, dom.getElementsByTagNameNS(XMLNS_TP, 'property'))
+
+ hct_elems = (
+ dom.getElementsByTagNameNS(XMLNS_TP, 'handler-capability-token') +
+ dom.getElementsByTagNameNS(XMLNS_TP, 'hct'))
+ self.handler_capability_tokens = build_list(self,
+ HandlerCapabilityToken, self.name,
+ hct_elems)
+
+ self.contact_attributes = build_list(self, ContactAttribute, self.name,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'contact-attribute'))
+
+ self.client_interests = build_list(self, ClientInterest, self.name,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'client-interest'))
+
+ # build a list of types in this interface
+ self.types = parse_types(self, dom, self.name)
+
+ # find out if this interface causes havoc
+ self.causes_havoc = dom.getAttributeNS(XMLNS_TP, 'causes-havoc')
+ if self.causes_havoc == '': self.causes_havoc = None
+
+ # find out what we're required to also implement
+ self.requires = map(lambda n: n.getAttribute('interface'),
+ getChildrenByName(dom, XMLNS_TP, 'requires'))
+
+ def map_xor(element):
+ return map(lambda n: n.getAttribute('interface'),
+ getChildrenByName(element, XMLNS_TP, 'requires'))
+
+ self.xor_requires = map(map_xor,
+ getChildrenByName(dom, XMLNS_TP, 'xor-requires'))
+
+ # let's make sure there's nothing we don't know about here
+ self.check_for_odd_children(dom)
+
+ self.is_channel_related = self.name.startswith(spec_namespace + '.Channel')
+
+ def get_interface(self):
+ return self
+
+ def lookup_requires(self, r):
+ spec = self.get_spec()
+
+ try:
+ return spec.lookup(r)
+ except KeyError:
+ if not spec.allow_externals:
+ print >> sys.stderr, """
+WARNING: Interface not known: '%s'
+ (<tp:requires> in %s)
+ """.strip() % (r, self)
+
+ return External(r)
+
+ def get_requires(self):
+ return map(self.lookup_requires, self.requires)
+
+ def get_xor_requires(self):
+ def xor_lookup(r):
+ return map(self.lookup_requires, r)
+
+ return map(xor_lookup, self.xor_requires)
+
+ def get_url(self):
+ return '%s.html' % self.name_for_bindings
+
+ def check_for_odd_children(self, dom):
+ expected = [
+ (None, 'annotation'),
+ (None, 'method'),
+ (None, 'property'),
+ (None, 'signal'),
+ (XMLNS_TP, 'property'),
+ (XMLNS_TP, 'handler-capability-token'),
+ (XMLNS_TP, 'hct'),
+ (XMLNS_TP, 'contact-attribute'),
+ (XMLNS_TP, 'client-interest'),
+ (XMLNS_TP, 'simple-type'),
+ (XMLNS_TP, 'enum'),
+ (XMLNS_TP, 'flags'),
+ (XMLNS_TP, 'mapping'),
+ (XMLNS_TP, 'struct'),
+ (XMLNS_TP, 'external-type'),
+ (XMLNS_TP, 'requires'),
+ (XMLNS_TP, 'xor-requires'),
+ (XMLNS_TP, 'added'),
+ (XMLNS_TP, 'changed'),
+ (XMLNS_TP, 'deprecated'),
+ (XMLNS_TP, 'docstring')
+ ]
+
+ unexpected = [
+ x for x in dom.childNodes
+ if isinstance(x, xml.dom.minidom.Element) and
+ (x.namespaceURI, x.localName) not in expected
+ ]
+
+ if unexpected:
+ print >> sys.stderr, """
+WARNING: Unknown element(s): %s
+ (in interface '%s')
+ """.strip() % (', '.join([x.tagName for x in unexpected]), self.name)
+
+class Error(Base):
+ def get_url(self):
+ return 'errors.html#%s' % self.get_anchor()
+
+ def get_root_namespace(self):
+ return self.namespace
+
+class DBusList(object):
+ """Stores a list of a given DBusType. Provides some basic validation to
+ determine whether or not the type is sane.
+ """
+ def __init__(self, child):
+ self.child = child
+
+ if isinstance(child, DBusType):
+ self.ultimate = child
+ self.depth = 1
+
+ if self.child.array_name == '':
+ raise UnsupportedArray("Type '%s' does not support being "
+ "used in an array" % self.child.name)
+ else:
+ self.name = build_name(self.child.namespace,
+ self.child.array_name)
+ self.short_name = self.child.array_name
+
+ elif isinstance(child, DBusList):
+ self.ultimate = child.ultimate
+ self.depth = child.depth + 1
+ self.name = self.child.name + '_List'
+ self.short_name = self.child.short_name + '_List'
+
+ # check that our child can operate at this depth
+ maxdepth = int(self.ultimate.array_depth)
+ if self.depth > maxdepth:
+ raise TypeError("Type '%s' has exceeded its maximum depth (%i)" % (self, maxdepth))
+
+ else:
+ raise TypeError("DBusList can contain only a DBusType or DBusList not '%s'" % child)
+
+ self.dbus_type = 'a' + self.child.dbus_type
+
+ def get_url(self):
+ return self.ultimate.get_url()
+
+ def get_title(self):
+ return "Array of %s" % self.child.get_title()
+
+ def __repr__(self):
+ return 'Array(%s)' % self.child
+
+class DBusType(Base):
+ """The base class for all D-Bus types referred to in the spec.
+
+ Don't instantiate this class directly.
+ """
+
+ devhelp_name = "typedef"
+
+ def __init__(self, parent, namespace, dom):
+ super(DBusType, self).__init__(parent, namespace, dom)
+
+ self.dbus_type = dom.getAttribute('type')
+ self.array_name = dom.getAttribute('array-name')
+ self.array_depth = dom.getAttribute('array-depth')
+ self.name = self.short_name
+
+ def get_root_namespace(self):
+ return self.namespace
+
+ def get_breakdown(self):
+ return ''
+
+ def get_url(self):
+ if isinstance(self.parent, Interface):
+ html = self.parent.get_url()
+ else:
+ html = 'generic-types.html'
+
+ return '%s#%s' % (html, self.get_anchor())
+
+class SimpleType(DBusType):
+ def get_type_name(self):
+ return 'Simple Type'
+
+class ExternalType(DBusType):
+ def __init__(self, parent, namespace, dom):
+ super(ExternalType, self).__init__(parent, namespace, dom)
+
+ # FIXME: until we are able to cross reference external types to learn
+ # about their array names, we're just going to assume they work like
+ # this
+ self.array_name = self.short_name + '_List'
+
+ def get_type_name(self):
+ return 'External Type'
+
+class StructLike(DBusType):
+ """Base class for all D-Bus types that look kind of like Structs
+
+ Don't instantiate this class directly.
+ """
+
+ class StructMember(Typed):
+ def get_root_namespace(self):
+ return self.parent.get_root_namespace()
+
+ def __init__(self, parent, namespace, dom):
+ super(StructLike, self).__init__(parent, namespace, dom)
+
+ self.members = build_list(self, StructLike.StructMember, None,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'member'))
+
+ def get_breakdown(self):
+ str = ''
+ str += '<ul>\n'
+ for member in self.members:
+ # attempt to lookup the member up in the type system
+ t = member.get_type()
+
+ str += '<li>%s &mdash; %s' % (member.name, member.dbus_type)
+ if t: str += ' (<a href="%s" title="%s">%s</a>)' % (
+ t.get_url(), t.get_title(), t.short_name)
+ str += '</li>\n'
+ str += member.get_docstring()
+ str += '</ul>\n'
+
+ return str
+
+class Mapping(StructLike):
+ def __init__(self, parent, namespace, dom):
+ super(Mapping, self).__init__(parent, namespace, dom)
+
+ if len(self.members) != 2:
+ raise WrongNumberOfChildren('%s node should have exactly two tp:members'
+ % dom.tagName)
+
+ # rewrite the D-Bus type
+ self.dbus_type = 'a{%s}' % ''.join(map(lambda m: m.dbus_type, self.members))
+
+ # not sure why tp:mapping sometimes has a type attribute, but
+ # make sure it's right.
+ t = dom.getAttribute('type')
+ if t and self.dbus_type != t:
+ raise TypeMismatch('%r reports type is %s but actual type is %s'
+ % (self, t, self.dbus_type))
+
+class Struct(StructLike):
+
+ devhelp_name = "struct"
+
+ def __init__(self, parent, namespace, dom):
+ super(Struct, self).__init__(parent, namespace, dom)
+
+ if len(self.members) == 0:
+ raise WrongNumberOfChildren('%s node should have a tp:member'
+ % dom.tagName)
+
+ # rewrite the D-Bus type
+ self.dbus_type = '(%s)' % ''.join(map(lambda m: m.dbus_type, self.members))
+
+class EnumLike(DBusType):
+ """Base class for all D-Bus types that look kind of like Enums
+
+ Don't instantiate this class directly.
+ """
+ class EnumValue(Base):
+ def __init__(self, parent, namespace, dom):
+ super(EnumLike.EnumValue, self).__init__(parent, namespace, dom)
+
+ # rewrite self.name
+ self.short_name = dom.getAttribute('suffix')
+ self.name = build_name(namespace, self.short_name)
+
+ self.value = dom.getAttribute('value')
+
+ super(EnumLike.EnumValue, self).validate()
+
+ def validate(self):
+ pass
+
+ def get_root_namespace(self):
+ return self.parent.get_root_namespace()
+
+ def get_breakdown(self):
+ str = ''
+ str += '<ul>\n'
+ for value in self.values:
+ # attempt to lookup the member.name as a type in the type system
+ str += '<li>%s (%s)</li>\n' % (value.short_name, value.value)
+ str += value.get_added()
+ str += value.get_changed()
+ str += value.get_deprecated()
+ str += value.get_docstring()
+ str += '</ul>\n'
+
+ return str
+
+ def check_for_duplicates(self):
+ # make sure no two values have the same value
+ for u in self.values:
+ for v in [x for x in self.values if x is not u]:
+ if u.value == v.value:
+ raise DuplicateEnumValueValue('%s %s has two values '
+ 'with the same value: %s=%s and %s=%s' % \
+ (self.__class__.__name__, self.name, \
+ u.short_name, u.value, v.short_name, v.value))
+
+
+class Enum(EnumLike):
+
+ devhelp_name = "enum"
+
+ def __init__(self, parent, namespace, dom):
+ super(Enum, self).__init__(parent, namespace, dom)
+
+ if self.name.endswith('Flag') or self.name.endswith('Flags'):
+ raise MismatchedFlagsAndEnum('%s should probably be tp:flags, '
+ 'not tp:enum' % self.name)
+
+ if dom.getElementsByTagNameNS(XMLNS_TP, 'flag'):
+ raise MismatchedFlagsAndEnum('%s is a tp:enum, so it should not '
+ 'contain tp:flag' % self.name)
+
+ self.values = build_list(self, EnumLike.EnumValue, self.name,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'enumvalue'))
+
+ self.check_for_duplicates()
+
+class Flags(EnumLike):
+ def __init__(self, parent, namespace, dom):
+ super(Flags, self).__init__(parent, namespace, dom)
+
+ if dom.getAttribute('type') != 'u':
+ raise BadFlagsType('Flags %s doesn\'t make sense to be of '
+ 'type "%s" (only type "u" makes sense")' % (
+ self.name, dom.getAttribute('type')))
+
+ if dom.getElementsByTagNameNS(XMLNS_TP, 'enumvalue'):
+ raise MismatchedFlagsAndEnum('%s is a tp:flags, so it should not '
+ 'contain tp:enumvalue' % self.name)
+
+ self.values = build_list(self, EnumLike.EnumValue, self.name,
+ dom.getElementsByTagNameNS(XMLNS_TP, 'flag'))
+ self.flags = self.values # in case you're looking for it
+
+ self.check_for_duplicates()
+
+ # make sure all these values are sane
+ for flag in self.values:
+ v = int(flag.value)
+
+ # positive x is a power of two if (x & (x - 1)) = 0.
+ if v == 0 or (v & (v - 1)) != 0:
+ raise BadFlagValue('Flags %s has bad value (not a power of '
+ 'two): %s=%s' % (self.name, flag.short_name, v))
+
+class TokenBase(Base):
+
+ devhelp_name = "macro" # it's a constant, which is near enough...
+ separator = '/'
+
+ def __init__(self, parent, namespace, dom):
+ super(TokenBase, self).__init__(parent, namespace, dom)
+
+ items = [ namespace ]
+
+ if self.short_name != '':
+ items.append (self.short_name)
+
+ self.name = self.separator.join (items)
+
+class ContactAttribute(TokenBase, Typed):
+
+ def get_type_name(self):
+ return 'Contact Attribute'
+
+class HandlerCapabilityToken(TokenBase):
+
+ def get_type_name(self):
+ return 'Handler Capability Token'
+
+ def __init__(self, parent, namespace, dom):
+ super(HandlerCapabilityToken, self).__init__(parent, namespace, dom)
+
+ is_family = dom.getAttribute('is-family')
+ assert is_family in ('yes', 'no', '')
+ self.is_family = (is_family == 'yes')
+
+class ClientInterest(TokenBase):
+
+ def __init__(self, parent, namespace, dom):
+ super(ClientInterest, self).__init__(parent, namespace, dom)
+
+ self.short_name = self.name
+
+ def get_type_name(self):
+ return 'Client Interest'
+
+ def validate(self):
+ pass
+
+class SectionBase(object):
+ """A SectionBase is an abstract base class for any type of node that can
+ contain a <tp:section>, which means the top-level Spec object, or any
+ Section object.
+
+ It should not be instantiated directly.
+ """
+
+ def __init__(self, dom, spec_namespace):
+ self.spec_namespace = spec_namespace
+ self.items = []
+
+ def recurse(nodes):
+ # iterate through the list of child nodes
+ for node in nodes:
+ if node.nodeType != node.ELEMENT_NODE: continue
+
+ if node.tagName == 'node':
+ # recurse into this level for interesting items
+ recurse(node.childNodes)
+ elif node.namespaceURI == XMLNS_TP and \
+ node.localName == 'section':
+ self.items.append(Section(self, None, node,
+ spec_namespace))
+ elif node.tagName == 'interface':
+ self.items.append(Interface(self, None, node,
+ spec_namespace))
+
+ recurse(dom.childNodes)
+
+ def get_index_context(self):
+ return self.spec_namespace
+
+class Section(Base, SectionBase):
+ def __init__(self, parent, namespace, dom, spec_namespace):
+ Base.__init__(self, parent, namespace, dom)
+ SectionBase.__init__(self, dom, spec_namespace)
+
+ def get_root_namespace(self):
+ return None
+
+class ErrorsSection(Section):
+ def validate(self):
+ pass
+
+class Spec(SectionBase):
+ def __init__(self, dom, spec_namespace, allow_externals=False):
+ self.document = dom
+ self.spec_namespace = spec_namespace
+ self.short_name = spec_namespace
+ self.allow_externals = allow_externals
+
+ # build a dictionary of errors in this spec
+ try:
+ errorsnode = dom.getElementsByTagNameNS(XMLNS_TP, 'errors')[0]
+ self.errors = build_dict(self, Error,
+ errorsnode.getAttribute('namespace'),
+ errorsnode.getElementsByTagNameNS(XMLNS_TP, 'error'))
+ self.errors_section = ErrorsSection(self, None, errorsnode,
+ spec_namespace)
+ except IndexError:
+ self.errors = {}
+ self.errors_section = None
+
+ self.sorted_errors = sorted(self.errors.values(),
+ key=lambda e: e.name)
+
+ # build a list of generic types
+ self.generic_types = reduce (lambda a, b: a + b,
+ map(lambda l: parse_types(self, l),
+ dom.getElementsByTagNameNS(XMLNS_TP, 'generic-types')),
+ [])
+
+ # create a top-level section for this Spec
+ SectionBase.__init__(self, dom.documentElement, spec_namespace)
+
+ # build a list of interfaces in this spec
+ self.interfaces = []
+ def recurse(items):
+ for item in items:
+ if isinstance(item, Section): recurse(item.items)
+ elif isinstance(item, Interface): self.interfaces.append(item)
+ recurse(self.items)
+
+ # build a giant dictionary of everything (interfaces, methods, signals
+ # and properties); also build a dictionary of types
+ self.everything = {}
+ self.types = {}
+
+ for type in self.generic_types:
+ self.types[type.name] = type
+
+ for interface in self.interfaces:
+ self.everything[interface.name] = interface
+
+ for things in [ 'methods', 'signals', 'properties',
+ 'tpproperties', 'contact_attributes',
+ 'handler_capability_tokens',
+ 'client_interests' ]:
+ for thing in getattr(interface, things):
+ self.everything[thing.name] = thing
+
+ for type in interface.types:
+ self.types[type.name] = type
+
+ # get some extra bits for the HTML
+ node = dom.getElementsByTagNameNS(XMLNS_TP, 'spec')[0]
+ self.title = getText(getChildrenByName(node, XMLNS_TP, 'title')[0])
+
+ try:
+ self.version = getText(getChildrenByName(node, XMLNS_TP, 'version')[0])
+ except IndexError:
+ self.version = None
+
+ self.copyrights = map(getText,
+ getChildrenByName(node, XMLNS_TP, 'copyright'))
+
+ try:
+ license = getChildrenByName(node, XMLNS_TP, 'license')[0]
+ self.license = map(getText, license.getElementsByTagName('p'))
+ except IndexError:
+ self.license = []
+
+ self.check_consistency()
+
+ def check_consistency(self):
+ for x in self.everything.values():
+ x.check_consistency()
+
+ def get_spec(self):
+ return self
+
+ def lookup(self, name, namespace=None):
+ key = build_name(namespace, name)
+ return self.everything[key]
+
+ def lookup_type(self, type_):
+ if type_.endswith('[]'):
+ return DBusList(self.lookup_type(type_[:-2]))
+
+ if type_ == '': return None
+ elif type_ in self.types:
+ return self.types[type_]
+
+ raise UnknownType("Type '%s' is unknown" % type_)
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, self.title)
+
+def build_dict(parent, type_, namespace, nodes):
+ """Build a dictionary of D-Bus names to Python objects representing that
+ name using the XML node for that item in the spec.
+
+ e.g. 'org.freedesktop.Telepathy.Channel' : Interface(Channel)
+
+ Works for any Python object inheriting from 'Base' whose XML node
+ implements the 'name' attribute.
+ """
+
+ def build_tuple(node):
+ o = type_(parent, namespace, node)
+ return(o.name, o)
+
+ return dict(build_tuple(n) for n in nodes)
+
+def build_list(parent, type_, namespace, nodes):
+ return map(lambda node: type_(parent, namespace, node), nodes)
+
+def parse_types(parent, dom, namespace = None):
+ """Parse all of the types of type nodes mentioned in 't' from the node
+ 'dom' and insert them into the dictionary 'd'.
+ """
+ t = [
+ (SimpleType, 'simple-type'),
+ (Enum, 'enum'),
+ (Flags, 'flags'),
+ (Mapping, 'mapping'),
+ (Struct, 'struct'),
+ (ExternalType, 'external-type'),
+ ]
+
+ types = []
+
+ for (type_, tagname) in t:
+ types += build_list(parent, type_, namespace,
+ dom.getElementsByTagNameNS(XMLNS_TP, tagname))
+
+ return types
+
+def parse(filename, spec_namespace, allow_externals=False):
+ dom = xml.dom.minidom.parse(filename)
+ xincludator.xincludate(dom, filename)
+
+ spec = Spec(dom, spec_namespace, allow_externals=allow_externals)
+
+ return spec
+
+if __name__ == '__main__':
+ parse(sys.argv[1])
diff --git a/spec/tools/xincludator.py b/spec/tools/xincludator.py
new file mode 100644
index 000000000..63e106ace
--- /dev/null
+++ b/spec/tools/xincludator.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+
+from sys import argv, stdout, stderr
+import codecs, locale
+import os
+import xml.dom.minidom
+
+stdout = codecs.getwriter('utf-8')(stdout)
+
+NS_XI = 'http://www.w3.org/2001/XInclude'
+
+def xincludate(dom, base, dropns = []):
+ remove_attrs = []
+ for i in xrange(dom.documentElement.attributes.length):
+ attr = dom.documentElement.attributes.item(i)
+ if attr.prefix == 'xmlns':
+ if attr.localName in dropns:
+ remove_attrs.append(attr)
+ else:
+ dropns.append(attr.localName)
+ for attr in remove_attrs:
+ dom.documentElement.removeAttributeNode(attr)
+ for include in dom.getElementsByTagNameNS(NS_XI, 'include'):
+ href = include.getAttribute('href')
+ # FIXME: assumes Unixy paths
+ filename = os.path.join(os.path.dirname(base), href)
+ subdom = xml.dom.minidom.parse(filename)
+ xincludate(subdom, filename, dropns)
+ if './' in href:
+ subdom.documentElement.setAttribute('xml:base', href)
+ include.parentNode.replaceChild(subdom.documentElement, include)
+
+if __name__ == '__main__':
+ argv = argv[1:]
+ dom = xml.dom.minidom.parse(argv[0])
+ xincludate(dom, argv[0])
+ xml = dom.toxml()
+ stdout.write(xml)
+ stdout.write('\n')