telepathy-qt-0.9.6~git1/ 0000775 0001750 0001750 00000000000 12470405666 012756 5 ustar jr jr telepathy-qt-0.9.6~git1/doxygen-header.html 0000664 0001750 0001750 00000001652 12470405660 016545 0 ustar jr jr
$title
telepathy-qt-0.9.6~git1/COPYING 0000664 0001750 0001750 00000063637 12470405660 014022 0 ustar jr jr
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.
Copyright (C)
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.
, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
telepathy-qt-0.9.6~git1/NEWS 0000664 0001750 0001750 00000176064 12470405660 013465 0 ustar jr jr telepathy-qt 0.9.6 ()
=================================
The "..." release.
telepathy-qt 0.9.5 (2014-09-09)
=================================
The "Return of the Akademy Release" release.
Enhancements:
* Added more service side bindings
* Service bindings now enabled by default
* Bump Farstream version
* Allow subclass of Tp::ReceivedMessage
Fixes:
* fd.o #77986: Workaround invalid channelRequests when delegating
telepathy-qt 0.9.4 (2014-06-14)
=================================
The "Back from the dead" release.
Enhancements:
* fd.o #63098: add method Account::createDbusTubeRoom
Fixes:
* fd.o #46241: Fixed linking in farstream and farsight
* Require tp-glib 0.18 and fix 0.19-ism
* fd.o #47647: Fixed storing avatars, so that they are not stored millions
of times each.
* fd.o #62711: Fixed stack overflow in SimpleObserver::create
* Fix compilation and running against release Qt5
Cleanups:
* Removed Farsight
telepathy-qt 0.9.3 (2012-07-13)
=================================
The "We promised, we delivered" release.
Enhancements:
* Added ClientTypes bindings to Contact.
* Fixed deprecation macros, and added TP_QT_EXPORT_DEPRECATED.
* Ported SimpleCallObserver to also handle Call1 calls.
* Deprecated Farsight and StreamedMedia.
Fixes:
* Removed occurencies of deprecated tp-glib functions from the DBus tube tests.
* Fixed DISABLE_WERROR, which now works as expected.
* Fixed linking of the DBus tube tests with strict linkers like gold.
* Synced tests/lib/glib/utils.* to remove deprecation warnings.
* Removed occurencies of the deprecated tp_connection_new from Farsight/Farstream.
telepathy-qt 0.9.2 (2012-07-04)
=================================
The "We were at aKademy and we got bored" release.
Enhancements:
* Introducing Telepathy-Qt-Service, a new static library that contains
experimental service-side bindings. For the moment this exposes
the required low-level interfaces for writing connection managers,
as well as some basic high-level API.
* Renamed AccountManager::accountForPath() and AccountManager::accountsForPaths()
to accountForObjectPath() and accountsForObjectPaths() respectively,
deprecating the old names.
* Added bindings for Debug interface.
* Enable several options in CMake to allow to selectively build components. In particular,
now Farsight, Farstream, examples and tests are optional. Farsight is disabled by default.
* fd.o #28366: Added high level bindings for DBus tubes.
Fixes:
* Fix PkgConfig detection in DBus find files
* Fix a race condition in test-account-basics and test-dbus-properties.
* Fix compilation with gcc 4.7.
* Fix tests compilation with telepathy-glib 0.19.
* Fix FindDBus.cmake to find the correct paths.
* Pass -fvisibility-inlines-hidden to the compiler if it's supported.
telepathy-qt 0.9.1 (2012-03-23)
=================================
The "it is call time" release.
Enhancements:
* fd.o #43025: Tp::Presence now has a setStatusMessage() method which keeps the
old status id and status type
* Added methods in Tp::AbstractInterface to support PropertiesChanged. This way it is
possible for internal classes to monitor any property belonging to their interface
* fd.o #46403: Update spec files to spec 0.25.2 and generate low-level bindings
for all non-draft interfaces
* fd.o #46347: Added high-level bindings for new CaptchaAuthentication interface
* fd.o #46484: Add high-level Call bindings
* Introducing new Telepathy-Qt-Farstream, a new mini-library with glue code to
connect telepathy-farstream to Telepathy-Qt
Fixes:
* fd.o #45850: Telepathy Qt4 cannot compile against glib 2.31.0 and above
* fd.o #39346: telepathy-qt fails to build with clang
* fd.o #45755: Inconsistent ordering of pendingMessageRemoved
telepathy-qt 0.9.0 (2011-12-20)
================================
The "Merry Christmas" release.
This release begins the new 0.9 development series for feature additions
following the 0.8 stable release series.
Starting with this release the project is renamed to telepathy-qt (TelepathyQt) and
Qt5 support is added alongside Qt4 support and for that 0.9 will be
API (see changes below) and ABI incompatible with previous versions.
API changes:
* Everything containing qt4 (with or without caps) was renamed to qt.
Eg.:
- TP_QT4_DEPRECATED -> TP_QT_DEPRECATED
- #include -> #include
* Errors and constant macros starting with TELEPATHY_ (const char *
versions) were removed, remaining only the versions that expand to
QLatin1String.
Eg.:
- TELEPATHY_ERROR_INVALID_HANDLE <- removed
- TP_QT4_ERROR_INVALID_HANDLE -> TP_QT_ERROR_INVALID_HANDLE
* All deprecated methods (marked with TP_QT4_DEPRECATED) and signals
(those that used to emit warnings at runtime when connecting to them)
were removed.
* StreamTubeChannel::connections() now returns a QSet instead of an
UIntList.
* Channel::groupContacts and groupLocal/RemotePendingContacts() gained
a "includeSelfContact" param defaulting to true.
* KeyFile and ManagerFile classes are now removed from public API.
* SharedPtr cannot be constructed from a QWeakPointer anymore as the
conversion from a QWeakPointer to a SharedPtr can't be made thread-safe.
WeakPtr is reintroduced as a weak pointer class safely promoteable to a
SharedPtr.
* TelepathyQt-Farsight does not include telepathy-farsight/channel.h
directly anymore.
* ContactManager::lookupContactByHandle() is removed from public API.
Enhancements:
* fd.o #35084: The StreamTubeClient and StreamTubeServer classes have been
added to allow implementing Telepathy Stream Tube connectivity for
applications without having to worry about the channel dispatching details
* Contact::refreshInfo() requests are now batched together on D-Bus
* fd.o #41356: Implement methods to retrieve available message types on
TextChannel.
* fd.o #43631: Add CMake config files. Now CMake projects can find Tp-Qt
straight away without the need of Find* files.
* fd.o #43598 - Add high-level API for Proto.I.Addressing interface
* fd.o #43599 - Add high-level API for Conn.I.Addressing interface
Fixes:
* Our TODO process being completely out of date. Trying to use doxygen \todo
annotations from now on
* FeatureRoster is set on Tp::Connection even for roster-less accounts.
Known issues:
* Some tests are failing for some Qt 4.7 configurations, reports on fd.o bug
#43551 please.
telepathy-qt4 0.7.3 (2011-10-07)
================================
The "a must" release.
Enhancements:
* Added HandleTypeRoom StreamTubes to ChannelClassSpec
* It is now possible to capture and redirect the library debug output via
setting a DebugCallback using the Tp::setDebugCallback function
* The ChannelClassSpec implementation has been optimized, which yields
ChannelFactory setup and consequently application startup speedups
* StreamTubeChannel now ensures connectionClosed() is emitted for all
connections on a closing tube
* Add Presence/PresenceSpec operator== support
* Add Presence/PresenceSpec operator!= support (Rohan Garg)
* Add Authentication.TLSCertificate to the set of generated interfaces
* Improve file transfer examples to properly use the ChannelDispatcher
Fixes:
* Ensure that the proper Channel Dispatcher methods are being called when
creating/ensuring channels.
* Prevent PendingContacts crashes in corner cases where contacts are still
being built when a Connection is destroyed. Note that this affects which
object is returned by PendingContacts::object() - we've now made it explicit
that object() shouldn't be used externally as we make no guarantees on what
object it returns, by deprecating it. It will be made protected: in the next
API break
* Passing a non-empty service param to
ChannelClassSpec::{incoming,outgoing}StreamTube() messing up the shared
instance as used by e.g. ChannelFactory
* Connections not being removed from StreamTubeChannel::connections() when they
are closed, and newConnection() and connectionClosed() events getting
reordered
* fd.o# 40655 - ChannelDispatchOperation::claim() cannot be used by Approvers
to handle channels
* Codegen is now able to utilize types with D-Bus signature aay, aas and aav
* Account/Connection/Channel now properly check if FeatureCore is ready on
accessors
* Readded erroneously removed protected API to StreamTubeChannel, which
restores full ABI backwards compatibility.
telepathy-qt4 0.7.2 (2011-08-04)
================================
The "Stage 0 Tune Up" release.
Enhancements:
* Lots of additions and corrections to API documentation
* Code generator now produces nicer output for member-ref, dbus-ref and
rationale elements in docstrings
* The stable D-Bus interfaces Account.Interface.Storage, Channel.Type.DBusTube
and Channel.Interface.Destroyable have been added to generated bindings
Fixes:
* Tp::IncomingStreamTubeChannel always reports an empty socket address to
connect to for accepted Tubes - and various other StreamTube fixes thanks to
now having unit tests for them
telepathy-qt4 0.7.1 (2011-06-09)
================================
The "where is the file?" release.
Enhancements:
* fd.o #37034: The URI property can now be set when requesting file transfers,
and can be read by the Handler (and any Observers) from
Tp::FileTransferChannel (Daniele E. Domenichelli)
* Improved tests readability by moving common code into helper classes,
macros, etc, in preparation for increasing the test coverage
Fixes:
* Fixed documentation for Contact::publishStateChanged()
(Daniele E. Domenichelli)
* Properly crosslink our doxygen docs to Qt documentation on fresh builds
* Properly generate docs for auto generated classes
telepathy-qt4 0.7.0 (2011-06-01)
================================
The "Doctor Love knew this so he made another great invention just for the
lonely you!" release.
This release begins the new 0.7 development series series for feature additions
following the 0.6 stable release series. Both 0.6 and 0.7 will continue to be
backwards compatible API and ABI wise with the earlier 0.5 development series.
Enhancements:
* fd.o #35341: Use the new ContactBlocking D-Bus interface for better
performance in Tp::ContactManager (George Kiagiadakis)
* ReceivedMessage: Add accessors for retrieving delivery report information,
sender nickname and superseded message token
* Crosslink our doxygen docs to Qt documentation
Fixes:
* Do not close channels created using the request and handle API if MC
restarts
* Pass new value correctly as variant in generated binding setProperty* methods
* Properly initialize Connection account balance members
* fd.o #36881 - Wrong documentation for Tp::Account::connectionStatusChanged
(and a bunch of other parts of the API)
* fd.o #31769 - The documentation of TextChannel's features is not very helpful
* Skip docs generation for internal OptionalInterfaceCache
telepathy-qt4 0.5.16 (2011-05-01)
=================================
The "A brown paper bagful of Easter Eggs" release.
Enhancements:
* fd.o #36526: Tp::Channel has now gained targetID() and targetContact()
accessors
* fd.o #35421: Update to spec 0.22.0:
- Added auto generated class for Conn.ContactBlocking
- Added Connection::ErrorDetails accessors for ConnectionError details
server-message, user-requested, expected-hostname and certificate-hostname
* Add support for Conn.SimplePresence.MaximumStatusMessageLength
* Add Features operator|(Features, Feature)
* ContactManager state now only advances to Success when both the roster and
the roster groups have been downloaded, if requested
* New class SimpleObserver that can be used to observe arbitrary channels on a
given Account.
* fd.o #33525 - Helper class(es) for observing calls
- New class SimpleCallObserver class which makes it easy to follow all
StreamedMedia communication on a given Account.
Fixes:
* fd.o #35633: Contact features being erased after further contact upgrades,
e.g. from ContactFactory used together with Connection::FeatureRosterGroups
* Contact::groups() and ContactManager::groupContacts() not populated correctly
when using CMs with new-style ContactGroups D-Bus API
* Timeout in some CMs when introspecting contact list channels
* Crashes with Connection::FeatureSelfContact enabled (Manifested as an assert
for inFlightFeatures or pendingFeatures being hit)
* Crashes if a connection disconnects while FeatureRosterGroups is being
introspected (SIGSEGV in PendingOperation from ContactManager::Roster)
* Added correctly named pretty headers for the
Conn.ClientTypes/ContactGroups/ContactList/Saving interfaces
* Odd build system failures from feature checks which were anyway redundant due
to our recently bumped Qt 4.6+ dependency - checks now removed
telepathy-qt4 0.5.15 (2011-04-12)
=================================
The "How to remove a hole from a set of holes" release.
Enhancements:
* Performance improvements for introspection (becomeReady() latency)
* Some documentation improvements.
Fixes:
* Incorrect scoping for Initial{Audio,Video} properties in Account channel
request methods
* Possible deadlock on connection status changes when FeatureConnected is
requested on a Connection
* Crash opportunities when introspecting a Connection which disappears in the
process (e.g. due to a network error or a CM crash)
telepathy-qt4 0.5.14 (2011-04-05)
=================================
The "Now succeeds at failing!" release.
The Qt dependency has been bumped to >= 4.6.0 for all future releases.
Enhancements:
* AccountManager will now retry introspection 5 times with a 3 seconds interval
(or immediately if error is Timeout) if the introspection failed and
becomeReady() will fail if there is still an error after all tries.
* AccountManager will no more signal newAccount if the initial
introspection failed.
* ConnectionCapabilities and ContactCapabilities are now subclassable
Fixes:
* Regression in 0.5.13 causing PendingReadys to not fail even if the object
being made ready disappears
* Discrepancy between the spec and implementation on initially assumed
non-locally-requested StreamedMediaChannel stream direction
* Reporting capabilities of offline accounts incorrectly because of a .manager
file parsing bug
telepathy-qt4 0.5.13 (2011-03-23)
=================================
The "what is my id?" release.
Enhancements:
* Added example to send messages using ContactMessenger.
Fixes:
* ContactMessenger: Do not crash if an error occurred normalizing the contact
identifier but the ContactManager::contactsForIdentifiers() succeeded.
* Multiple parallel invalidated() signal connections created between DBusProxy
and ReadinessHelper
telepathy-qt4 0.5.12 (2011-03-18)
=================================
The "Can I use the IM framework for, like, sending and receiving messages" release.
Enhancements:
* fd.o #28753: Added SimpleTextObserver class which makes it easy to follow all
text communication on a given Account
* fd.o #35321: Added ContactMessenger class for easily sending and receiving
text messages with a particular contact
Fixes:
* The Request & Handle API spuriously failing with SERVICE_CONFUSED because of
a race condition with introspecting the proxies
telepathy-qt4 0.5.11 (2011-03-09)
=================================
The "more contacts?" release.
Enhancements:
* fd.o#33121 - Bind Connection.ContactList.ContactsChangedWithID.
Fixes:
* ContactManager will now create contact objects even if everything fails but
we have the contact handle/id and the connection has ImmortalHandles.
* Ensure FeatureRoster is ready before setting ContactManager state to
success even in fallback mode.
telepathy-qt4 0.5.10 (2011-03-09)
=================================
The "am I connected?" release.
Enhancements:
* Added Connection::FeatureConnected to help applications that only care about
connected connections. Setting this feature on the ConnectionFactory used
will make sure all connections signalled by the library are connected.
Fixes:
* Ensure FeatureRoster is ready before setting ContactManager state to
success.
telepathy-qt4 0.5.9 (2011-03-07)
=================================
The "planned engineering works for the last year" release.
Enhancements:
* fd.o#28367 - Added High-level API for StreamTube channels
* fd.o#34228 - Added API on Account for requesting Channels and handling them
yourself, implemented properly using the Channel Dispatcher service
* Account::allowedPresenceStatuses() now has fallbacks to include "available"
and "offline" when that makes sense
* Removed some more private symbols from the shared library, resulting in
slightly faster load times
* Deprecated ConnectionCapabilities contact search related methods with
singular names and added plural versions of them, for API consistency.
* Contacts publish/subscription state updates for removed contacts are only
signalled after the ContactManager::allKnownContactsChanged signal is
emitted.
Fixes:
* Redundant Contact::avatarDataChanged() emissions
* Connection::becomeReady() never finishing in state Connecting, which for
example prevents handling ServerAuthentication channels. NOTE: any code
incorrectly relying on the old buggy behavior of becomeReady() only finishing
once the connection goes Connected or Disconnected may need adjustment.
* Linking errors referencing the QtXml library
* Spec-incompliant building of Client names when uniquifying is requested from
ClientRegistrar
* Sensitive data in Account parameters being included in debug logs
telepathy-qt4 0.5.8 (2011-02-22)
=================================
The "where are my contacts?" release.
Enhancements:
* Account won't try to build a Connection object anymore if the connection
object path hasn't changed.
* Connection::FeatureRoster will now fail introspection if ContactList
interface is not supported, neither fallback roster channels.
* ContactManager now has a state() accessor and a corresponding stateChanged()
signal to keep track of the progress made in retrieving the contact list.
* Made Profile/Account/ContactManager debug output a bit cleaner.
* Cleaned up debug classes by removing unused code.
Fixes:
* Properly replace "_" with "-" on Account::protocolName().
telepathy-qt4 0.5.7 (2011-02-15)
=================================
The "fit for galoshes" release.
Enhancements:
* Make the debug subsystem as no-op as possible when debugging is disabled at
runtime with Tp::enableDebug(false) and Tp::enableWarnings(false).
* fd.o#33123 - Bind Protocol.Avatars.
* fd.o#33124 - Bind Protocol.Presence.
* fd.o#33116 - Added support for passing hints to channel requests, also making
channel requests marginally more efficient CPU and memory wise in the
process.
* fd.o#33117 - Added support for extracting hints from ChannelRequests.
* fd.o#33117 - Added support for ChannelRequests reporting the channel created
for them on success, for further observation.
Fixes:
* fd.o#34131 - Writing avatar cache into $HOME with scratchbox.
* Unstable generated future-* headers being installed (although nothing
declared in them was ever exported in the library).
* Possible crashes in Channel internal updateContacts function when just the
self handle changed.
telepathy-qt4 0.5.6 (2011-01-27)
=================================
The "accept/decline" release.
Enhancements:
* Update to spec 0.21.8.
- Added auto generated classes for Account.Addressing,
Channel.ServerAuthentication, Channel.SASLAuthentication,
Channel.Securable and Conn.MainNotification.
Fixes:
* Properly ignore protocol with invalid names.
* Properly escape protocol name with "-" when constructing protocol object
path.
* Properly link against QtXml.
* Properly emit presencePublicationRequested if the contact current publish
state changes to PresenceStateAsk.
* Added missing fancy-headers for generated classes.
telepathy-qt4 0.5.5 (2011-01-25)
=================================
The "I wish I had less contacts" release.
Enhancements:
* CapabilitiesBase: Added method to check if file transfer is supported.
Fixes:
* Contact list contacts are now guaranteed to contain the features set on
ContactFactory.
* Contact list groups are now automatically reintrospected when needed.
* Another attempt to fix a crash when contacts are removed from contact list
while the introspection is still running.
* fd.o#33457 - tp-qt4 uses non-atomic file write in avatar cache.
telepathy-qt4 0.5.4 (2011-01-20)
=================================
The "the shower of golden paper bags" release.
Enhancements:
* Presence publication requests are now reported more sensibly by the
ContactManager::presencePublicationRequested(Contacts) signal, with the
per-contact request message, if any, being in Contact::publishStateMessage()
Fixes:
* ContactManager not emitting presencePublicationRequested if the request
message is empty.
* ContactManager sometimes crashing when contacts are removed using the new
ContactList interface.
telepathy-qt4 0.5.3 (2011-01-17)
=================================
The "contact factorization" release.
Enhancements:
* Added Tp::Contact::requestAvatarData()
* Added Tp::Contact::isContactInfoKnown()
* fd.o#32999 - operator< and qHash are not implemented for
Tp::ProtocolParameter.
* fd.o#33119 - Bind Connection.HasImmortalHandles.
* ContactFactory is no more a stub class. The features set in the
ContactFactory will be enabled in all contacts created by ContactManager and
the classes using it (Connection, Channel, etc).
Fixes:
* Build failures on systems using GNU gold or the
--no-add-needed/--no-copy-dt-needed-entries linker flags
telepathy-qt4 0.5.2 (2011-01-03)
=================================
The "I'm not subscribed now, right? WRONG" release.
Enhancements:
* Added Or/NotFilter classes making it more flexible to use the Filter API.
* Channel invalidation reasons now more accurately describe what happened,
including a new error TP_QT4_ERROR_ORPHANED for the corresponding Connection
getting invalidated from whichever reason.
* Added support for ContactList and ContactGroups interfaces improving
performance of Connection::FeatureRoster/Groups when the CM supports the new
interfaces.
* ContactManager PendingOperations finish at consistent times wrt actual state
changes when used with a CM sporting the new ContactList/ContactGroups
interfaces
* Deprecated Contact/ContactManager signals carrying a
Channel::GroupMemberChangeDetails param for publish/subscription/block state
changes and added new signals that should be used in new code.
* fd.o #31464 - Added Channel::requestLeave() for leaving channels more
gracefully than closing them; StreamedMediaChannel::hangupCall now uses that
Fixes:
* Properly install TelepathyQt4/ConnectionManagerLowLevel.
* A race condition causing proxies to be needlessly dropped from the factory
cache and hence new proxies built for a future request, and eventually
hitting an assert in onProxyInvalidated as a result
* Memory leaks when using Connection::FeatureRoster/RosterGroups where the
connection and roster channels were leaking.
* fd.o#29728 - ContactManager::addGroup and removeGroup are confusing/broken.
* fd.o#29735 - Roster API semantics are error / race condition prone.
telepathy-qt4 0.5.1 (2010-12-08)
=================================
The "lazily evaluated birth" release.
Fixes:
* fd.o #29731: Memory leaks reported by make check-valgrind
* Crash using a dangling (const!) iterator when a channel is removed from a
conference
* Crash when the an object path for an Account in an account set is quickly
reused after it's removed
* Emitting redundant {local,remote}SendingStateChanged signals from
StreamedMediaChannel
* ChannelDispatchOperation::channelLost failing to include Tp:: in the signal
arg type names, making it a tad hard to connect to
telepathy-qt4 0.5.0 (2010-11-16)
=================================
The "new era of breakage" release.
This release IS NOT API/ABI COMPATIBLE WITH EARLIER RELEASES. Further releases
in the 0.5 development series will however be compatible with this release, as
will any releases in a 0.6 stable series.
For enhanced compatibility versions from 0.5 and earlier series can be parallel
installed, with 0.5 bumping the .so major version to .so.1. However, the
development headers and pkgconfig file can't be parallel installed.
Enhancements:
* fd.o #28793 - It is no longer necessary to keep the proxy / other object you
get a PendingOperation from manually referenced until the operation is
finished
* fd.o #28797 - generated client code (AbstractInterface subclasses) now allows
setting a non-default timeout for D-Bus method calls
* fd.o #29486 - Bare variant maps and string lists are no longer exposed in the
API unless absolutely necessary; instead they have wrapper classes with
easy access to well-known keys and values. Among other consequences, this
means AbstractClient implementations NEED TO CHANGE their method
implementation signatures to accept the wrapper classes instead of bare
QVariantMaps.
* Setting automatic/requested presence in Account now uses Tp::Presence
* Cleaned up the API and internal code by removing all deprecated classes,
methods and signals.
* Added Tp::Object intermediate base class for uniform QObject property change
notification. Connection, Channel and Contact will be propertified using it
in the future.
* Enumeration and flag types generated from the specification can now be used
in API without endangering ABI stability due to added padding members,
enhancing type safety in numerous instances where bare uints used to be
returned / taken as a parameter.
* Moved low-level functionality which shouldn't be used when using a full
Telepathy setup with a Mission Control service (Account Manager + Channel
Dispatcher) available from Connection and ConnectionManager to Lowlevel
classes, which can be accessed only if TP_QT4_ENABLE_LOWLEVEL_API is #defined
through a lowlevel() accessor on them
* Bare pointers are no longer returned from the API, instead either SharedPtr
or Qt implicitly shared handle classes are used (applicable to
Connection/ContactCapabilities, ProtocolInfo, etc)
* Tp::Contact is now a RefCounted and uses Tp::Feature like the rest of the
library.
* ClientRegistrar no longer guarantees that a singleton instance is returned
for create(). In particular, this relaxation allows us to implement an API in
the future which constructs a ClientRegistrar behind the scenes to be able to
request and handle channels without manually implementing an
AbstractClientHandler.
* The Filter API is now more future-proof, with the assumption that the filter
chain is ANDed together dropped. It will be possible to combine filters using
And/Or/Not filter combiners in the future, of which And is included now.
* The SharedPtr API has been improved. In particular, it's now safe to use it
as a QMap/QHash key and more difficult to use it incorrectly as a boolean or
an integer. The redundant WeakPtr class has been removed - use QWeakPointer
instead (which works with SharedPtr for all QObject classes).
* Tp::Contact friend list state change signals now have a details argument
(which will contain e.g. the request message for publishState() == Ask when
somebody adds you to their contact list, for example). This means that
code connecting to them NEEDS TO BE CHANGED.
* Account::haveConnection(Changed) and friends is now the less confusing
Account::connection(Changed) pair
* AccountManager filtering methods returning an AccountSet now have more
descriptive names without the Set suffix
* Account/Connection/Channel subclasses now can override the "core" feature
implied by isReady() and becomeReady(). In particular, this means that e.g.
ContactSearchChannel::isReady() with no arguments will only return true if
ContactSearchChannel::FeatureCore is ready in addition to
Channel::FeatureCore.
* StreamedMediaChannel is once again just for Channel.Type.StreamedMedia
channels, with the intermediate Call.DRAFT support and API removed. When Call
is undrafted, a new CallChannel will be added and StreamedMediaChannel
deprecated.
* Similarly, hacky Conference.DRAFT support IS REMOVED. Only the final
Conference interface is supported from now on.
* Everything that used to be called just Audio/Video/MediaCall etc now has
StreamedMedia in the name, to not conflict with future Call API.
Fixes:
* fd.o #27204 - Codegen erroneously uses enums' value-prefix as the name for
the C++ enum
* fd.o #29998 - Connecting to signal Tp::TextChannel::chatStateChanged needs
typedef if not done in Tp namespace
* fd.o #27795 - Problems using Tp::SharedPtr as a key in QMap
* ChannelRequest not becoming ready successfully when there is no Account
specified
* ContactSearchChannel not initializing its private members correctly
* Compile errors with QT_STRICT_ITERATORS
* Some MSVC++ compilation issues (though there still are likely some remaining)
* ContactManager::allKnownContacts not picking up changes from the "stored"
list
telepathy-qt4 0.3.14 (2010-11-05)
=================================
The "O HAI MY NAME IS CONFERENCE" release.
Enhancements:
* fd.o #30098 - Added an asynchronous property request API for generated
low-level proxies
* Added high-level class for SimplePresence and changed Contact to use it,
deprecating the old methods using SimplePresence directly.
* Added signals deprecation support to Contact.
* Deprecated StreamedMediaChannel methods that only make sense when used with
Call.DRAFT channels (we're going to drop support for that particular draft in
0.5.0)
* Deprecated all optional interface convenience methods.
The methods inherited from OptionalInterfaceFactory should be used directly
instead if access to low-level proxies is needed.
* Add unnamed (anonymous, TargetHandleType == None) variants for text chats and
calls to ChannelClassSpec
* Register all non-QObject public classes with the Qt meta-object system, so
they can e.g. be stored in QVariants.
Fixes:
* Unnamed text and StreamedMedia calls not included in the ChannelFactory
(channel class) -> (subclass, features) mapping
* Some RequestableChannelClassSpec and ConnectionCapabilities methods having a
notion of "text chat with a person WHO is a conference", which doesn't exist
telepathy-qt4 0.3.13 (2010-11-01)
=================================
The "sickness won't slow us down" release.
Enhancements:
* Added TP_QT4_ prefixed versions of all generated string constants marked as
QLatin1String for less verbose usage with Q_NO_CAST_FROM_ASCII
* Added signals deprecation mechanism to warn when a deprecated signal is used.
* fd.o #29451 - Make it possible to specify subclasses to use and features to
make ready on them in ChannelFactory
* fd.o #29484 - RequestableChannelClass should have high-level API
* fd.o #29486 - Add a ChannelClassSpec class for easily specifying Client
channel filters (and building Channel requests and ChannelFactory filters for
advanced usage)
* Added more deprecated methods and remove some methods that should not be
deprecated. Now the library together with examples builds itself with
deprecation warnings enabled, to make sure no deprecate method is used
internally.
* Deprecated autogenerated synchronous properties accessors/setters.
Fixes:
* fd.o #30223 - telepathy-qt4's codegen doesn't deal with tp:external-type
properly
* fd.o #30923 - Fix compilation errors in 0.3.12
- The tp-glib version requirement in 0.3.12 was too old
- Compile error in the tp-glib based test library
* fd.o #31087 - ChannelRequest immutable property extraction relying on
undefined method argument evaluation order -> failing on some toolchains
* TextChannel never finishing introspection of FeatureMessageQueue with some
older services
* Properly document ContactSearchChannel signals.
* AccountManager and AccountSet getting confused and hitting asserts with
certain sequences of introspecting and adding/removing accounts, most
prominently when removing and readding an account
* Useless PendingReady code having potential for crashes in corner-cases but
serving no useful purpose (now removed)
* Code generator changes not always triggering rebuilds properly
telepathy-qt4 0.3.12 (2010-10-15)
=================================
The "break is coming" release.
New API:
* Added ContactSearch high-level class.
* Added constructors/accessors for using Channel/ContactFactory in Connection.
* Added high-level class for ContactInfoFieldList.
Enhancements:
* Updated to spec 0.21.1:
- Added auto generated classes for Conn.ClientTypes/ContactGroups/ContactList/
PowerSaving and Chan.ServerTLSConnection.
- Make use of Observer.ObserverInfo.request-properties map, making
ChannelRequest use the immutable properties defined in the map if
available, avoiding unneeded introspection.
- Added support for Conference interface alongside Conference.DRAFT support.
- Added ConnectionCapabilities methods to check conference support.
* Improved Account::capabilities() to take Profile::unsupportedChannelClasses
into account.
* Improved StreamedMediaChannel test coverage to yellow (> 80%).
Fixes:
* Properly install TelepathyQt4/Farsight/global.h.
* fd.o#30386 - Regression: StreamedMediaChannel::streamAdded is not emitted when
one requests a new stream using a StreamedMedia channel type.
* Fixed MediaStream::requestDirection when using a Call channel type.
* Un-deprecate AccountManager methods to retrieve accounts given the account
paths.
* Some small documentation fixes.
telepathy-qt4 0.3.11 (2010-10-04)
=================================
The "farewell hated friend" release.
Enhancements:
* fd.o #24648 - Port Telepathy-Qt4's build system from autotools to cmake,
resulting in faster builds. All targets supported by the previous build system
are still supported, and some new were added, notably individual targets for
unit tests and callgrind support.
* fd.o #29672 - Support for Profiles - a way to describe different IM/VoIP
services by data files (e.g. Google Talk for the XMPP/Jabber protocol)
* fd.o #29699 - ChannelRequest immutable data is now accessible even before it's
fully ready - this is useful for e.g. early initialization of channel context
in applications with the AbstractClientHandler requestNotification API
* Some performance optimizations in ReadyObject, ReadinessHelper and Channel
Fixes:
* Race conditions uncovered by Qt 4.7 in TestAccountBasics and TestConnRoster
telepathy-qt4 0.3.10 (2010-09-16)
=================================
The {bool b; if (b == false || b == true || b == 99) { /*...*/ }} release.
Enhancements:
* fd.o #29609 - ClientRegistrar and all related classes now use Factories too,
which means if you use the factory-enabled create() variants such as
create(AccountManagerPtr), you can share account and connection proxies with
the rest of your application, and/or make them be ready by the time your
addDispatchOperation/handleChannels/observeChannels implementation is called
* fd.o #29090 - Added support to filter accounts by their capabilities (whether
you can do room chats, voice calls, etc, using a given account)
* Added Account::capabilities(), which automatically gets the capabilities from
a connected Connection if there's one, or the protocol object if there isn't
* Generic Filter framework, currently only used for Account filtering, but in
the future also for filtering Contacts
* ChannelRequest is now also using the same Account/Connection etc objects than
the rest of the application
* PendingChannelRequest now holds a reference to its Account, so you don't have
to keep a reference to the Account in your application's scope for the channel
request to succeed
* There are now variants of the ContactManager signals
presencePublicationRequested, groupMembersChanged and allKnownContactsChanged
which carry the details parameter (contains things like the message and the
reason)
Fixes:
* Memory leak when using PendingComposite
* Memory leak in QDBus triggered by ClientHandlerRequestsAdaptor code (there's a
workaround, and the actual bug is reported as QTBUG-13562)
* The PendingOperation returned by Connection::requestConnect() finishing even
if the connection wasn't connected yet
* Hitting an assert in cornercases for calling setIntrospectedCalled twice in
Account Avatar introspection
* Account::changingPresence() not being initialized correctly
telepathy-qt4 0.3.9 (2010-09-10)
================================
The "THE ORIGINAL SWEAT FACTORY^W^WSAUNA MASTER" release.
Enhancements:
* fd.o #29451 - Add Factory infrastructure, enabling:
- sharing accounts/connections between different parts of the library better
(this will soon enable us to eliminate duplicate objects between
AbstractClient implementations and the AM)
- requesting that all accounts/connections/channels/contacts are always ready
with given features
- automatically constructing application-defined subclasses whenever eg. an
Account is constructed
* Add finished and usable AccountFactory and ConnectionFactory APIs, and also
added API/ABI placeholder ChannelFactory and ContactFactory APIs which will be
more useful soon
* fd.o #29606 - Use factories in AccountManager and Account for constructing
Accounts and Connections -> if desired features are enabled, one no longer
needs to make any Account::becomeReady and Connection::becomeReady calls when
using an AccountManager
* fd.o #29409 - Use QDBusServiceWatcher if available, reducing wakeups
* fd.o #20034 - Add avatar cache implementation and featureAvatarData on
Tp::Contact using it.
* Made Channel::groupSelfContact() always have some contact for the user as long
as the channel is ready (if the group has none, the Connection one is used)
* (Side-effect from other work) Add fallbacks to channel requests in case the
service doesn't provide the InitiatorHandle or the Requested property
* Made Channel debug output a bit cleaner
* Added Connection::ErrorDetails to represent additional information about error
conditions causing Connection invalidation
* Made the Connection API guide the applications better to correct error
handling practices (all error handling should be done in invalidated() slots)
* Add SharedPtr::qobjectCast(), an upcasting constructor and pointer to const
support
Fixes:
* A race condition which could result in Channel ignoring a member change (only
applicable to services with Group.MembersChangedDetailed)
* A bug where Channel::groupMembersChanged(only removed members) isn't always
emitted if the local user is not a member of the group - probably means
signaling contacts being removed from roster groups didn't work either
* Yet another TestConnRosterGroup race condition (freq: 6 in 20000 runs)
* fd.o#29930 - Build error with glib 2.25
* ReadyObjects incorrectly handling feature dependencies
* Account/Connection/Channel readifying themselves even if not asked to
* Handle reference management screwing up if there are multiple connections
online on a single CM
* Lots of crash opportunities when a PendingOperation is underway when its
parent-ish object is unreferenced in an application
telepathy-qt4 0.3.8 (2010-08-24)
================================
The "a weekend (and quite a bit of the Monday early hours) well spent" release.
Enhancements:
* fd.o#29395 - Update to spec 0.19.10
* fd.o#29461 - Update to spec 0.19.11
* fd.o#28948 - Added docs/tests/missing Qt properties to AccountSet
* fd.o#29357 - Account::iconName() and icon() now always return sensible
non-empty values
* fd.o#28819 - {Account,ConnectionManager}::protocolInfo() has been improved
- Recent CMs are now introspected with less D-Bus calls
- New API capabilities(), vcardField(), englishName(),
iconName() on ProtocolInfo and ManagerFile
* fd.o#25126 - Some redundant debug output has been removed
* fd.o#27460 - Connection now introspects recent CMs with less D-Bus traffic
* Connection::contactManager and ::capabilities are now less of a death-trap
- now always are non-NULL
- operations fail with descriptive errors if the Connection isn't valid
- they used to go NULL at an indeterminate time when eg. disconnecting
* Account::connection() object path parsing has been optimized
Fixes:
* fd.o#28947 - Account::filterAccounts doc does not properly format the example
code
* fd.o#28651 - Cannot receive files using gabble 0.9
* fd.o#29145 - AccountSet::accountRemoved is emitted for newly-created
non-matching accounts
* fd.o#29699 - ChannelRequest incorrectly checks immutable properties
* Broken iteration code in MediaStream which often led to busy-looping forever
* (Harmless) uninitialized memory use reported by valgrind in Account internals
Test suite improvements:
* fd.o#29702 - Unit tests now execute reliably, and 10-30x faster
* Added the script repeat-tests.sh for repeating tests to detect race conditions
* Added a conservative 10 minute per test watchdog to detect hung-up test logic
- Should be plenty even for heavily loaded VM build bots, as the whole test
suite now executes in 2.4-2.5 seconds on my laptop
* The StreamedMedia legacy and Future.Call tests now actually have different
names to be able to distinguish between them in the test logs
* Test coverage reporting now works again; turns out we need to disable building
the shared library when it is enabled
* amd64 memory use errors (pointer size != int size) calling g_object_new() in
tests have been fixed
telepathy-qt4 0.3.7 (2010-07-12)
================================
The “not as bad as Pepsi Max” release.
Enhancements:
* fd.o#28927 - Generate code for Channel.Interface.{Anonymity,ServicePoint}
(wjt)
* fd.o#28942 - Refresh HACKING and README (wjt)
* Update to spec version 0.19.9, adding Read and Deleted members to
MessageSendingFlagReport, DeliveryReportingSupportFlagReceive, and
DeliveryStatus (wjt)
Fixes:
* fd.o#28945 - AccountManager::accountsByProtocol() returns an empty set
* fd.o#28946 - AccountSet should indicate whether the filter used is valid
telepathy-qt4 0.3.6 (2010-07-01)
================================
The "I've been thinkin' a lot today" release.
New API:
* Added Qt properties to Account.
* Added filter API to AccountManager to filter accounts based on Qt properties.
Includes a new class AccountSet that represents a set of accounts that match a
certain filter and that updates automatically based on accounts Qt properties
changes.
* fd.o#25035 - Add API to AccountManager to get a list of Account objects, all
ready.
* fd.o#28825 - Bind Account.Service
* fd.o#28828 - Add Qt properties to ConnectionManager
* fd.o#28861 - Add auto generated interface and Connection accessor for
Connection.Cellular interface
Enhancements:
* fd.o#28302 - Sync test CM with telepathy-glib
* fd.o#28827 - Add valgrind support to tests
* fd.o#28850 - Update to spec 0.19.8
Fixes:
* fd.o#28489 - manager-file.py missing in tp-qt4 0.3.4 tarball
* fd.o#28826 - KeyFile should support spaces in key names and string list params
that don't terminate with ;
* fd.o#28829 - Contact should not fail if /capabilities attr is empty
* fd.o#28830 - Channel does not parse immutable properties correctly
* fd.o#28831 - Connection FeatureRosterGroups does not work after
FeatureAccountBalance support was added
telepathy-qt4 0.3.5 (2010-06-21)
================================
The "Think I'll get it done yesterday" release.
New API:
* fd.o#28018: Bind Account.ChangingPresence.
* fd.o#28552: Bind Account.ConnectionError/Details.
Enhancements:
* fd.o#28536: update to spec 0.19.7 (ConnectionError, Anonymity, ServicePoint,
ChatStates).
Fixes:
* Update with-session-bus.sh from telepathy-glib, fixing a bashism. (smcv)
* Fixed coverity issues with call example.
* Fixed AbstractClient documentation. (albanc)
* telepathy-qt4-farsight telepathy-glib dependency is now >= 0.8.1. (albanc)
telepathy-qt4 0.3.4 (2010-05-23)
================================
The "Cause time takes time, ya know" release.
New API:
* fd.o#28143: Implement Connection.Balance interface support.
Fixes:
* Fix strict QtDBus demarshalling which was causing crashes when using
qdbus_cast from a SocketAddressIP*. (drf)
telepathy-qt4 0.3.3 (2010-05-09)
================================
The "generic fun" release.
New API:
* fd.o#27671: ContactInfo high-level API.
Enhancements:
- Added Call.Content.Remove support to StreamedMediaChannel.
Fixes:
- Fixed a leak in Connection::gotCapabilities,
- Correctly remove object path from Account::uniqueIdentifier.
telepathy-qt4 0.3.2 (2010-04-23)
================================
The "poisoned with anti-coffee" release.
New API:
* fd.o#27379: Add a new signal, allKnownContactsChanged. (drf)
* fd.o#27677: Add Observer.Recover support.
* Added support for retrieving contacts location.
Enhancements:
* Added example application to list all supported protocols.
* fd.o#27670: Updated to spec 0.19.5.
Fixes:
* Fixed compilation (more specific, moc generation). The code was
triggering QTBUG #2151. (drf)
* Correctly handle UTF-8 in code generator. (wjt)
* Fixed text-chan test race condition. (drf)
telepathy-qt4 0.3.1 (2010-03-30)
================================
The "it's all about coffee" release.
Enhancements:
* Added/Improved documentation for various classes and some minor documentation
style fixes.
Fixes:
* Fixed bug where StreamedMediaChannel::requestStream returned PendingOperation
was never finishing.
telepathy-qt4 0.3.0 (2010-03-18)
================================
The "With My Own Two Hands" release.
Dependencies:
* Full regression tests now require telepathy-glib >= 0.10.0 (telepathy-glib
is still optional)
New API:
* Channel: Added Conference/MergeableConference/Spplitabble interfaces support.
* StreamedMediaChannel: Added Call interface support.
Enhancements:
* Updated to 0.19.1 spec.
* Better tests directories organization (complete separation of glib/python
specific code).
Fixes:
* fd.o#25422: generate code for Call draft API.
* fd.o#26117: Add Call interface support to StreamedMediaChannel.
* fd.o#26881: Remove the usage of QString::fromAscii.
* fd.o#27124: Missing docs for some classes.
* fd.o#27125: Add support to QT_NO_CAST_FROM_ASCII.
* Fixed bug when Channel was never getting ready.
telepathy-qt4 0.2.2 (2010-02-22)
================================
The "no pain, no gain" release.
New API:
* AbstractClientHandler: Added support to set Handler Capabilities property.
Fixes:
* fd.o #25659: ObserveChannels implementation might actually return immediately.
telepathy-qt4 0.2.1 (2009-12-04)
================================
The "all you want, only better" release.
Fixes:
* fd.o #25058: reduce the scope of our workaround for Qt 4.5 bug
, fixing compilation
against Qt versions >= 4.6 beta, where this bug has been fixed (smcv)
* Avoid the installed AccountManager (if any) being service-activated during
distcheck under some circumstances (smcv)
* Compile with symbols hidden by default, explicitly export a few
symbols that were mistakenly not exported, and improve the code generation
tools to be more correct about their exports (smcv)
* Improve the code-generation tools to cope with UTF-8 in the spec (wjt, smcv)
* Enable Automake 1.11 silent building (./configure --enable-silent-rules
to enable this) (wjt)
Code generation release notes:
* qt4-types-gen.py and qt4-client-gen.py previously forced the generated
classes to be exported, in a way that's not actually correct for code outside
telepathy-qt4 (the TELEPATHY_QT4_EXPORT macro).
They now use a macro set by --visibility, defaulting to nothing; if you're
building a shared library with -fvisibility=hidden, or supporting Windows,
you may need to use --visibility=YOUR_LIB_EXPORT when running these scripts.
See TelepathyQt4/global.h or QtDBus/qdbusmacros.h for an example of setting
up such a macro (unfortunately, the only correct way to do this seems to be
for each shared library to define its own).
telepathy-qt4 0.2.0 (2009-11-10)
================================
The "I Shot the Sheriff" release.
API changes:
* Connection: Changed status/statusReason/statusChanged to use enums
Tp::Connection::Status and ConnectionStatusReason.
* Connection: Renamed getContactAttributes method to contactAttributes.
Fixes:
* fd.o#23370: Make better use of telepathy-spec 0.17.27 errors.
* fd.o#24422: Account removal should be represented by
TELEPATHY_QT4_ERROR_OBJECT_REMOVED.
telepathy-qt4 0.1.12 (2009-11-05)
================================
The "an enzyme that breaks down tigers" release.
New API:
* TextChannel: Added ChatState interface support.
API changes:
* TextChannel: send() methods now receive a flags parameter, so we proper
support delivery reports.
Fixes:
* pkgconfig: Added missing QtNetwork dependency.
telepathy-qt4 0.1.11 (2009-10-08)
================================
The "on more to go" release.
New API:
* FileTransferChannel: Added methods to access FileTransfer interface
properties.
* IncomingFileTransferChannel: Added specialized class for handling incoming
file transfers.
* OutgoingFileTransferChannel: Added specialized class for handling outgoing
file transfers.
* CapabilitiesBase: Added base class to represent contact/connection
capabilities.
* ContactCapabilities: Added specialized class that inherits CapabilitiesBase to
represent contact capabilities.
* ConnectionCapabilities: Added specialized class that inherits CapabilitiesBase
to represent connection capabilities.
* Contact: Added ContactCapabilities interface support.
* Connection: Added capabilities (RequestableChannelClasses) support.
* Account: Added ensureAudio/VideoCall methods that make use of
InitialAudio/Video properties when creating StreamedMedia channels.
* Channel: Added streamTubeInterface/tubeInterface methods.
(Patch from Abner Silva ).
* PendingVariant: Added pending operation helper class for D-Bus methods that
return a variant as result.
API changes:
* Renamed PendingVoidMethodCall to PendingVoid.
* Changed PendingVoid/Success/Failure constructor to receive parent as last
parameter.
Enhancements:
* Added examples for handling incoming/outgoing file transfers,
examples/file-transfer/
* Added C++ visibility support.
* Updated to 0.18.0 spec.
Fixes:
* fd.o #24324: Account::create/ensureXXX should receive a const QDateTime & for
userActionTime
* Explicitly use uint for TargetHandleType.
telepathy-qt4 0.1.10 (2009-08-25)
================================
The "not yet stable" release.
New API:
* StreamedMediaChannel: Added Hold and DTMF interface support.
Enhancements:
* Moved OptionalInterfaceFactory::InterfaceSupportedChecking docs from DBusProxy
to OptionalInterfaceFactory.
* Use struct Private instead of class Private for consistence.
* Removed cli/Client from header guards.
Fixes:
* fd.o #20269: Channel's Contact objects should initially have no features.
* fd.o #21335: Implement Group self-handle removal reasons.
* fd.o #23040: Running connection managers appear twice in
ConnectionManager::listNames result.
* fd.o #23282: Channel should update ReadinessHelper with the supported
interfaces.
telepathy-qt4 0.1.9 (2009-07-23)
================================
The "never too late" release.
New API:
* OptionalInterfaceFactory: Added methods interfaces and optionalInterface
and removed duplicated code in all OptionalInterfaceFactory subclasses.
* Added ContactManager allKnownGroups, addGroup, removeGroup, groupContacts,
addContactsToGroup and removeContactsFromGroup methods.
* Added ContactManager groupAdded, groupRemoved and groupMembersChanged signals.
* Added Contact groups, addToGroup and removeFromGroup methods.
* Added Contact addedToGroup and removedFromGroup signals.
API changes:
* Changed ProtocolParameter requiredForRegistration method to
isRequiredForRegistration to make it consistent with other bool returning
getters.
Enhancements:
* Changed all classes to follow coding-style.
* Moved documentation to source file for all classes.
* Standardize class definition in all classes:
* Moved public xxxInterface methods definition to the end of the public
methods declaration.
* Added friend struct Private declaration.
* Added Q_DISABLE_COPY(xxx) to all classes that can not be copied.
* Moved Q_DISABLE_COPY(xxx) declaration to the top of the class definition,
before the public keyword.
* Reorder public, protected, SIGNALS declaration as follows:
public
public Q_SLOTS
Q_SIGNALS
protected
protected Q_SLOTS
private Q_SLOTS
private
* Moved friend class xxx definitions to be placed right below private keyword
* ChannelDispatchOperation: Emit invalidated with
TELEPATHY_QT4_ERROR_OBJECT_REMOVED when ChannelDispatchOperation.Finished is
received.
* Added/Improved some documentation.
Fixes:
* ClientApproverAdaptor: Use the dbus fully qualified name to get the connection
property (Patch from George Kiagiadakis ).
* Fixed bug 20268: Connection's selfContact object should initially have no
features.
* Fixed bug 20080: KeyFile: ";" as a list may be mis-parsed.
* Fixed bug 20082: KeyFile: double (and other types?) not correctly tested.
* Fixed bug 20353: No d-pointer in Channel::GroupMemberChangeDetails.
* Fixed bug 20033: Contact / ContactList Group integration.
telepathy-qt4 0.1.8 (2009-06-16)
================================
The "Every Good Boy Deserves Frontalot" release.
New API:
* Added PendingChannelRequest class to be used when requesting channels using
ChannelDispatcher through Account.
* Added Account methods to request/create channels using ChannelDispatcher
(ensureTextChat, ensureTextChatroom, ensureMediaCall, createChannel and
ensureChannel)
Enhancements:
* Updated to telepathy-spec 0.17.26
Fixes:
* ChannelDispatchOperation: Read Channels property instead of incorrectly
reading ChannelDetailsList (Patch from George Kiagiadakis
).
telepathy-qt4 0.1.7 (2009-06-02)
================================
The "approver" release.
New API:
* Added Client Approver support.
* Added ChannelDispatchOperation high-level class.
Bugfixes:
* Fixed bug 21988: Channel does not work properly if the parent
connection object is not ready
* Fixed bug 21993: TextChannel does not become ready until first message is
received if FeatureMessageQueue is enabled.
telepathy-qt4 0.1.6 (2009-05-28)
================================
The "So hot, I have a fever" release.
New API:
* Added Channel::immutableProperties public method.
Enhancements:
* Added ChannelFactory, internal class to create channels based on
their types.
* PendingChannel: Use ChannelFactory to create channels.
Bugfixes:
* Proper define AbstractClientPtr.
* ClientRegistrar: Fixed Observer adaptor introspection data.
* ClientRegistrar: Use ChannelFactory to create Channels.
telepathy-qt4 0.1.5 (2009-05-19)
================================
The "do not look at the conductor" release.
New API:
* Added Client support (Handler, Observer).
* Added ClientRegistrar, class responsible for registering clients and proper
exporting their D-Bus interfaces.
* Added AbstractClientObserver, AbstractClientApprover (skeleton) and
AbstractClientHandler. Clients should inherit one or some combination of
these, by using multiple inheritance, and register themselves using
ClientRegistrar::registerClient() in order to become a Client.
* Added ChannelRequest high-level class.
telepathy-qt4 0.1.4 (2009-05-08)
================================
The "global military-industrial complex is subsidising your iPod" release.
Dependencies:
* Creating accounts, and possibly updating their parameters, now requires an
AccountManager implementing telepathy-spec 0.17.24, such as
telepathy-mission-control >= 5.0.beta70 (in particular, beta 69 won't work,
and the KWallet-based account manager will also need updating)
API changes:
* Renamed SharedData header file to RefCounted to follow class name.
New API:
* Update to telepathy-spec 0.17.24, breaking some D-Bus APIs:
* fd.o #21619: Account::updateParameters() returns a PendingStringList of
the parameters that won't be changed until reconnection takes place
* Account::reconnect() added (newer MC versions don't violate telepathy-spec
by reconnecting automatically when parameters are changed)
* AccountManager::supportedAccountProperties() added
* AccountManager::createAccount() takes an optional dict of properties
(the valid keys are in supportedAccountProperties())
* Enhance PendingStringList to have a constructor from a QDBusPendingCall
Bugfixes:
* Don't try to run Python tests unless we have the gobject module (the tests
use it)
telepathy-qt4 0.1.3 (2009-04-22)
================================
The "what are you scared of?" release.
Dependencies:
* Full regression tests now require telepathy-glib >= 0.7.28 (telepathy-glib
is still optional)
API changes:
* Namespace simplification: Telepathy::Client::Channel (etc.) are now
Tp::Channel, similar to telepathy-glib's TpChannel. Auto-generated client
classes like Telepathy::Client::ChannelInterface are now
Tp::Client::ChannelInterface.
* AccountManager, Account, ConnectionManager, Connection, Channel and Channel
subclasses now inherit from Tp::RefCounted and are used together with
Tp::SharedPtr/Tp::WeakPtr, shared and weak pointer classes using ideas from
Qt, glibmm, Boost and WebKit. The constructor is now protected (in order to
support custom classes) and a public create method that returns a SharedPtr
was added. This is an attempt to avoid memory leaks as much as possible, see
http://lists.freedesktop.org/archives/telepathy/2009-March/003218.html for
more details.
* Instead of forward-declaring Telepathy::Client::Channel and using
a variable of type Telepathy::Client::Channel *, you should now include
and use either Tp::ChannelPtr, which is a
reference-counted shared pointer, or Tp::WeakPtr, which is the
weak counterpart.
* Header simplification: the public headers now look like
, i.e. without the Client subdirectory.
* PendingHandles now finish successfully on non fatal errors (InvalidArgument,
InvalidHandle, NotAvailable). PendingHandles::invalidNames/invalidHandles
should be used to check if a non-fatal error occurred and some handle could
not be acquired.
Enhancements:
* Updated to telepathy-spec 0.17.23
* TelepathyQt4Farsight is a new mini-library with glue code to connect
telepathy-farsight to Telepathy-Qt4. Handlers for streamed media channels
with media signalling can #include and pass
their Tp::StreamedMediaChannel to Tp::createFarsightChannel, then hook up
the resulting TfChannel to a GStreamer pipeline of their choice.
* StreamedMediaChannel has a new handlerStreamingRequired method so you can
check whether the handler needs to carry out the streaming
* fd.o #21336: Channels now indicate whether a message is expected when
doing various Group operations
* fd.o #21337: Account supports the new HasBeenOnline property
Fixes:
* fd.o #20583: Contact objects don't work without the Contacts interface.
* fd.o #20584: Contact object creation doesn't survive bad IDs or handles.
telepathy-qt4 0.1.2 (2009-03-23)
================================
The "robotic automatic hoover" release.
Dependencies:
* Full regression tests now require telepathy-glib >= 0.7.27 (telepathy-glib
is still optional)
* telepathy-farsight >= 0.0.4 is a new optional dependency
API changes:
* AccountManager, Account, ConnectionManager, Connection, Channel
now inherit QSharedData and are used together with
QExplicitlySharedDataPointer.
This is needed so we can create shared pointers based on the object itself,
instead of doing hacks to find the shared pointer related to a given object.
See http://lists.freedesktop.org/archives/telepathy/2009-March/003168.html for
more details.
* Channel Features are now Feature objects, not integers
* The Feature class is now in its own header,
Enhancements:
* The skeletal StreamedMediaChannel class from 0.1.0 has been expanded to
cover all the functionality of the Telepathy StreamedMedia interface
* PendingConnection, PendingAccount etc. have busName and objectPath
methods where necessary, so that objects of custom classes can be
constructed
* Features can now be considered critical, meaning that failure to set them up
leads to failure of becomeReady() - this should only be used for features
that should never fail unless the service is buggy, like Connection and
Channel core functionality
* examples/call/ is an example of how to use StreamedMediaChannel, which can
make and receive XMPP Jingle calls using telepathy-gabble
(this feature requires telepathy-farsight and GStreamer)
Fixes:
* When introspection of a Feature fails, the D-Bus error is propagated as the
failure reason of becomeReady()
* Fix a memory leak in TextChannel
telepathy-qt4 0.1.1 (2009-03-05)
================================
The "PresencePublicationAuthorizationRequestRejection" release.
API changes:
* PendingReadyAccount, PendingReadyAccountManager, PendingReadyConnection,
PendingReadyConnectionManager have all been replaced by the PendingReady
class
* Account, AccountManager, Connection and ConnectionManager features are now
QSet, not bitfields
* Plural contacts are generally represented by a QSet >
instead of a QList > (with a new typedef,
Telepathy::Client::Contacts, which must be used in signal/slot connections)
Enhancements:
* Added Connection::FeatureRoster, which, when enabled, adds contact list
(a.k.a. roster/buddy list) functionality to the ContactManager and
Contact objects
* Improved maintainability of Account, AccountManager, Connection and
ConnectionManager becoming ready
* A QSharedPointer is now hashable with qHash, meaning contacts can
be QSet or QHash members
* Added a trivial contact list user interface, examples/roster/roster
Fixes:
* The client library no longer attempts to enforce group add/remove flags:
whatever change the user requests is passed on to the connection manager
(which might reject it)
* PendingReady objects returned by Connection::becomeReady() have the
Connection as parent, rather than an internal object that isn't useful
to library users
telepathy-qt4 0.1.0 (2009-02-26)
================================
The "pending operation" release.
This first release of telepathy-qt4 features high-level API for the following:
* Manipulating accounts on a Telepathy AccountManager implementation as
described by telepathy-spec 0.17.x, such as Mission Control 5 (beta versions
currently available)
* Manipulating Telepathy connection managers via the ConnectionManager and
Connection core API
* Setting your own presence on a connection manager supporting the
SimplePresence interface
* Requesting channels from a connection manager supporting the Requests
interface
* Reading contacts' aliases etc. on a connection manager supporting the
Contacts interface
* Sending and receiving messages on Text channels, with or without the
Messages interface
In addition, lower-level auto-generated accessors are provided for all the
functionality of telepathy-spec version 0.17.19.
Notable functionality that is currently missing, but will be added soon,
includes:
* Manipulating a server-stored contact list
* Controlling VoIP calls in StreamedMedia channels
/* ex: set textwidth=80: */
telepathy-qt-0.9.6~git1/AUTHORS 0000664 0001750 0001750 00000000254 12470405660 014021 0 ustar jr jr Andre Moreira Magalhaes (andrunko)
Olli Salli (oggis)
Simon McVittie (smcv)
telepathy-qt-0.9.6~git1/config-version.h.in 0000664 0001750 0001750 00000000054 12470405660 016455 0 ustar jr jr #define PACKAGE_VERSION "@PACKAGE_VERSION@"
telepathy-qt-0.9.6~git1/tools/ 0000775 0001750 0001750 00000000000 12470405660 014110 5 ustar jr jr telepathy-qt-0.9.6~git1/tools/git-which-branch.sh 0000664 0001750 0001750 00000001253 12470405660 017563 0 ustar jr jr #!/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.
#
# 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
telepathy-qt-0.9.6~git1/tools/qt-client-gen.py 0000664 0001750 0001750 00000042054 12470405660 017136 0 ustar jr jr #!/usr/bin/python
#
# Copyright (C) 2008 Collabora Limited
# Copyright (C) 2008 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 St, Fifth Floor, Boston, MA 02110-1301 USA
from sys import argv
import xml.dom.minidom
import codecs
from getopt import gnu_getopt
from libtpcodegen import NS_TP, get_descendant_text, get_by_path
from libqtcodegen import binding_from_usage, extract_arg_or_member_info, format_docstring, gather_externals, gather_custom_lists, get_headerfile_cmd, get_qt_name, qt_identifier_escape, RefRegistry
class Generator(object):
def __init__(self, opts):
try:
self.group = opts.get('--group', '')
self.headerfile = opts['--headerfile']
self.implfile = opts['--implfile']
self.namespace = opts['--namespace']
self.typesnamespace = opts['--typesnamespace']
self.realinclude = opts['--realinclude']
self.prettyinclude = opts.get('--prettyinclude')
self.extraincludes = opts.get('--extraincludes', None)
self.mainiface = opts.get('--mainiface', None)
self.must_define = opts.get('--must-define', None)
self.dbus_proxy = opts.get('--dbus-proxy',
'Tp::DBusProxy')
self.visibility = opts.get('--visibility', '')
ifacedom = xml.dom.minidom.parse(opts['--ifacexml'])
specdom = xml.dom.minidom.parse(opts['--specxml'])
except KeyError, k:
assert False, 'Missing required parameter %s' % k.args[0]
self.hs = []
self.bs = []
self.ifacenodes = ifacedom.getElementsByTagName('node')
self.spec, = get_by_path(specdom, "spec")
self.custom_lists = gather_custom_lists(self.spec, self.typesnamespace)
self.externals = gather_externals(self.spec)
self.refs = RefRegistry(self.spec)
def __call__(self):
# Output info header and includes
self.h("""\
/*
* This file contains D-Bus client proxy classes generated by qt-client-gen.py.
*
* This file can be distributed under the same terms as the specification from
* which it was generated.
*/
""")
if self.must_define:
self.h('\n')
self.h('#ifndef %s\n' % self.must_define)
self.h('#error %s\n' % self.must_define)
self.h('#endif\n')
self.h('\n')
if self.extraincludes:
for include in self.extraincludes.split(','):
self.h('#include %s\n' % include)
self.h("""
#include
#include
#include
#include
#include
#include
#include
#include
namespace Tp
{
class PendingVariant;
class PendingOperation;
}
""")
if self.must_define:
self.b("""#define %s\n""" % (self.must_define))
self.b("""#include "%s"
""" % self.realinclude)
# Begin namespace
for ns in self.namespace.split('::'):
self.hb("""\
namespace %s
{
""" % ns)
# Output interface proxies
def ifacenodecmp(x, y):
xname, yname = [self.namespace + '::' + node.getAttribute('name').replace('/', '').replace('_', '') + 'Interface' for node in x, y]
if xname == self.mainiface:
return -1
elif yname == self.mainiface:
return 1
else:
return cmp(xname, yname)
self.ifacenodes.sort(cmp=ifacenodecmp)
for ifacenode in self.ifacenodes:
self.do_ifacenode(ifacenode)
# End namespace
self.hb(''.join(['}\n' for ns in self.namespace.split('::')]))
# Add metatype declaration - otherwise QTBUG #2151 might be triggered
for ifacenode in self.ifacenodes:
classname = ifacenode.getAttribute('name').replace('/', '').replace('_', '') + 'Interface'
self.h("Q_DECLARE_METATYPE(" + self.namespace + "::" + classname + "*)\n")
# Write output to files
(codecs.getwriter('utf-8')(open(self.headerfile, 'w'))).write(''.join(self.hs))
(codecs.getwriter('utf-8')(open(self.implfile, 'w'))).write(''.join(self.bs))
def do_ifacenode(self, ifacenode):
# Extract info
name = ifacenode.getAttribute('name').replace('/', '').replace('_', '') + 'Interface'
iface, = get_by_path(ifacenode, 'interface')
dbusname = iface.getAttribute('name')
# Begin class, constructors
self.h("""
/**
* \\class %(name)s
%(headercmd)s\
%(groupcmd)s\
*
* Proxy class providing a 1:1 mapping of the D-Bus interface "%(dbusname)s".
*/
class %(visibility)s %(name)s : public Tp::AbstractInterface
{
Q_OBJECT
public:
/**
* Returns the name of the interface "%(dbusname)s", which this class
* represents.
*
* \\return The D-Bus interface name.
*/
static inline QLatin1String staticInterfaceName()
{
return QLatin1String("%(dbusname)s");
}
/**
* Creates a %(name)s associated with the given object on the session bus.
*
* \\param busName Name of the service the object is on.
* \\param objectPath Path to the object on the service.
* \\param parent Passed to the parent class constructor.
*/
%(name)s(
const QString& busName,
const QString& objectPath,
QObject* parent = 0
);
/**
* Creates a %(name)s associated with the given object on the given bus.
*
* \\param connection The bus via which the object can be reached.
* \\param busName Name of the service the object is on.
* \\param objectPath Path to the object on the service.
* \\param parent Passed to the parent class constructor.
*/
%(name)s(
const QDBusConnection& connection,
const QString& busName,
const QString& objectPath,
QObject* parent = 0
);
""" % {'name' : name,
'headercmd' : get_headerfile_cmd(self.realinclude, self.prettyinclude),
'groupcmd' : self.group and (' * \\ingroup %s\n' % self.group),
'dbusname' : dbusname,
'visibility': self.visibility,
})
self.b("""
%(name)s::%(name)s(const QString& busName, const QString& objectPath, QObject *parent)
: Tp::AbstractInterface(busName, objectPath, staticInterfaceName(), QDBusConnection::sessionBus(), parent)
{
}
%(name)s::%(name)s(const QDBusConnection& connection, const QString& busName, const QString& objectPath, QObject *parent)
: Tp::AbstractInterface(busName, objectPath, staticInterfaceName(), connection, parent)
{
}
""" % {'name' : name})
# Construct from DBusProxy subclass
self.h("""
/**
* Creates a %(name)s associated with the same object as the given proxy.
*
* \\param proxy The proxy to use. It will also be the QObject::parent()
* for this object.
*/
%(name)s(%(dbus_proxy)s *proxy);
""" % {'name' : name,
'dbus_proxy' : self.dbus_proxy})
self.b("""
%(name)s::%(name)s(%(dbus_proxy)s *proxy)
: Tp::AbstractInterface(proxy, staticInterfaceName())
{
}
""" % {'name' : name,
'dbus_proxy' : self.dbus_proxy})
# Main interface
mainiface = self.mainiface or 'Tp::AbstractInterface'
if mainiface != self.namespace + '::' + name:
self.h("""
/**
* Creates a %(name)s associated with the same object as the given proxy.
* Additionally, the created proxy will have the same parent as the given
* proxy.
*
* \\param mainInterface The proxy to use.
*/
explicit %(name)s(const %(mainiface)s& mainInterface);
/**
* Creates a %(name)s associated with the same object as the given proxy.
* However, a different parent object can be specified.
*
* \\param mainInterface The proxy to use.
* \\param parent Passed to the parent class constructor.
*/
%(name)s(const %(mainiface)s& mainInterface, QObject* parent);
""" % {'name' : name,
'mainiface' : mainiface})
self.b("""
%(name)s::%(name)s(const %(mainiface)s& mainInterface)
: Tp::AbstractInterface(mainInterface.service(), mainInterface.path(), staticInterfaceName(), mainInterface.connection(), mainInterface.parent())
{
}
%(name)s::%(name)s(const %(mainiface)s& mainInterface, QObject *parent)
: Tp::AbstractInterface(mainInterface.service(), mainInterface.path(), staticInterfaceName(), mainInterface.connection(), parent)
{
}
""" % {'name' : name,
'mainiface' : mainiface})
# Properties
has_props = False
for prop in get_by_path(iface, 'property'):
# Skip tp:properties
if not prop.namespaceURI:
self.do_prop(prop)
has_props = True
self.h("""
/**
* Request all of the DBus properties on the interface.
*
* \\return A pending variant map which will emit finished when the properties have
* been retrieved.
*/
Tp::PendingVariantMap *requestAllProperties() const
{
return internalRequestAllProperties();
}
""")
# Methods
methods = get_by_path(iface, 'method')
if methods:
self.h("""
public Q_SLOTS:\
""")
for method in methods:
self.do_method(method)
# Signals
signals = get_by_path(iface, 'signal')
if signals:
self.h("""
Q_SIGNALS:\
""")
for signal in signals:
self.do_signal(signal)
# invalidated handler (already a slot in the superclass)
# we can't just use disconnect(this, NULL, NULL, NULL) because
# (a) that would disconnect QObject::destroyed() and other non-D-Bus
# signals, and (b) QtDBus doesn't support that usage anyway (it needs
# specific signals in order to remove its signal match rules)
self.h("""
protected:
virtual void invalidate(Tp::DBusProxy *, const QString &, const QString &);
""")
self.b("""
void %(name)s::invalidate(Tp::DBusProxy *proxy,
const QString &error, const QString &message)
{
""" % {'name' : name})
for signal in signals:
self.do_signal_disconnect(signal)
self.b("""
Tp::AbstractInterface::invalidate(proxy, error, message);
}
""")
# Close class
self.h("""\
};
""")
def do_prop(self, prop):
name = prop.getAttribute('name')
access = prop.getAttribute('access')
gettername = name
settername = None
docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/')
sig = prop.getAttribute('type')
tptype = prop.getAttributeNS(NS_TP, 'type')
binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace)
if 'write' in access:
settername = 'set' + name
if 'read' in access:
self.h("""
/**
* Asynchronous getter for the remote object property \\c %(name)s of type \\c %(val)s.
*
%(docstring)s\
*
* \\return A pending variant which will emit finished when the property has been
* retrieved.
*/
inline Tp::PendingVariant *%(gettername)s() const
{
return internalRequestProperty(QLatin1String("%(name)s"));
}
""" % {'name' : name,
'docstring' : docstring,
'val' : binding.val,
'gettername' : 'requestProperty' + name})
if 'write' in access:
self.h("""
/**
* Asynchronous setter for the remote object property \\c %(name)s of type \\c %(type)s.
*
%(docstring)s\
*
* \\return A pending operation which will emit finished when the property has been
* set.
*/
inline Tp::PendingOperation *%(settername)s(%(type)s newValue)
{
return internalSetProperty(QLatin1String("%(name)s"), QVariant::fromValue(newValue));
}
""" % {'name' : name,
'docstring' : docstring,
'type' : binding.val,
'name' : name,
'settername' : 'setProperty' + name})
def do_method(self, method):
name = method.getAttribute('name')
args = get_by_path(method, 'arg')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists,
self.externals, self.typesnamespace, self.refs, ' * ')
inargs = []
outargs = []
for i in xrange(len(args)):
if args[i].getAttribute('direction') == 'out':
outargs.append(i)
else:
inargs.append(i)
assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name)
rettypes = ', '.join([argbindings[i].val for i in outargs])
params = ', '.join([argbindings[i].inarg + ' ' + argnames[i] for i in inargs])
if params:
params += ', int timeout = -1'
else:
params = 'int timeout = -1'
self.h("""
/**
* Begins a call to the D-Bus method \\c %s on the remote object.
%s\
*
* Note that \\a timeout is ignored as of now. It will be used once
* http://bugreports.qt.nokia.com/browse/QTBUG-11775 is fixed.
*
""" % (name, format_docstring(method, self.refs, ' * ')))
for i in inargs:
if argdocstrings[i]:
self.h("""\
*
* \\param %s
%s\
""" % (argnames[i], argdocstrings[i]))
self.h("""\
* \\param timeout The timeout in milliseconds.
""")
for i in outargs:
if argdocstrings[i]:
self.h("""\
*
* \\return
%s\
""" % argdocstrings[i])
self.h("""\
*/
inline QDBusPendingReply<%(rettypes)s> %(name)s(%(params)s)
{
if (!invalidationReason().isEmpty()) {
return QDBusPendingReply<%(rettypes)s>(QDBusMessage::createError(
invalidationReason(),
invalidationMessage()
));
}
""" % {'rettypes' : rettypes,
'name' : name,
'params' : params})
if inargs:
self.h("""
QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(),
this->staticInterfaceName(), QLatin1String("%s"));
callMessage << %s;
return this->connection().asyncCall(callMessage, timeout);
}
""" % (name, ' << '.join(['QVariant::fromValue(%s)' % argnames[i] for i in inargs])))
else:
self.h("""
QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(),
this->staticInterfaceName(), QLatin1String("%s"));
return this->connection().asyncCall(callMessage, timeout);
}
""" % name)
def do_signal(self, signal):
name = signal.getAttribute('name')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(get_by_path(signal,
'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
self.h("""
/**
* Represents the signal \\c %s on the remote object.
%s\
""" % (name, format_docstring(signal, self.refs, ' * ')))
for i in xrange(len(argnames)):
assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name)
if argdocstrings[i]:
self.h("""\
*
* \\param %s
%s\
""" % (argnames[i], argdocstrings[i]))
self.h("""\
*/
void %s(%s);
""" % (name, ', '.join(['%s %s' % (binding.inarg, name) for binding, name in zip(argbindings, argnames)])))
def do_signal_disconnect(self, signal):
name = signal.getAttribute('name')
_, _, argbindings = extract_arg_or_member_info(get_by_path(signal, 'arg'),
self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
self.b("""\
disconnect(this, SIGNAL(%s(%s)), NULL, NULL);
""" % (name, ', '.join([binding.inarg for binding in argbindings])))
def h(self, str):
self.hs.append(str)
def b(self, str):
self.bs.append(str)
def hb(self, str):
self.h(str)
self.b(str)
if __name__ == '__main__':
options, argv = gnu_getopt(argv[1:], '',
['group=',
'namespace=',
'typesnamespace=',
'headerfile=',
'implfile=',
'ifacexml=',
'specxml=',
'realinclude=',
'prettyinclude=',
'extraincludes=',
'mainiface=',
'must-define=',
'dbus-proxy=',
'visibility='])
Generator(dict(options))()
telepathy-qt-0.9.6~git1/tools/telepathy-glib.supp 0000664 0001750 0001750 00000014513 12470405660 017737 0 ustar jr jr # Valgrind error suppression file
# ============================= libc ==================================
{
ld.so initialization + selinux
Memcheck:Leak
...
fun:_dl_init
obj:/lib/ld-*.so
}
{
dlopen initialization, triggered by handle-leak-debug code
Memcheck:Leak
...
fun:__libc_dlopen_mode
fun:init
fun:backtrace
fun:handle_leak_debug_bt
fun:dynamic_ensure_handle
fun:tp_handle_ensure
}
# default.supp has these for 2.10, but they're too specific
{
Debian libc6 (2.10.x, 2.11.x) stripped dynamic linker
Memcheck:Cond
fun:index
fun:expand_dynamic_string_token
fun:_dl_map_object
fun:map_doit
fun:_dl_catch_error
fun:do_preload
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:/lib/ld-*.so
}
{
Debian libc6 (2.9.x - 2.11.x) stripped dynamic linker
Memcheck:Cond
fun:_dl_relocate_object
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:/lib/ld-*.so
}
{
ld.so initialization on glibc 2.9
Memcheck:Cond
fun:strlen
fun:_dl_init_paths
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:/lib/ld-2.9.so
}
# ======================= libselinux on Debian amd64 =====================
{
I have no idea what SELinux is doing but it's not my problem
Memcheck:Cond
...
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
}
{
I have no idea what SELinux is doing but it's not my problem
Memcheck:Value8
...
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
}
{
I have no idea what SELinux is doing but it's not my problem
Memcheck:Leak
...
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
obj:/lib/libselinux.so.1
}
# ============================= GLib ==================================
{
g_set_prgname copies its argument
Memcheck:Leak
...
fun:g_set_prgname
}
{
one g_get_charset per child^Wprocess
Memcheck:Leak
...
fun:g_get_charset
}
{
one g_get_home_dir per process
Memcheck:Leak
...
fun:g_get_home_dir
}
{
GQuarks can't be freed
Memcheck:Leak
...
fun:g_quark_from_static_string
}
{
GQuarks can't be freed
Memcheck:Leak
...
fun:g_quark_from_string
}
{
interned strings can't be freed
Memcheck:Leak
...
fun:g_intern_string
}
{
interned strings can't be freed
Memcheck:Leak
...
fun:g_intern_static_string
}
{
shared global default g_main_context
Memcheck:Leak
...
fun:g_main_context_new
fun:g_main_context_default
}
{
GTest initialization
Memcheck:Leak
...
fun:g_test_init
fun:main
}
{
GTest admin
Memcheck:Leak
...
fun:g_test_add_vtable
}
{
GTest pseudorandomness
Memcheck:Leak
...
fun:g_rand_new_with_seed_array
fun:test_run_seed
...
fun:g_test_run
}
{
GSLice initialization
Memcheck:Leak
...
fun:g_malloc0
fun:g_slice_init_nomessage
fun:g_slice_alloc
}
# ============================= GObject ===============================
{
g_type_init
Memcheck:Leak
...
fun:g_type_init
}
{
g_type_init_with_debug_flags
Memcheck:Leak
...
fun:g_type_init_with_debug_flags
}
{
g_type_register_static
Memcheck:Leak
...
fun:g_type_register_static
}
{
g_type_add_interface_static
Memcheck:Leak
...
fun:g_type_add_interface_static
}
{
initialization of interfaces
Memcheck:Leak
...
fun:type_iface_vtable_base_init_Wm
fun:g_type_class_ref
}
# ============================= GIO ===================================
{
GIO init
Memcheck:Leak
...
fun:g_inet_address_class_intern_init
}
{
g_simple_async_result class
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_simple_async_result_new
}
# ============================= dbus-glib =============================
{
registering marshallers is permanent
Memcheck:Leak
...
fun:dbus_g_object_register_marshaller_array
fun:dbus_g_object_register_marshaller
}
{
dbus-glib specialized GTypes are permanent
Memcheck:Leak
...
fun:dbus_g_type_specialized_init
}
{
libdbus shared connection
Memcheck:Leak
...
fun:dbus_g_bus_get
}
{
dbus-gobject registrations aren't freed unless we fall off the bus
Memcheck:Leak
...
fun:g_slist_append
fun:dbus_g_connection_register_g_object
}
{
DBusGProxy slots aren't freed unless we fall off the bus
Memcheck:Leak
...
fun:dbus_connection_allocate_data_slot
...
fun:dbus_g_proxy_constructor
}
{
error registrations are for life, not just for Christmas
Memcheck:Leak
...
fun:dbus_g_error_domain_register
}
{
DBusGProxy class init
Memcheck:Leak
...
fun:dbus_g_proxy_class_init
}
# ============================= telepathy-glib ========================
{
tp_dbus_daemon_constructor @daemons once per DBusConnection
Memcheck:Leak
...
fun:g_slice_alloc
fun:tp_dbus_daemon_constructor
}
{
tp_proxy_subclass_add_error_mapping refs the enum
Memcheck:Leak
...
fun:g_type_class_ref
fun:tp_proxy_subclass_add_error_mapping
}
{
tp_proxy_or_subclass_hook_on_interface_add never frees its list
Memcheck:Leak
...
fun:tp_proxy_or_subclass_hook_on_interface_add
}
{
tp_dbus_daemon_constructor filter not freed til we fall off the bus
Memcheck:Leak
...
fun:dbus_connection_add_filter
fun:tp_dbus_daemon_constructor
}
{
tp_g_socket_address_from_variant reffing GNIO types
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:tp_g_socket_address_from_variant
}
{
creating classes for DBusGProxy
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_object_new
...
fun:tp_proxy_borrow_interface_by_id
}
{
creating classes for tp_dbus_daemon_new
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_object_new
...
fun:tp_dbus_daemon_new
}
{
creating classes for TpCHannel
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_object_new
...
fun:tp_channel_new
}
{
creating a boxed type to use in TpCapabilities
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_param_spec_boxed
fun:tp_capabilities_class_intern_init
}
# ============================= questionable ==========================
{
creating classes for instances (this is a pretty big hammer)
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:g_type_create_instance
...
fun:g_param_spec_string
}
telepathy-qt-0.9.6~git1/tools/check-misc.sh 0000664 0001750 0001750 00000000360 12470405660 016451 0 ustar jr jr #!/bin/sh
fail=0
( . "${tools_dir}"/check-whitespace.sh ) || fail=$?
if egrep '(Free\s*Software\s*Foundation.*02139|02111-1307)' "$@"
then
echo "^^^ The above files contain the FSF's old address in GPL headers"
fail=1
fi
exit $fail
telepathy-qt-0.9.6~git1/tools/glib-gtypes-generator.py 0000664 0001750 0001750 00000030133 12470405660 020674 0 ustar jr jr #!/usr/bin/python
# Generate GLib GInterfaces from the Telepathy specification.
# The master copy of this program is in the telepathy-glib repository -
# please make any changes there.
#
# Copyright (C) 2006, 2007 Collabora Limited
#
# 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
import sys
import xml.dom.minidom
from libglibcodegen import escape_as_identifier, \
get_docstring, \
NS_TP, \
Signature, \
type_to_gtype, \
xml_escape
def types_to_gtypes(types):
return [type_to_gtype(t)[1] for t in types]
class GTypesGenerator(object):
def __init__(self, dom, output, mixed_case_prefix):
self.dom = dom
self.Prefix = mixed_case_prefix
self.PREFIX_ = self.Prefix.upper() + '_'
self.prefix_ = self.Prefix.lower() + '_'
self.header = open(output + '.h', 'w')
self.body = open(output + '-body.h', 'w')
for f in (self.header, self.body):
f.write('/* Auto-generated, do not edit.\n *\n'
' * This file may be distributed under the same terms\n'
' * as the specification from which it was generated.\n'
' */\n\n')
# keys are e.g. 'sv', values are the key escaped
self.need_mappings = {}
# keys are the contents of the struct (e.g. 'sssu'), values are the
# key escaped
self.need_structs = {}
# keys are the contents of the struct (e.g. 'sssu'), values are the
# key escaped
self.need_struct_arrays = {}
# keys are the contents of the array (unlike need_struct_arrays!),
# values are the key escaped
self.need_other_arrays = {}
def h(self, code):
self.header.write(code.encode("utf-8"))
def c(self, code):
self.body.write(code.encode("utf-8"))
def do_mapping_header(self, mapping):
members = mapping.getElementsByTagNameNS(NS_TP, 'member')
assert len(members) == 2
impl_sig = ''.join([elt.getAttribute('type')
for elt in members])
esc_impl_sig = escape_as_identifier(impl_sig)
name = (self.PREFIX_ + 'HASH_TYPE_' +
mapping.getAttribute('name').upper())
impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig
docstring = get_docstring(mapping) or '(Undocumented)'
self.h('/**\n * %s:\n *\n' % name)
self.h(' * %s\n' % xml_escape(docstring))
self.h(' *\n')
self.h(' * This macro expands to a call to a function\n')
self.h(' * that returns the #GType of a #GHashTable\n')
self.h(' * appropriate for representing a D-Bus\n')
self.h(' * dictionary of signature\n')
self.h(' * a{%s}.\n' % impl_sig)
self.h(' *\n')
key, value = members
self.h(' * Keys (D-Bus type %s,\n'
% key.getAttribute('type'))
tp_type = key.getAttributeNS(NS_TP, 'type')
if tp_type:
self.h(' * type %s,\n' % tp_type)
self.h(' * named %s):\n'
% key.getAttribute('name'))
docstring = get_docstring(key) or '(Undocumented)'
self.h(' * %s\n' % xml_escape(docstring))
self.h(' *\n')
self.h(' * Values (D-Bus type %s,\n'
% value.getAttribute('type'))
tp_type = value.getAttributeNS(NS_TP, 'type')
if tp_type:
self.h(' * type %s,\n' % tp_type)
self.h(' * named %s):\n'
% value.getAttribute('name'))
docstring = get_docstring(value) or '(Undocumented)'
self.h(' * %s\n' % xml_escape(docstring))
self.h(' *\n')
self.h(' */\n')
self.h('#define %s (%s ())\n\n' % (name, impl))
self.need_mappings[impl_sig] = esc_impl_sig
array_name = mapping.getAttribute('array-name')
if array_name:
gtype_name = self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()
contents_sig = 'a{' + impl_sig + '}'
esc_contents_sig = escape_as_identifier(contents_sig)
impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig
self.h('/**\n * %s:\n\n' % gtype_name)
self.h(' * Expands to a call to a function\n')
self.h(' * that returns the #GType of a #GPtrArray\n')
self.h(' * of #%s.\n' % name)
self.h(' */\n')
self.h('#define %s (%s ())\n\n' % (gtype_name, impl))
self.need_other_arrays[contents_sig] = esc_contents_sig
def do_struct_header(self, struct):
members = struct.getElementsByTagNameNS(NS_TP, 'member')
impl_sig = ''.join([elt.getAttribute('type') for elt in members])
esc_impl_sig = escape_as_identifier(impl_sig)
name = (self.PREFIX_ + 'STRUCT_TYPE_' +
struct.getAttribute('name').upper())
impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig
docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring')
if docstring:
docstring = docstring[0].toprettyxml()
if docstring.startswith(''):
docstring = docstring[14:]
if docstring.endswith('\n'):
docstring = docstring[:-16]
if docstring.strip() in ('', ''):
docstring = '(Undocumented)'
else:
docstring = '(Undocumented)'
self.h('/**\n * %s:\n\n' % name)
self.h(' * %s\n' % xml_escape(docstring))
self.h(' *\n')
self.h(' * This macro expands to a call to a function\n')
self.h(' * that returns the #GType of a #GValueArray\n')
self.h(' * appropriate for representing a D-Bus struct\n')
self.h(' * with signature (%s).\n'
% impl_sig)
self.h(' *\n')
for i, member in enumerate(members):
self.h(' * Member %d (D-Bus type '
'%s,\n'
% (i, member.getAttribute('type')))
tp_type = member.getAttributeNS(NS_TP, 'type')
if tp_type:
self.h(' * type %s,\n' % tp_type)
self.h(' * named %s):\n'
% member.getAttribute('name'))
docstring = get_docstring(member) or '(Undocumented)'
self.h(' * %s\n' % xml_escape(docstring))
self.h(' *\n')
self.h(' */\n')
self.h('#define %s (%s ())\n\n' % (name, impl))
array_name = struct.getAttribute('array-name')
if array_name != '':
array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper())
impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig
self.h('/**\n * %s:\n\n' % array_name)
self.h(' * Expands to a call to a function\n')
self.h(' * that returns the #GType of a #GPtrArray\n')
self.h(' * of #%s.\n' % name)
self.h(' */\n')
self.h('#define %s (%s ())\n\n' % (array_name, impl))
self.need_struct_arrays[impl_sig] = esc_impl_sig
self.need_structs[impl_sig] = esc_impl_sig
def __call__(self):
mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping')
structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct')
for mapping in mappings:
self.do_mapping_header(mapping)
for sig in self.need_mappings:
self.h('GType %stype_dbus_hash_%s (void);\n\n' %
(self.prefix_, self.need_mappings[sig]))
self.c('GType\n%stype_dbus_hash_%s (void)\n{\n' %
(self.prefix_, self.need_mappings[sig]))
self.c(' static GType t = 0;\n\n')
self.c(' if (G_UNLIKELY (t == 0))\n')
# FIXME: translate sig into two GTypes
items = tuple(Signature(sig))
gtypes = types_to_gtypes(items)
self.c(' t = dbus_g_type_get_map ("GHashTable", '
'%s, %s);\n' % (gtypes[0], gtypes[1]))
self.c(' return t;\n')
self.c('}\n\n')
for struct in structs:
self.do_struct_header(struct)
for sig in self.need_structs:
self.h('GType %stype_dbus_struct_%s (void);\n\n' %
(self.prefix_, self.need_structs[sig]))
self.c('GType\n%stype_dbus_struct_%s (void)\n{\n' %
(self.prefix_, self.need_structs[sig]))
self.c(' static GType t = 0;\n\n')
self.c(' if (G_UNLIKELY (t == 0))\n')
self.c(' t = dbus_g_type_get_struct ("GValueArray",\n')
items = tuple(Signature(sig))
gtypes = types_to_gtypes(items)
for gtype in gtypes:
self.c(' %s,\n' % gtype)
self.c(' G_TYPE_INVALID);\n')
self.c(' return t;\n')
self.c('}\n\n')
for sig in self.need_struct_arrays:
self.h('GType %stype_dbus_array_%s (void);\n\n' %
(self.prefix_, self.need_struct_arrays[sig]))
self.c('GType\n%stype_dbus_array_%s (void)\n{\n' %
(self.prefix_, self.need_struct_arrays[sig]))
self.c(' static GType t = 0;\n\n')
self.c(' if (G_UNLIKELY (t == 0))\n')
self.c(' t = dbus_g_type_get_collection ("GPtrArray", '
'%stype_dbus_struct_%s ());\n' %
(self.prefix_, self.need_struct_arrays[sig]))
self.c(' return t;\n')
self.c('}\n\n')
for sig in self.need_other_arrays:
self.h('GType %stype_dbus_array_of_%s (void);\n\n' %
(self.prefix_, self.need_other_arrays[sig]))
self.c('GType\n%stype_dbus_array_of_%s (void)\n{\n' %
(self.prefix_, self.need_other_arrays[sig]))
self.c(' static GType t = 0;\n\n')
self.c(' if (G_UNLIKELY (t == 0))\n')
if sig[:2] == 'a{' and sig[-1:] == '}':
# array of mappings
self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_hash_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[2:-1])))
elif sig[:2] == 'a(' and sig[-1:] == ')':
# array of arrays of struct
self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_array_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[2:-1])))
elif sig[:1] == 'a':
# array of arrays of non-struct
self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_array_of_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[1:])))
else:
raise AssertionError("array of '%s' not supported" % sig)
self.c(' return t;\n')
self.c('}\n\n')
if __name__ == '__main__':
argv = sys.argv[1:]
dom = xml.dom.minidom.parse(argv[0])
GTypesGenerator(dom, argv[1], argv[2])()
telepathy-qt-0.9.6~git1/tools/repeat-tests.sh 0000775 0001750 0001750 00000000704 12470405660 017070 0 ustar jr jr #!/bin/sh
if [ $# -ne 2 ]
then
echo "usage: $0 "
echo "example: $0 \"make check-valgrind\" 100"
echo " or: $0 \"make -j4 check\" 100"
exit 1
fi
for i in `seq 1 $2`
do
echo -n "Running test iteration ${i}... "
log="test-round-${i}.log"
$1 > ${log} 2>&1
if grep -q "FAIL" $log
then
echo "FAILED (log in $log)"
else
echo "PASSED"
rm ${log}
fi
done
telepathy-qt-0.9.6~git1/tools/check-whitespace.sh 0000664 0001750 0001750 00000000323 12470405660 017651 0 ustar jr jr #!/bin/sh
fail=0
if grep -n ' $' "$@"
then
echo "^^^ The above files contain unwanted trailing spaces"
fail=1
fi
if grep -n ' ' "$@"
then
echo "^^^ The above files contain tabs"
fail=1
fi
exit $fail
telepathy-qt-0.9.6~git1/tools/libglibcodegen.py 0000664 0001750 0001750 00000014563 12470405660 017424 0 ustar jr jr """Library code for GLib/D-Bus-related code generation.
The master copy of this library is in the telepathy-glib repository -
please make any changes there.
"""
# Copyright (C) 2006-2008 Collabora Limited
#
# 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
from libtpcodegen import NS_TP, \
Signature, \
cmp_by_name, \
escape_as_identifier, \
get_by_path, \
get_descendant_text, \
get_docstring, \
xml_escape, \
get_deprecated
def dbus_gutils_wincaps_to_uscore(s):
"""Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore
which gets sequences of capital letters wrong in the same way.
(e.g. in Telepathy, SendDTMF -> send_dt_mf)
"""
ret = ''
for c in s:
if c >= 'A' and c <= 'Z':
length = len(ret)
if length > 0 and (length < 2 or ret[length-2] != '_'):
ret += '_'
ret += c.lower()
else:
ret += c
return ret
def signal_to_marshal_type(signal):
"""
return a list of strings indicating the marshalling type for this signal.
"""
mtype=[]
for i in signal.getElementsByTagName("arg"):
name =i.getAttribute("name")
type = i.getAttribute("type")
mtype.append(type_to_gtype(type)[2])
return mtype
_glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT',
'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT',
'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT',
'UINT_POINTER']
def signal_to_marshal_name(signal, prefix):
mtype = signal_to_marshal_type(signal)
if len(mtype):
name = '_'.join(mtype)
else:
name = 'VOID'
if name in _glib_marshallers:
return 'g_cclosure_marshal_VOID__' + name
else:
return prefix + '_marshal_VOID__' + name
def method_to_glue_marshal_name(method, prefix):
mtype = []
for i in method.getElementsByTagName("arg"):
if i.getAttribute("direction") != "out":
type = i.getAttribute("type")
mtype.append(type_to_gtype(type)[2])
mtype.append('POINTER')
name = '_'.join(mtype)
if name in _glib_marshallers:
return 'g_cclosure_marshal_VOID__' + name
else:
return prefix + '_marshal_VOID__' + name
def type_to_gtype(s):
if s == 'y': #byte
return ("guchar ", "G_TYPE_UCHAR","UCHAR", False)
elif s == 'b': #boolean
return ("gboolean ", "G_TYPE_BOOLEAN","BOOLEAN", False)
elif s == 'n': #int16
return ("gint ", "G_TYPE_INT","INT", False)
elif s == 'q': #uint16
return ("guint ", "G_TYPE_UINT","UINT", False)
elif s == 'i': #int32
return ("gint ", "G_TYPE_INT","INT", False)
elif s == 'u': #uint32
return ("guint ", "G_TYPE_UINT","UINT", False)
elif s == 'x': #int64
return ("gint64 ", "G_TYPE_INT64","INT64", False)
elif s == 't': #uint64
return ("guint64 ", "G_TYPE_UINT64","UINT64", False)
elif s == 'd': #double
return ("gdouble ", "G_TYPE_DOUBLE","DOUBLE", False)
elif s == 's': #string
return ("gchar *", "G_TYPE_STRING", "STRING", True)
elif s == 'g': #signature - FIXME
return ("gchar *", "DBUS_TYPE_G_SIGNATURE", "STRING", True)
elif s == 'o': #object path
return ("gchar *", "DBUS_TYPE_G_OBJECT_PATH", "BOXED", True)
elif s == 'v': #variant
return ("GValue *", "G_TYPE_VALUE", "BOXED", True)
elif s == 'as': #array of strings
return ("gchar **", "G_TYPE_STRV", "BOXED", True)
elif s == 'ay': #byte array
return ("GArray *",
"dbus_g_type_get_collection (\"GArray\", G_TYPE_UCHAR)", "BOXED",
True)
elif s == 'au': #uint array
return ("GArray *", "DBUS_TYPE_G_UINT_ARRAY", "BOXED", True)
elif s == 'ai': #int array
return ("GArray *", "DBUS_TYPE_G_INT_ARRAY", "BOXED", True)
elif s == 'ax': #int64 array
return ("GArray *", "DBUS_TYPE_G_INT64_ARRAY", "BOXED", True)
elif s == 'at': #uint64 array
return ("GArray *", "DBUS_TYPE_G_UINT64_ARRAY", "BOXED", True)
elif s == 'ad': #double array
return ("GArray *", "DBUS_TYPE_G_DOUBLE_ARRAY", "BOXED", True)
elif s == 'ab': #boolean array
return ("GArray *", "DBUS_TYPE_G_BOOLEAN_ARRAY", "BOXED", True)
elif s == 'ao': #object path array
return ("GPtrArray *",
'dbus_g_type_get_collection ("GPtrArray",'
' DBUS_TYPE_G_OBJECT_PATH)',
"BOXED", True)
elif s == 'a{ss}': #hash table of string to string
return ("GHashTable *", "DBUS_TYPE_G_STRING_STRING_HASHTABLE", "BOXED", False)
elif s[:2] == 'a{': #some arbitrary hash tables
if s[2] not in ('y', 'b', 'n', 'q', 'i', 'u', 's', 'o', 'g'):
raise Exception, "can't index a hashtable off non-basic type " + s
first = type_to_gtype(s[2])
second = type_to_gtype(s[3:-1])
return ("GHashTable *", "(dbus_g_type_get_map (\"GHashTable\", " + first[1] + ", " + second[1] + "))", "BOXED", False)
elif s[:2] in ('a(', 'aa'): # array of structs or arrays, recurse
gtype = type_to_gtype(s[1:])[1]
return ("GPtrArray *", "(dbus_g_type_get_collection (\"GPtrArray\", "+gtype+"))", "BOXED", True)
elif s[:1] == '(': #struct
gtype = "(dbus_g_type_get_struct (\"GValueArray\", "
for subsig in Signature(s[1:-1]):
gtype = gtype + type_to_gtype(subsig)[1] + ", "
gtype = gtype + "G_TYPE_INVALID))"
return ("GValueArray *", gtype, "BOXED", True)
# we just don't know ..
raise Exception, "don't know the GType for " + s
telepathy-qt-0.9.6~git1/tools/CMakeLists.txt 0000664 0001750 0001750 00000011271 12470405660 016652 0 ustar jr jr # Some useful commands
add_custom_command(OUTPUT FIXME.out
COMMAND egrep
ARGS -A 5 '[F]IXME|[T]ODO|[X]XX' ${CMAKE_SOURCE_DIR}/TelepathyQt/*.[ch]*
${CMAKE_SOURCE_DIR}/TelepathyQt/*.[ch]*
> FIXME.out || true)
add_custom_target(check-local DEPENDS FIXME.out)
execute_process(COMMAND ${SH} tools/git-which-branch.sh misc | tr -d '\n' | tr -C "[:alnum:]" _
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH_CURRENT)
if (GIT_BRANCH_CURRENT)
string(LENGTH ${GIT_BRANCH_CURRENT} HAVE_GIT_BRANCH)
if (HAVE_GIT_BRANCH)
string(REPLACE "\n" "" GIT_BRANCH_CURRENT ${GIT_BRANCH_CURRENT})
set(UPLOAD_BRANCH_TO people.freedesktop.org:public_html/telepathy-qt)
add_custom_target(upload-branch-docs rsync -rtzvPp --chmod=a+rX doc/html/ ${UPLOAD_BRANCH_TO}-${GIT_BRANCH_CURRENT}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(upload-branch-docs doxygen-doc)
endif (HAVE_GIT_BRANCH)
endif (GIT_BRANCH_CURRENT)
if (PERL_FOUND)
add_custom_target(maintainer-fix-qt-links-in-docs
${PERL_EXECUTABLE} doc/html/installdox -l qt.tags@http://doc.qt.nokia.com/latest/ doc/html/*.html
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(maintainer-fix-qt-links-in-docs doxygen-doc _maintainer-upload-release-check)
endif (PERL_FOUND)
add_custom_target(maintainer-upload-release-docs
rsync -rtOvzPp --chmod=Dg+s,ug+rwX,o=rX doc/html/ telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/doc/telepathy-qt/
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
if (PERL_FOUND)
add_dependencies(maintainer-upload-release-docs maintainer-fix-qt-links-in-docs)
else (PERL_FOUND)
add_dependencies(maintainer-upload-release-docs doxygen-doc _maintainer-upload-release-check)
endif (PERL_FOUND)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/maintainer-upload-release-check.sh "
#!/bin/sh
case ${PACKAGE_VERSION} in
(*.*.*.*)
echo \"${PACKAGE_VERSION} is not a release\" >&2;
exit 2;
;;
esac
test -f ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
if ! test -f ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz.asc; then
gpg --detach-sign -a ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz;
fi;
gpg --verify ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz.asc
")
add_custom_target(_maintainer-upload-release-check ${SH} ${CMAKE_CURRENT_BINARY_DIR}/maintainer-upload-release-check.sh)
add_custom_target(maintainer-upload-release
rsync -vzP ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/${PACKAGE_NAME}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
COMMAND
rsync -vzP ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz.asc
telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/${PACKAGE_NAME}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz.asc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(maintainer-upload-release _maintainer-upload-release-check maintainer-upload-release-docs)
set(toolchain_files
c-constants-gen.py
check-misc.sh
check-whitespace.sh
git-which-branch.sh
glib-ginterface-gen.py
glib-gtypes-generator.py
glib-interfaces-gen.py
glib-signals-marshal-gen.py
libtpcodegen.py
libglibcodegen.py
libqtcodegen.py
qt-client-gen.py
qt-constants-gen.py
qt-types-gen.py
manager-file.py
with-session-bus.sh
xincludator.py
)
string(REPLACE "." " " sh_toolchain_files ${toolchain_files})
set(TELEPATHY_SPEC_SRCDIR ${CMAKE_SOURCE_DIR}/../telepathy-spec)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/maintainer-update-from-telepathy-spec.sh "
#!/bin/sh
set -e
cd ${CMAKE_SOURCE_DIR}
for x in ${sh_toolchain_files}; do
if test -f ${TELEPATHY_SPEC_SRCDIR}/tools/$$x; then
cp ${TELEPATHY_SPEC_SRCDIR}/tools/$$x $$x;
fi;
done
")
add_custom_target(maintainer-update-from-telepathy-spec ${SH} ${CMAKE_CURRENT_BINARY_DIR}/maintainer-update-from-telepathy-spec.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
set(TELEPATHY_GLIB_SRCDIR ${CMAKE_SOURCE_DIR}/../telepathy-glib)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/maintainer-update-from-telepathy-glib.sh "
#!/bin/sh
set -e
cd ${CMAKE_SOURCE_DIR}
for x in ${sh_toolchain_files}; do
if test -f ${TELEPATHY_GLIB_SRCDIR}/tools/$$x; then
cp ${TELEPATHY_GLIB_SRCDIR}/tools/$$x $$x;
fi;
done
")
add_custom_target(maintainer-update-from-telepathy-glib ${SH} ${CMAKE_CURRENT_BINARY_DIR}/maintainer-update-from-telepathy-glib.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
telepathy-qt-0.9.6~git1/tools/manager-file.py 0000664 0001750 0001750 00000013616 12470405660 017020 0 ustar jr jr #!/usr/bin/python
# manager-file.py: generate .manager files and TpCMParamSpec arrays from the
# same data (should be suitable for all connection managers that don't have
# plugins)
#
# The master copy of this program is in the telepathy-glib repository -
# please make any changes there.
#
# Copyright (c) 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 St, Fifth Floor, Boston, MA 02110-1301 USA
import re
import sys
import os
_NOT_C_STR = re.compile(r'[^A-Za-z0-9_-]')
def c_string(x):
# whitelist-based brute force and ignorance - escape nearly all punctuation
return '"' + _NOT_C_STR.sub(lambda c: r'\x%02x' % ord(c), x) + '"'
def desktop_string(x):
return x.replace(' ', r'\s').replace('\n', r'\n').replace('\r', r'\r').replace('\t', r'\t')
supported = list('sbuiqn')
fdefaultencoders = {
's': desktop_string,
'b': (lambda b: b and '1' or '0'),
'u': (lambda n: '%u' % n),
'i': (lambda n: '%d' % n),
'q': (lambda n: '%u' % n),
'n': (lambda n: '%d' % n),
}
for x in supported: assert x in fdefaultencoders
gtypes = {
's': 'G_TYPE_STRING',
'b': 'G_TYPE_BOOLEAN',
'u': 'G_TYPE_UINT',
'i': 'G_TYPE_INT',
'q': 'G_TYPE_UINT',
'n': 'G_TYPE_INT',
}
for x in supported: assert x in gtypes
gdefaultencoders = {
's': c_string,
'b': (lambda b: b and 'GINT_TO_POINTER (TRUE)' or 'GINT_TO_POINTER (FALSE)'),
'u': (lambda n: 'GUINT_TO_POINTER (%u)' % n),
'i': (lambda n: 'GINT_TO_POINTER (%d)' % n),
'q': (lambda n: 'GUINT_TO_POINTER (%u)' % n),
'n': (lambda n: 'GINT_TO_POINTER (%d)' % n),
}
for x in supported: assert x in gdefaultencoders
gdefaultdefaults = {
's': 'NULL',
'b': 'GINT_TO_POINTER (FALSE)',
'u': 'GUINT_TO_POINTER (0)',
'i': 'GINT_TO_POINTER (0)',
'q': 'GUINT_TO_POINTER (0)',
'n': 'GINT_TO_POINTER (0)',
}
for x in supported: assert x in gdefaultdefaults
gflags = {
'has-default': 'TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT',
'register': 'TP_CONN_MGR_PARAM_FLAG_REGISTER',
'required': 'TP_CONN_MGR_PARAM_FLAG_REQUIRED',
'secret': 'TP_CONN_MGR_PARAM_FLAG_SECRET',
'dbus-property': 'TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY',
}
def write_manager(f, manager, protos):
# pointless backwards compat section
print >> f, '[ConnectionManager]'
print >> f, 'BusName=org.freedesktop.Telepathy.ConnectionManager.' + manager
print >> f, 'ObjectPath=/org/freedesktop/Telepathy/ConnectionManager/' + manager
# protocols
for proto, params in protos.iteritems():
print >> f
print >> f, '[Protocol %s]' % proto
defaults = {}
for param, info in params.iteritems():
dtype = info['dtype']
flags = info.get('flags', '').split()
struct_field = info.get('struct_field', param.replace('-', '_'))
filter = info.get('filter', 'NULL')
filter_data = info.get('filter_data', 'NULL')
setter_data = 'NULL'
if 'default' in info:
default = fdefaultencoders[dtype](info['default'])
defaults[param] = default
if flags:
flags = ' ' + ' '.join(flags)
else:
flags = ''
print >> f, 'param-%s=%s%s' % (param, desktop_string(dtype), flags)
for param, default in defaults.iteritems():
print >> f, 'default-%s=%s' % (param, default)
def write_c_params(f, manager, proto, struct, params):
print >> f, "static const TpCMParamSpec %s_%s_params[] = {" % (manager, proto)
for param, info in params.iteritems():
dtype = info['dtype']
flags = info.get('flags', '').split()
struct_field = info.get('struct_field', param.replace('-', '_'))
filter = info.get('filter', 'NULL')
filter_data = info.get('filter_data', 'NULL')
setter_data = 'NULL'
if 'default' in info:
default = gdefaultencoders[dtype](info['default'])
else:
default = gdefaultdefaults[dtype]
if flags:
flags = ' | '.join([gflags[flag] for flag in flags])
else:
flags = '0'
if struct is None or struct_field is None:
struct_offset = '0'
else:
struct_offset = 'G_STRUCT_OFFSET (%s, %s)' % (struct, struct_field)
print >> f, (''' { %s, %s, %s,
%s,
%s, /* default */
%s, /* struct offset */
%s, /* filter */
%s, /* filter data */
%s /* setter data */ },''' %
(c_string(param), c_string(dtype), gtypes[dtype], flags,
default, struct_offset, filter, filter_data, setter_data))
print >> f, " { NULL }"
print >> f, "};"
if __name__ == '__main__':
environment = {}
execfile(sys.argv[1], environment)
f = open('%s/%s.manager' % (sys.argv[2], environment['MANAGER']), 'w')
write_manager(f, environment['MANAGER'], environment['PARAMS'])
f.close()
f = open('%s/param-spec-struct.h' % sys.argv[2], 'w')
for protocol in environment['PARAMS']:
write_c_params(f, environment['MANAGER'], protocol,
environment['STRUCTS'][protocol],
environment['PARAMS'][protocol])
f.close()
telepathy-qt-0.9.6~git1/tools/qt-types-gen.py 0000664 0001750 0001750 00000041203 12470405660 017017 0 ustar jr jr #!/usr/bin/python
#
# Copyright (C) 2008 Collabora Limited
# Copyright (C) 2008 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 St, Fifth Floor, Boston, MA 02110-1301 USA
import sys
import xml.dom.minidom
from getopt import gnu_getopt
from libtpcodegen import NS_TP, get_descendant_text, get_by_path
from libqtcodegen import binding_from_usage, binding_from_decl, extract_arg_or_member_info, format_docstring, gather_externals, gather_custom_lists, get_qt_name, get_headerfile_cmd, RefRegistry
class BrokenSpecException(Exception):
pass
class MissingTypes(BrokenSpecException):
def __init__(self, types):
super(MissingTypes, self).__init__(self)
self.types = types
def __str__(self):
typelist = ''.join([' %s' % t for t in self.types])
return "The following types were used, but not provided by the spec " \
"or by declarations in all.xml:\n%s" % typelist
class UnresolvedDependency(BrokenSpecException):
def __init__(self, child, parent):
super(UnresolvedDependency, self).__init__(self)
self.child = child
self.parent = parent
def __str__(self):
return 'Type %s has unresolved dependency on %s' % (
self.child, self.parent)
class EmptyStruct(BrokenSpecException):
def __init__(self, struct_name):
super(EmptyStruct, self).__init__(self)
self.struct_name = struct_name
def __str__(self):
return 'tp:struct %s should have some members' % self.struct_name
class MalformedMapping(BrokenSpecException):
def __init__(self, mapping_name, members):
super(MalformedMapping, self).__init__(self)
self.mapping_name = mapping_name
self.members = members
def __str__(self):
return 'tp:mapping %s should have 2 members, not %u' % (
self.mapping_name, self.members)
class WTF(BrokenSpecException):
def __init__(self, element_name):
super(BrokenSpecException, self).__init__(self)
self.element_name = element_name
def __str__(self):
return 'What the hell is a tp:%s?' % self.element_name
class DepInfo:
def __init__(self, el, externals, custom_lists):
self.el = el
name = get_by_path(el, '@name')
array_name = get_by_path(el, '@array-name')
array_depth = get_by_path(el, '@array-depth')
if array_depth:
array_depth = int(array_depth)
else:
array_depth = None
self.binding = binding_from_decl(name, array_name, array_depth)
self.deps = []
for member in get_by_path(el, 'member'):
sig = member.getAttribute('type')
tptype = member.getAttributeNS(NS_TP, 'type')
if (sig, tptype) in externals:
continue
if tptype.endswith('[]'):
tptype = tptype[:-2]
binding = binding_from_usage(sig, tptype, custom_lists)
if binding.custom_type:
self.deps.append(binding.val)
self.revdeps = []
class Generator(object):
def __init__(self, opts):
try:
self.namespace = opts['--namespace']
self.declfile = opts['--declfile']
self.implfile = opts['--implfile']
self.realinclude = opts['--realinclude']
self.prettyinclude = opts.get('--prettyinclude', self.realinclude)
self.extraincludes = opts.get('--extraincludes', None)
self.must_define = opts.get('--must-define', None)
self.visibility = opts.get('--visibility', '')
dom = xml.dom.minidom.parse(opts['--specxml'])
except KeyError, k:
assert False, 'Missing required parameter %s' % k.args[0]
self.decls = []
self.impls = []
self.spec = get_by_path(dom, "spec")[0]
self.externals = gather_externals(self.spec)
self.custom_lists = gather_custom_lists(self.spec, self.namespace)
self.required_custom = []
self.required_arrays = []
self.to_declare = []
self.depinfos = {}
self.refs = RefRegistry(self.spec)
def __call__(self):
# Emit comment header
self.both('/* Generated from ')
self.both(get_descendant_text(get_by_path(self.spec, 'title')))
version = get_by_path(self.spec, "version")
if version:
self.both(', version ' + get_descendant_text(version))
self.both(' */\n')
# Gather info on available and required types
self.gather_required()
if self.must_define:
self.decl('\n')
self.decl('#ifndef %s\n' % self.must_define)
self.decl('#error %s\n' % self.must_define)
self.decl('#endif')
self.decl('\n')
if self.extraincludes:
for include in self.extraincludes.split(','):
self.decl('#include %s\n' % include)
self.decl("""
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
* \\addtogroup typesconstants Types and constants
*
* Enumerated, flag, structure, list and mapping types and utility constants.
*/
/**
* \\defgroup struct Structure types
* \\ingroup typesconstants
*
* Structure types generated from the specification.
*/
/**
* \\defgroup list List types
* \\ingroup typesconstants
*
* List types generated from the specification.
*/
/**
* \\defgroup mapping Mapping types
* \\ingroup typesconstants
*
* Mapping types generated from the specification.
*/
""")
if self.must_define:
self.impl("""
#define %s""" % self.must_define)
self.impl("""
#include "%s"
""" % self.realinclude)
self.both("""
namespace %s
{
""" % self.namespace)
# Emit type definitions for types provided in the spec
self.provide_all()
# Emit type registration function
self.decl("""
} // namespace %s
""" % self.namespace)
self.impl("""\
TP_QT_NO_EXPORT void _registerTypes()
{
static bool registered = false;
if (registered)
return;
registered = true;
""")
# Emit Qt metatype declarations
self.to_declare.sort()
for metatype in self.to_declare:
self.decl('Q_DECLARE_METATYPE(%s)\n' % metatype)
self.impl(' qDBusRegisterMetaType<%s>();\n' % ((metatype.endswith('>') and metatype + ' ') or metatype))
self.impl("""\
}
} // namespace %s
""" % self.namespace)
# Write output to files
open(self.declfile, 'w').write(''.join(self.decls).encode("utf-8"))
open(self.implfile, 'w').write(''.join(self.impls).encode("utf-8"))
def decl(self, str):
self.decls.append(str)
def impl(self, str):
self.impls.append(str)
def both(self, str):
self.decl(str)
self.impl(str)
def gather_required(self):
members = self.spec.getElementsByTagNameNS(NS_TP, 'member')
args = self.spec.getElementsByTagName('arg')
props = self.spec.getElementsByTagName('property')
tp_props = self.spec.getElementsByTagNameNS(NS_TP, 'property')
for requirer in members + args + props + tp_props:
sig = requirer.getAttribute('type')
tptype = requirer.getAttributeNS(NS_TP, 'type')
external = (sig, tptype) in self.externals
binding = binding_from_usage(sig, tptype, self.custom_lists, external)
if binding.custom_type and binding.val not in self.required_custom:
self.required_custom.append(binding.val)
if not binding.custom_type and binding.array_of and (binding.val, binding.array_of) not in self.required_arrays:
self.required_arrays.append((binding.val, binding.array_of))
def provide_all(self):
self.required_arrays.sort()
for (val, array_of) in self.required_arrays:
real = 'QList<%s>' % array_of
self.decl("""\
/**
* \\struct %s
* \\ingroup list
%s\
*
* Generic list type with %s elements. Convertible with
* %s, but needed to have a discrete type in the Qt type system.
*/
""" % (val, get_headerfile_cmd(self.realinclude, self.prettyinclude), array_of, real))
self.decl(self.faketype(val, real))
self.to_declare.append(self.namespace + '::' + val)
structs = self.spec.getElementsByTagNameNS(NS_TP, 'struct')
mappings = self.spec.getElementsByTagNameNS(NS_TP, 'mapping')
exts = self.spec.getElementsByTagNameNS(NS_TP, 'external-type')
for deptype in structs + mappings:
info = DepInfo(deptype, self.externals, self.custom_lists)
self.depinfos[info.binding.val] = info
leaves = []
next_leaves = []
for val, depinfo in self.depinfos.iteritems():
leaf = True
for dep in depinfo.deps:
if not self.depinfos.has_key(dep):
raise UnresolvedDependency(val, dep)
leaf = False
self.depinfos[dep].revdeps.append(val)
if leaf:
next_leaves.append(val)
while leaves or next_leaves:
if not leaves:
leaves = next_leaves
leaves.sort()
next_leaves = []
val = leaves.pop(0)
depinfo = self.depinfos[val]
self.output_by_depinfo(depinfo)
for revdep in depinfo.revdeps:
revdepinfo = self.depinfos[revdep]
revdepinfo.deps.remove(val)
if not revdepinfo.deps:
next_leaves.append(revdep)
del self.depinfos[val]
for provider in structs + mappings + exts:
name = get_by_path(provider, '@name')
array_name = get_by_path(provider, '@array-name')
array_depth = get_by_path(provider, '@array-depth')
if array_depth:
array_depth = int(array_depth)
else:
array_depth = None
sig = provider.getAttribute('type')
tptype = provider.getAttribute('name')
external = (sig, tptype) in self.externals
binding = binding_from_decl(name, array_name, array_depth, external)
self.provide(binding.val)
if binding.array_val:
self.provide(binding.array_val)
d = binding.array_depth
while d > 1:
d -= 1
self.provide(binding.array_val + ('List' * d))
if self.required_custom:
raise MissingTypes(self.required_custom)
def provide(self, type):
if type in self.required_custom:
self.required_custom.remove(type)
def output_by_depinfo(self, depinfo):
names, docstrings, bindings = extract_arg_or_member_info(get_by_path(depinfo.el, 'member'), self.custom_lists, self.externals, None, self.refs, ' * ', (' /**', ' */'))
members = len(names)
if depinfo.el.localName == 'struct':
if members == 0:
raise EmptyStruct(depinfo.binding.val)
self.decl("""\
/**
* \\struct %(name)s
* \\ingroup struct
%(headercmd)s\
*
* Structure type generated from the specification.
%(docstring)s\
*/
struct %(visibility)s %(name)s
{
""" % {
'name' : depinfo.binding.val,
'headercmd': get_headerfile_cmd(self.realinclude, self.prettyinclude),
'docstring' : format_docstring(depinfo.el, self.refs),
'visibility': self.visibility,
})
for i in xrange(members):
self.decl("""\
%s\
%s %s;
""" % (docstrings[i], bindings[i].val, names[i]))
self.decl("""\
};
""")
self.both('%s bool operator==(%s v1, %s v2)' %
(self.visibility,
depinfo.binding.inarg,
depinfo.binding.inarg))
self.decl(';\n')
self.impl("""
{""")
if (bindings[0].val != 'QDBusVariant'):
self.impl("""
return ((v1.%s == v2.%s)""" % (names[0], names[0]))
else:
self.impl("""
return ((v1.%s.variant() == v2.%s.variant())""" % (names[0], names[0]))
for i in xrange(1, members):
if (bindings[i].val != 'QDBusVariant'):
self.impl("""
&& (v1.%s == v2.%s)""" % (names[i], names[i]))
else:
self.impl("""
&& (v1.%s.variant() == v2.%s.variant())""" % (names[i], names[i]))
self.impl("""
);
}
""")
self.decl('inline bool operator!=(%s v1, %s v2)' %
(depinfo.binding.inarg, depinfo.binding.inarg))
self.decl("""
{
return !operator==(v1, v2);
}
""")
self.both('%s QDBusArgument& operator<<(QDBusArgument& arg, %s val)' %
(self.visibility, depinfo.binding.inarg))
self.decl(';\n')
self.impl("""
{
arg.beginStructure();
arg << %s;
arg.endStructure();
return arg;
}
""" % ' << '.join(['val.' + name for name in names]))
self.both('%s const QDBusArgument& operator>>(const QDBusArgument& arg, %s val)' %
(self.visibility, depinfo.binding.outarg))
self.decl(';\n\n')
self.impl("""
{
arg.beginStructure();
arg >> %s;
arg.endStructure();
return arg;
}
""" % ' >> '.join(['val.' + name for name in names]))
elif depinfo.el.localName == 'mapping':
if members != 2:
raise MalformedMapping(depinfo.binding.val, members)
realtype = 'QMap<%s, %s>' % (bindings[0].val, (bindings[1].val.endswith('>') and bindings[1].val + ' ') or bindings[1].val)
self.decl("""\
/**
* \\struct %s
* \\ingroup mapping
%s\
*
* Mapping type generated from the specification. Convertible with
* %s, but needed to have a discrete type in the Qt type system.
%s\
*/
""" % (depinfo.binding.val, get_headerfile_cmd(self.realinclude, self.prettyinclude), realtype, format_docstring(depinfo.el, self.refs)))
self.decl(self.faketype(depinfo.binding.val, realtype))
else:
raise WTF(depinfo.el.localName)
self.to_declare.append(self.namespace + '::' + depinfo.binding.val)
if depinfo.binding.array_val:
self.to_declare.append('%s::%s' % (self.namespace, depinfo.binding.array_val))
self.decl("""\
/**
* \\ingroup list
%s\
*
* Array of %s values.
*/
typedef %s %s;
""" % (get_headerfile_cmd(self.realinclude, self.prettyinclude), depinfo.binding.val, 'QList<%s>' % depinfo.binding.val, depinfo.binding.array_val))
i = depinfo.binding.array_depth
while i > 1:
i -= 1
self.to_declare.append('%s::%s%s' % (self.namespace, depinfo.binding.array_val, ('List' * i)))
list_of = depinfo.binding.array_val + ('List' * (i-1))
self.decl("""\
/**
* \\ingroup list
%s\
*
* Array of %s values.
*/
typedef QList<%s> %sList;
""" % (get_headerfile_cmd(self.realinclude, self.prettyinclude), list_of, list_of, list_of))
def faketype(self, fake, real):
return """\
struct %(visibility)s %(fake)s : public %(real)s
{
inline %(fake)s() : %(real)s() {}
inline %(fake)s(const %(real)s& a) : %(real)s(a) {}
inline %(fake)s& operator=(const %(real)s& a)
{
*(static_cast<%(real)s*>(this)) = a;
return *this;
}
};
""" % {'fake' : fake, 'real' : real, 'visibility': self.visibility}
if __name__ == '__main__':
options, argv = gnu_getopt(sys.argv[1:], '',
['declfile=',
'implfile=',
'realinclude=',
'prettyinclude=',
'extraincludes=',
'must-define=',
'namespace=',
'specxml=',
'visibility=',
])
try:
Generator(dict(options))()
except BrokenSpecException as e:
print >> sys.stderr, 'Your spec is broken, dear developer! %s' % e
sys.exit(42)
telepathy-qt-0.9.6~git1/tools/qt-constants-gen.py 0000664 0001750 0001750 00000021211 12470405660 017664 0 ustar jr jr #!/usr/bin/python
#
# Copyright (C) 2008 Collabora Limited
# Copyright (C) 2008 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 St, Fifth Floor, Boston, MA 02110-1301 USA
from sys import argv, stdout, stderr
import codecs
import xml.dom.minidom
from getopt import gnu_getopt
from libtpcodegen import NS_TP, get_descendant_text, get_by_path
from libqtcodegen import format_docstring, RefRegistry
class Generator(object):
def __init__(self, opts):
try:
self.namespace = opts['--namespace']
self.must_define = opts.get('--must-define', None)
dom = xml.dom.minidom.parse(opts['--specxml'])
except KeyError, k:
assert False, 'Missing required parameter %s' % k.args[0]
self.define_prefix = None
if '--define-prefix' in opts:
self.define_prefix = opts['--define-prefix']
self.old_prefix = None
if '--str-constant-prefix' in opts:
self.old_prefix = opts['--str-constant-prefix']
self.spec = get_by_path(dom, "spec")[0]
self.out = codecs.getwriter('utf-8')(stdout)
self.refs = RefRegistry(self.spec)
def h(self, code):
self.out.write(code)
def __call__(self):
# Header
self.h('/* Generated from ')
self.h(get_descendant_text(get_by_path(self.spec, 'title')))
version = get_by_path(self.spec, "version")
if version:
self.h(', version ' + get_descendant_text(version))
self.h("""
*/
""")
if self.must_define:
self.h("""
#ifndef %s
#error %s
#endif
""" % (self.must_define, self.must_define))
self.h("""
#include
/**
* \\addtogroup typesconstants Types and constants
*
* Enumerated, flag, structure, list and mapping types and utility constants.
*/
/**
* \\defgroup flagtypeconsts Flag type constants
* \\ingroup typesconstants
*
* Types generated from the specification representing bit flag constants and
* combinations of them (bitfields).
*/
/**
* \\defgroup enumtypeconsts Enumerated type constants
* \\ingroup typesconstants
*
* Types generated from the specification representing enumerated types ie.
* types the values of which are mutually exclusive integral constants.
*/
/**
* \\defgroup ifacestrconsts Interface string constants
* \\ingroup typesconstants
*
* D-Bus interface names of the interfaces in the specification.
*/
/**
* \\defgroup errorstrconsts Error string constants
* \\ingroup typesconstants
*
* Names of the D-Bus errors in the specification.
*/
""")
# Begin namespace
self.h("""
namespace %s
{
""" % self.namespace)
# Flags
for flags in self.spec.getElementsByTagNameNS(NS_TP, 'flags'):
self.do_flags(flags)
# Enums
for enum in self.spec.getElementsByTagNameNS(NS_TP, 'enum'):
self.do_enum(enum)
# End namespace
self.h("""\
}
""")
# Interface names
for iface in self.spec.getElementsByTagName('interface'):
if self.old_prefix:
self.h("""\
/**
* \\ingroup ifacestrconsts
*
* The interface name "%(name)s".
*/
#define %(DEFINE)s "%(name)s"
""" % {'name' : iface.getAttribute('name'),
'DEFINE' : self.old_prefix + 'INTERFACE_' + get_by_path(iface, '../@name').upper().replace('/', '')})
if self.define_prefix:
self.h("""\
/**
* \\ingroup ifacestrconsts
*
* The interface name "%(name)s" as a QLatin1String, usable in QString requiring contexts even when
* building with Q_NO_CAST_FROM_ASCII defined.
*/
#define %(DEFINE)s (QLatin1String("%(name)s"))
""" % {'name' : iface.getAttribute('name'),
'DEFINE' : self.define_prefix + 'IFACE_' + get_by_path(iface, '../@name').upper().replace('/', '')})
# Error names
for error in get_by_path(self.spec, 'errors/error'):
name = error.getAttribute('name')
fullname = get_by_path(error, '../@namespace') + '.' + name.replace(' ', '')
if self.old_prefix:
define = self.old_prefix + 'ERROR_' + name.replace(' ', '_').replace('.', '_').upper()
self.h("""\
/**
* \\ingroup errorstrconsts
*
* The error name "%(fullname)s".
%(docstring)s\
*/
#define %(DEFINE)s "%(fullname)s"
""" % {'fullname' : fullname,
'docstring': format_docstring(error, self.refs),
'DEFINE' : define})
if self.define_prefix:
define = self.define_prefix + 'ERROR_' + name.replace(' ', '_').replace('.', '_').upper()
self.h("""\
/**
* \\ingroup errorstrconsts
*
* The error name "%(fullname)s" as a QLatin1String, usable in QString requiring contexts even when
* building with Q_NO_CAST_FROM_ASCII defined.
%(docstring)s\
*/
#define %(DEFINE)s QLatin1String("%(fullname)s")
""" % {'fullname' : fullname,
'docstring': format_docstring(error, self.refs),
'DEFINE' : define})
def do_flags(self, flags):
singular = flags.getAttribute('singular') or \
flags.getAttribute('value-prefix')
using_name = False
if not singular:
using_name = True
singular = flags.getAttribute('name')
if singular.endswith('lags'):
singular = singular[:-1]
if using_name and singular.endswith('s'):
singular = singular[:-1]
singular = singular.replace('_', '')
plural = (flags.getAttribute('plural') or flags.getAttribute('name') or singular + 's').replace('_', '')
self.h("""\
/**
* \\ingroup flagtypeconsts
*
* Flag type generated from the specification.
*/
enum %(singular)s
{
""" % {'singular' : singular})
flagvalues = get_by_path(flags, 'flag')
for flag in flagvalues:
self.do_val(flag, singular, flag == flagvalues[-1])
self.h("""\
%s = 0xffffffffU
""" % ("_" + singular + "Padding"))
self.h("""\
};
/**
* \\typedef QFlags<%(singular)s> %(plural)s
* \\ingroup flagtypeconsts
*
* Type representing combinations of #%(singular)s values.
%(docstring)s\
*/
typedef QFlags<%(singular)s> %(plural)s;
Q_DECLARE_OPERATORS_FOR_FLAGS(%(plural)s)
""" % {'singular' : singular, 'plural' : plural, 'docstring' : format_docstring(flags, self.refs)})
def do_enum(self, enum):
singular = enum.getAttribute('singular') or \
enum.getAttribute('name')
value_prefix = enum.getAttribute('singular') or \
enum.getAttribute('value-prefix') or \
enum.getAttribute('name')
if singular.endswith('lags'):
singular = singular[:-1]
plural = enum.getAttribute('plural') or singular + 's'
singular = singular.replace('_', '')
value_prefix = value_prefix.replace('_', '')
vals = get_by_path(enum, 'enumvalue')
self.h("""\
/**
* \\enum %(singular)s
* \\ingroup enumtypeconsts
*
* Enumerated type generated from the specification.
%(docstring)s\
*/
enum %(singular)s
{
""" % {'singular' : singular, 'docstring' : format_docstring(enum, self.refs)})
for val in vals:
self.do_val(val, value_prefix, val == vals[-1])
self.h("""\
%s = 0xffffffffU
};
""" % ("_" + singular + "Padding"))
self.h("""\
/**
* \\ingroup enumtypeconsts
*
* 1 higher than the highest valid value of %(singular)s.
*/
const int NUM_%(upper-plural)s = (%(last-val)s+1);
""" % {'singular' : singular,
'upper-plural' : plural.upper(),
'last-val' : vals[-1].getAttribute('value')})
def do_val(self, val, prefix, last):
name = (val.getAttribute('suffix') or val.getAttribute('name')).replace('_', '')
self.h("""\
%s\
%s = %s,
""" % (format_docstring(val, self.refs, indent=' * ', brackets=(' /**', ' */')), prefix + name, val.getAttribute('value')))
if __name__ == '__main__':
options, argv = gnu_getopt(argv[1:], '',
['namespace=',
'str-constant-prefix=',
'define-prefix=',
'must-define=',
'specxml='])
Generator(dict(options))()
telepathy-qt-0.9.6~git1/tools/tp-qt-tests.supp 0000664 0001750 0001750 00000002663 12470405660 017235 0 ustar jr jr # QDBus doesn't call dbus_shutdown, so some D-Bus internal data structures are leaked.
# We never call any low-level dbus message creation functions ourselves - if there are leaks,
# they're either caused by not calling dbus_shutdown, QDBus bugs or libdbus bugs - neither of which
# are our problem.
{
Initial session bus registration message
Memcheck:Leak
fun:malloc
fun:dbus_message_new_empty_header
}
# The conference test CM channel object leaks some crazy GValue boxed data which I don't have the
# energy to investigate how to properly free now - it's not production code anyway.
{
Conference test CM channel boxed GValue data
Memcheck:Leak
...
fun:g_boxed_copy
...
fun:_ZN18TestConferenceChan12initTestCaseEv
}
# Reported as https://bugs.freedesktop.org/show_bug.cgi?id=32116
{
TpBaseConnectionManager legacy protocol objects
Memcheck:Leak
...
fun:g_object_new
...
fun:tp_base_connection_manager_register
}
# O(number of error domains) leak from dbus_g_method_return_error
{
dbus_g_method_return_error error domain enum class
Memcheck:Leak
...
fun:g_type_class_ref
...
fun:dbus_g_method_return_error
}
# O(1) leak from tp_base_connection_manager installing the param spec for the dbus-daemon param
{
tp_base_connection_manager dbus-daemon param spec
Memcheck:Leak
...
fun:g_param_spec_object
fun:tp_base_connection_manager_class_intern_init
}
telepathy-qt-0.9.6~git1/tools/glib-interfaces-gen.py 0000664 0001750 0001750 00000006366 12470405660 020302 0 ustar jr jr #!/usr/bin/python
from sys import argv, stdout, stderr
import xml.dom.minidom
from libglibcodegen import NS_TP, get_docstring, \
get_descendant_text, get_by_path
class Generator(object):
def __init__(self, prefix, implfile, declfile, dom):
self.prefix = prefix + '_'
self.impls = open(implfile, 'w')
self.decls = open(declfile, 'w')
self.spec = get_by_path(dom, "spec")[0]
def h(self, code):
self.decls.write(code.encode('utf-8'))
def c(self, code):
self.impls.write(code.encode('utf-8'))
def __call__(self):
for f in self.h, self.c:
self.do_header(f)
self.do_body()
# Header
def do_header(self, f):
f('/* Generated from: ')
f(get_descendant_text(get_by_path(self.spec, 'title')))
version = get_by_path(self.spec, "version")
if version:
f(' version ' + get_descendant_text(version))
f('\n\n')
for copyright in get_by_path(self.spec, 'copyright'):
f(get_descendant_text(copyright))
f('\n')
f('\n')
f(get_descendant_text(get_by_path(self.spec, 'license')))
f(get_descendant_text(get_by_path(self.spec, 'docstring')))
f("""
*/
""")
# Body
def do_body(self):
for iface in self.spec.getElementsByTagName('interface'):
self.do_iface(iface)
def do_iface(self, iface):
parent_name = get_by_path(iface, '../@name')
self.h("""\
/**
* %(IFACE_DEFINE)s:
*
* The interface name "%(name)s"
*/
#define %(IFACE_DEFINE)s \\
"%(name)s"
""" % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \
parent_name).upper().replace('/', ''),
'name' : iface.getAttribute('name')})
self.h("""
/**
* %(IFACE_QUARK_DEFINE)s:
*
* Expands to a call to a function that returns a quark for the interface \
name "%(name)s"
*/
#define %(IFACE_QUARK_DEFINE)s \\
(%(iface_quark_func)s ())
GQuark %(iface_quark_func)s (void);
""" % {'IFACE_QUARK_DEFINE' : (self.prefix + 'IFACE_QUARK_' + \
parent_name).upper().replace('/', ''),
'iface_quark_func' : (self.prefix + 'iface_quark_' + \
parent_name).lower().replace('/', ''),
'name' : iface.getAttribute('name')})
self.c("""\
GQuark
%(iface_quark_func)s (void)
{
static GQuark quark = 0;
if (G_UNLIKELY (quark == 0))
{
quark = g_quark_from_static_string ("%(name)s");
}
return quark;
}
""" % {'iface_quark_func' : (self.prefix + 'iface_quark_' + \
parent_name).lower().replace('/', ''),
'name' : iface.getAttribute('name')})
for prop in iface.getElementsByTagNameNS(None, 'property'):
self.decls.write("""
/**
* %(IFACE_PREFIX)s_%(PROP_UC)s:
*
* The fully-qualified property name "%(name)s.%(prop)s"
*/
#define %(IFACE_PREFIX)s_%(PROP_UC)s \\
"%(name)s.%(prop)s"
""" % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \
parent_name).upper().replace('/', ''),
'PROP_UC': prop.getAttributeNS(NS_TP, "name-for-bindings").upper(),
'name' : iface.getAttribute('name'),
'prop' : prop.getAttribute('name'),
})
if __name__ == '__main__':
argv = argv[1:]
Generator(argv[0], argv[1], argv[2], xml.dom.minidom.parse(argv[3]))()
telepathy-qt-0.9.6~git1/tools/c-constants-gen.py 0000664 0001750 0001750 00000011200 12470405660 017457 0 ustar jr jr #!/usr/bin/python
from sys import argv, stdout, stderr
import xml.dom.minidom
from libglibcodegen import NS_TP, get_docstring, \
get_descendant_text, get_by_path
class Generator(object):
def __init__(self, prefix, dom):
self.prefix = prefix + '_'
self.spec = get_by_path(dom, "spec")[0]
def __call__(self):
self.do_header()
self.do_body()
self.do_footer()
def write(self, code):
stdout.write(code.encode('utf-8'))
# Header
def do_header(self):
self.write('/* Generated from ')
self.write(get_descendant_text(get_by_path(self.spec, 'title')))
version = get_by_path(self.spec, "version")
if version:
self.write(', version ' + get_descendant_text(version))
self.write('\n\n')
for copyright in get_by_path(self.spec, 'copyright'):
self.write(get_descendant_text(copyright))
self.write('\n')
self.write(get_descendant_text(get_by_path(self.spec, 'license')))
self.write('\n')
self.write(get_descendant_text(get_by_path(self.spec, 'docstring')))
self.write("""
*/
#ifdef __cplusplus
extern "C" {
#endif
\n""")
# Body
def do_body(self):
for elem in self.spec.getElementsByTagNameNS(NS_TP, '*'):
if elem.localName == 'flags':
self.do_flags(elem)
elif elem.localName == 'enum':
self.do_enum(elem)
def do_flags(self, flags):
name = flags.getAttribute('plural') or flags.getAttribute('name')
value_prefix = flags.getAttribute('singular') or \
flags.getAttribute('value-prefix') or \
flags.getAttribute('name')
self.write("""\
/**
*
%s:
""" % (self.prefix + name).replace('_', ''))
for flag in get_by_path(flags, 'flag'):
self.do_gtkdoc(flag, value_prefix)
self.write(' *\n')
docstrings = get_by_path(flags, 'docstring')
if docstrings:
self.write("""\
*
*
""" % get_descendant_text(docstrings).replace('\n', ' '))
self.write("""\
* Bitfield/set of flags generated from the Telepathy specification.
*/
typedef enum {
""")
for flag in get_by_path(flags, 'flag'):
self.do_val(flag, value_prefix)
self.write("""\
} %s;
""" % (self.prefix + name).replace('_', ''))
def do_enum(self, enum):
name = enum.getAttribute('singular') or enum.getAttribute('name')
value_prefix = enum.getAttribute('singular') or \
enum.getAttribute('value-prefix') or \
enum.getAttribute('name')
name_plural = enum.getAttribute('plural') or \
enum.getAttribute('name') + 's'
self.write("""\
/**
*
%s:
""" % (self.prefix + name).replace('_', ''))
vals = get_by_path(enum, 'enumvalue')
for val in vals:
self.do_gtkdoc(val, value_prefix)
self.write(' *\n')
docstrings = get_by_path(enum, 'docstring')
if docstrings:
self.write("""\
*
*
""" % get_descendant_text(docstrings).replace('\n', ' '))
self.write("""\
* Bitfield/set of flags generated from the Telepathy specification.
*/
typedef enum {
""")
for val in vals:
self.do_val(val, value_prefix)
self.write("""\
} %(mixed-name)s;
/**
* NUM_%(upper-plural)s:
*
* 1 higher than the highest valid value of #%(mixed-name)s.
*/
#define NUM_%(upper-plural)s (%(last-val)s+1)
""" % {'mixed-name' : (self.prefix + name).replace('_', ''),
'upper-plural' : (self.prefix + name_plural).upper(),
'last-val' : vals[-1].getAttribute('value')})
def do_val(self, val, value_prefix):
name = val.getAttribute('name')
suffix = val.getAttribute('suffix')
use_name = (self.prefix + value_prefix + '_' + \
(suffix or name)).upper()
assert not (name and suffix) or name == suffix, \
'Flag/enumvalue name %s != suffix %s' % (name, suffix)
self.write(' %s = %s,\n' % (use_name, val.getAttribute('value')))
def do_gtkdoc(self, node, value_prefix):
self.write(' * @')
self.write((self.prefix + value_prefix + '_' +
node.getAttribute('suffix')).upper())
self.write(': \n')
# Footer
def do_footer(self):
self.write("""
#ifdef __cplusplus
}
#endif
""")
if __name__ == '__main__':
argv = argv[1:]
Generator(argv[0], xml.dom.minidom.parse(argv[1]))()
telepathy-qt-0.9.6~git1/tools/qt-svc-gen.py 0000664 0001750 0001750 00000056366 12470405660 016466 0 ustar jr jr #!/usr/bin/python
#
# Copyright (C) 2012 Collabora Limited
# Copyright (C) 2012 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 St, Fifth Floor, Boston, MA 02110-1301 USA
from sys import argv
import xml.dom.minidom
import codecs
from getopt import gnu_getopt
from libtpcodegen import NS_TP, get_descendant_text, get_by_path
from libqtcodegen import binding_from_usage, extract_arg_or_member_info, format_docstring, gather_externals, gather_custom_lists, get_headerfile_cmd, get_qt_name, qt_identifier_escape, RefRegistry
# TODO generate docstrings
def to_lower_camel_case(s):
if len(s) <= 1:
return s.lower()
i = 0
for c in s:
if c == '_':
break
i += 1
ret = s
if i == len(s):
return s.lower()
else:
ret = s[0:i].lower() + s[i:]
ret = ret.replace('_', '')
return ret
class Generator(object):
def __init__(self, opts):
try:
self.group = opts.get('--group', '')
self.headerfile = opts['--headerfile']
self.implfile = opts['--implfile']
self.namespace = opts['--namespace']
self.typesnamespace = opts['--typesnamespace']
self.realinclude = opts.get('--realinclude', None)
self.mocinclude = opts.get('--mocinclude', None)
self.prettyinclude = opts.get('--prettyinclude')
self.extraincludes = opts.get('--extraincludes', None)
self.must_define = opts.get('--must-define', None)
self.visibility = opts.get('--visibility', '')
ifacedom = xml.dom.minidom.parse(opts['--ifacexml'])
specdom = xml.dom.minidom.parse(opts['--specxml'])
except KeyError, k:
assert False, 'Missing required parameter %s' % k.args[0]
if not self.realinclude:
self.realinclude = self.headerfile
self.hs = []
self.bs = []
self.ifacenodes = ifacedom.getElementsByTagName('node')
self.spec, = get_by_path(specdom, "spec")
self.custom_lists = gather_custom_lists(self.spec, self.typesnamespace)
self.externals = gather_externals(self.spec)
self.refs = RefRegistry(self.spec)
def __call__(self):
# Output info header and includes
self.h("""\
/*
* This file contains D-Bus adaptor classes generated by qt-svc-gen.py.
*
* This file can be distributed under the same terms as the specification from
* which it was generated.
*/
""")
if self.must_define:
self.h('\n')
self.h('#ifndef %s\n' % self.must_define)
self.h('#error %s\n' % self.must_define)
self.h('#endif\n')
self.h('\n')
if self.extraincludes:
for include in self.extraincludes.split(','):
self.h('#include %s\n' % include)
self.h("""\
#include
#include
#include
#include
#include
""")
if self.must_define:
self.b("""#define %s\n""" % (self.must_define))
self.b("""#include "%s"
""" % self.realinclude)
if self.mocinclude:
self.b("""#include "%s"
""" % self.mocinclude)
self.b("""\
#include
#include
""")
# Begin namespace
for ns in self.namespace.split('::'):
self.hb("""\
namespace %s
{
""" % ns)
# Output interface proxies
def ifacenodecmp(x, y):
xname, yname = [self.namespace + '::' + node.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor' for node in x, y]
return cmp(xname, yname)
self.ifacenodes.sort(cmp=ifacenodecmp)
for ifacenode in self.ifacenodes:
self.do_ifacenode(ifacenode)
# End namespace
self.hb(''.join(['\n}' for ns in self.namespace.split('::')]))
# Write output to files
(codecs.getwriter('utf-8')(open(self.headerfile, 'w'))).write(''.join(self.hs))
(codecs.getwriter('utf-8')(open(self.implfile, 'w'))).write(''.join(self.bs))
def do_ifacenode(self, ifacenode):
# Extract info
name = ifacenode.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor'
iface, = get_by_path(ifacenode, 'interface')
dbusname = iface.getAttribute('name')
props = get_by_path(iface, 'property')
methods = get_by_path(iface, 'method')
signals = get_by_path(iface, 'signal')
# Begin class, constructors
self.h("""
/**
* \\class %(name)s
%(headercmd)s\
%(groupcmd)s\
*
* Adaptor class providing a 1:1 mapping of the D-Bus interface "%(dbusname)s".
*/
class %(visibility)s %(name)s : public Tp::AbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "%(dbusname)s")
Q_CLASSINFO("D-Bus Introspection", ""
" \\n"
""" % {'name': name,
'headercmd': get_headerfile_cmd(self.realinclude, self.prettyinclude),
'groupcmd': self.group and (' * \\ingroup %s\n' % self.group),
'dbusname': dbusname,
'visibility': self.visibility,
})
self.do_introspection(props, methods, signals)
self.h("""\
" \\n"
"")
""")
self.do_qprops(props)
self.h("""
public:
%(name)s(const QDBusConnection& dbusConnection, QObject* adaptee, QObject* parent);
virtual ~%(name)s();
""" % {'name': name})
self.do_mic_typedefs(methods)
self.b("""
%(name)s::%(name)s(const QDBusConnection& bus, QObject* adaptee, QObject* parent)
: Tp::AbstractAdaptor(bus, adaptee, parent)
{
""" % {'name': name})
self.do_signals_connect(signals)
self.b("""\
}
%(name)s::~%(name)s()
{
}
""" % {'name': name})
# Properties
has_props = False
if props:
self.h("""
public: // PROPERTIES
""")
for prop in props:
# Skip tp:properties
if not prop.namespaceURI:
self.do_prop(name, prop)
has_props = True
# Methods
if methods:
self.h("""
public Q_SLOTS: // METHODS
""")
for method in methods:
self.do_method(name, method)
# Signals
if signals:
self.h("""
Q_SIGNALS: // SIGNALS
""")
for signal in signals:
self.do_signal(signal)
# Close class
self.h("""\
};
""")
def do_introspection(self, props, methods, signals):
self.do_prop_introspection(props)
self.do_method_introspection(methods)
self.do_signal_introspection(signals)
def do_prop_introspection(self, props):
for prop in props:
if prop.namespaceURI:
continue
name = prop.getAttribute('name')
access = prop.getAttribute('access')
sig = prop.getAttribute('type')
tptype = prop.getAttributeNS(NS_TP, 'type')
binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace)
if not binding.custom_type:
self.h("""\
" \\n"
""" % {'access': access,
'sig': sig,
'name': name,
})
else:
self.h("""\
" \\n"
" \\n"
" \\n"
""" % {'access': access,
'sig': sig,
'name': name,
'type': binding.val,
})
def do_method_introspection(self, methods):
for method in methods:
name = method.getAttribute('name')
args = get_by_path(method, 'arg')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(args,
self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
if not argnames:
self.h("""\
" \\n"
""" % {'name': name})
else:
self.h("""\
" \\n"
""" % {'name': name})
outindex = 0
inindex = 0
for i in xrange(len(argnames)):
assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name)
argbinding = argbindings[i]
argname = argnames[i]
argsig = args[i].getAttribute('type')
argdirection = args[i].getAttribute('direction')
# QtDBus requires annotating a{sv}
if argsig == 'a{sv}':
argbinding.custom_type = True
if not argbinding.custom_type:
self.h("""\
" \\n"
""" % {'direction': argdirection,
'sig': argsig,
'name': argname})
else:
self.h("""\
" \\n"
" \\n"
" \\n"
""" % {'direction': argdirection,
'sig': argsig,
'name': argname,
'type': argbinding.val,
'index': 'In' + str(inindex) if argdirection == 'in' else 'Out' + str(outindex),
})
if argdirection == 'out':
outindex += 1
else:
inindex += 1
self.h("""\
" \\n"
""")
def do_signal_introspection(self, signals):
for signal in signals:
name = signal.getAttribute('name')
args = get_by_path(signal, 'arg')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(args,
self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
if not argnames:
self.h("""\
" \\n"
""" % {'name': name})
else:
self.h("""\
" \\n"
""" % {'name': name})
for i in xrange(len(argnames)):
assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name)
argbinding = argbindings[i]
argname = argnames[i]
argsig = args[i].getAttribute('type')
if not argbinding.custom_type:
self.h("""\
" \\n"
""" % {'sig': argsig,
'name': argname})
else:
self.h("""\
" \\n"
" \\n"
" \\n"
""" % {'sig': argsig,
'name': argname,
'type': argbinding.val,
'index': i,
})
self.h("""\
" \\n"
""")
def do_mic_typedefs(self, methods):
for method in methods:
name = method.getAttribute('name')
args = get_by_path(method, 'arg')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists,
self.externals, self.typesnamespace, self.refs, ' * ')
outargs = []
for i in xrange(len(args)):
if args[i].getAttribute('direction') == 'out':
outargs.append(i)
if outargs:
outargtypes = ', '.join([argbindings[i].val for i in outargs])
else:
outargtypes = ''
self.h("""\
typedef Tp::MethodInvocationContextPtr< %(outargtypes)s > %(name)sContextPtr;
""" % {'name': name,
'outargtypes': outargtypes,
})
def do_qprops(self, props):
for prop in props:
# Skip tp:properties
if not prop.namespaceURI:
self.do_qprop(prop)
def do_qprop(self, prop):
name = prop.getAttribute('name')
access = prop.getAttribute('access')
gettername = name
settername = None
if 'write' in access:
settername = 'Set' + name
sig = prop.getAttribute('type')
tptype = prop.getAttributeNS(NS_TP, 'type')
binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace)
self.h("""\
Q_PROPERTY(%(type)s %(name)s %(getter)s %(setter)s)
""" % {'type': binding.val,
'name': name,
'getter': 'READ ' + gettername if ('read' in access) else '',
'setter': 'WRITE ' + settername if ('write' in access) else '',
})
def do_prop(self, ifacename, prop):
name = prop.getAttribute('name')
adaptee_name = to_lower_camel_case(prop.getAttribute('tp:name-for-bindings'))
access = prop.getAttribute('access')
gettername = name
settername = None
if 'write' in access:
settername = 'Set' + name
docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/')
sig = prop.getAttribute('type')
tptype = prop.getAttributeNS(NS_TP, 'type')
binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace)
if 'read' in access:
self.h("""\
/**
* Return the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s.
*
* Adaptees should export this property as a Qt property named
* '%(adaptee_name)s' with type %(type)s.
*
%(docstring)s\
*
* \\return The value of exported property \\c %(name)s.
*/
%(type)s %(gettername)s() const;
""" % {'name': name,
'adaptee_name': adaptee_name,
'docstring': docstring,
'type': binding.val,
'gettername': gettername,
})
self.b("""
%(type)s %(ifacename)s::%(gettername)s() const
{
return qvariant_cast< %(type)s >(adaptee()->property("%(adaptee_name)s"));
}
""" % {'type': binding.val,
'ifacename': ifacename,
'gettername': gettername,
'adaptee_name': adaptee_name,
})
if 'write' in access:
self.h("""\
/**
* Set the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s.
*
* Adaptees should export this property as a writable Qt property named
* '%(adaptee_name)s' with type %(type)s.
*
%(docstring)s\
*/
void %(settername)s(const %(type)s &newValue);
""" % {'name': name,
'adaptee_name': adaptee_name,
'docstring': docstring,
'settername': settername,
'type': binding.val,
})
self.b("""
void %(ifacename)s::%(settername)s(const %(type)s &newValue)
{
adaptee()->setProperty("%(adaptee_name)s", qVariantFromValue(newValue));
}
""" % {'ifacename': ifacename,
'settername': settername,
'type': binding.val,
'adaptee_name': adaptee_name,
})
def do_method(self, ifacename, method):
name = method.getAttribute('name')
adaptee_name = to_lower_camel_case(method.getAttribute('tp:name-for-bindings'))
args = get_by_path(method, 'arg')
argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists,
self.externals, self.typesnamespace, self.refs, ' * ')
docstring = format_docstring(method, self.refs, ' * ').replace('*/', '*/')
inargs = []
outargs = []
for i in xrange(len(args)):
if args[i].getAttribute('direction') == 'out':
outargs.append(i)
else:
inargs.append(i)
assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name)
if outargs:
rettype = argbindings[outargs[0]].val
else:
rettype = 'void'
params = [argbindings[i].inarg + ' ' + argnames[i] for i in inargs]
params.append('const QDBusMessage& dbusMessage')
params += [argbindings[i].outarg + ' ' + argnames[i] for i in outargs[1:]]
params = ', '.join(params)
if outargs:
outargtypes = ', '.join([argbindings[i].val for i in outargs])
else:
outargtypes = ''
invokemethodargs = ', '.join(['Q_ARG(' + argbindings[i].val + ', ' + argnames[i] + ')' for i in inargs])
inparams = [argbindings[i].val for i in inargs]
inparams.append("%s::%s::%sContextPtr" % (self.namespace, ifacename, name))
normalized_adaptee_params = ','.join(inparams)
adaptee_params = [argbindings[i].inarg + ' ' + argnames[i] for i in inargs]
adaptee_params.append('const %(namespace)s::%(ifacename)s::%(name)sContextPtr &context' %
{'namespace': self.namespace,
'ifacename': ifacename,
'name': name})
adaptee_params = ', '.join(adaptee_params)
self.h("""\
/**
* Begins a call to the exported D-Bus method \\c %(name)s on this object.
*
* Adaptees should export this method as a Qt slot with the following signature:
* void %(adaptee_name)s(%(adaptee_params)s);
*
* Implementations should call MethodInvocationContext::setFinished (or setFinishedWithError
* accordingly) on the received \\a context object once the method has finished processing.
*
%(docstring)s\
*
""" % {'name': name,
'adaptee_name': adaptee_name,
'adaptee_params': adaptee_params,
'rettype': rettype,
'docstring': docstring
})
for i in inargs:
if argdocstrings[i]:
self.h("""\
* \\param %s
%s\
""" % (argnames[i], argdocstrings[i]))
for i in outargs[1:]:
if argdocstrings[i]:
self.h("""\
* \\param %s Output parameter
%s\
""" % (argnames[i], argdocstrings[i]))
if outargs:
self.h("""\
* \\return
%s\
""" % argdocstrings[outargs[0]])
self.h("""\
*/
%(rettype)s %(name)s(%(params)s);
""" % {'rettype': rettype,
'name': name,
'params': params
})
self.b("""
%(rettype)s %(ifacename)s::%(name)s(%(params)s)
{
if (!adaptee()->metaObject()->indexOfMethod("%(adaptee_name)s(%(normalized_adaptee_params)s)") == -1) {
dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented")));
""" % {'rettype': rettype,
'ifacename': ifacename,
'name': name,
'adaptee_name': adaptee_name,
'normalized_adaptee_params': normalized_adaptee_params,
'params': params,
})
if rettype != 'void':
self.b("""\
return %(rettype)s();
""" % {'rettype': rettype})
else:
self.b("""\
return;
""")
self.b("""\
}
%(name)sContextPtr ctx = %(name)sContextPtr(
new Tp::MethodInvocationContext< %(outargtypes)s >(dbusConnection(), dbusMessage));
""" % {'name': name,
'outargtypes': outargtypes,
})
if invokemethodargs:
self.b("""\
QMetaObject::invokeMethod(adaptee(), "%(adaptee_name)s",
%(invokemethodargs)s,
Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx));
""" % {'namespace': self.namespace,
'ifacename': ifacename,
'name': name,
'adaptee_name': adaptee_name,
'invokemethodargs': invokemethodargs,
})
else:
self.b("""\
QMetaObject::invokeMethod(adaptee(), "%(lname)s",
Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx));
""" % {'namespace': self.namespace,
'ifacename': ifacename,
'name': name,
'lname': (name[0].lower() + name[1:]),
})
if rettype != 'void':
self.b("""\
return %(rettype)s();
""" % {'rettype': rettype})
self.b("}\n")
def do_signal(self, signal):
name = signal.getAttribute('name')
adaptee_name = to_lower_camel_case(signal.getAttribute('tp:name-for-bindings'))
argnames, argdocstrings, argbindings = extract_arg_or_member_info(get_by_path(signal,
'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
params = ', '.join(['%s %s' % (binding.inarg, param_name) for binding, param_name in zip(argbindings, argnames)])
for i in xrange(len(argnames)):
assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name)
self.h("""\
/**
* Represents the exported D-Bus signal \\c %(name)s on this object.
*
* Adaptees should export this signal as a Qt signal with the following signature:
* void %(adaptee_name)s(%(params)s);
*
* The adaptee signal will be automatically relayed as a D-Bus signal once emitted.
*
""" % {'name': name,
'adaptee_name': adaptee_name,
'params': params
})
for i in xrange(len(argnames)):
assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name)
if argdocstrings[i]:
self.h("""\
* \\param %s
%s\
""" % (argnames[i], argdocstrings[i]))
self.h("""\
*/
void %(name)s(%(params)s);
""" % {'name': name,
'params': params
})
def do_signals_connect(self, signals):
for signal in signals:
name = signal.getAttribute('name')
adaptee_name = to_lower_camel_case(signal.getAttribute('tp:name-for-bindings'))
_, _, argbindings = extract_arg_or_member_info(get_by_path(signal, 'arg'),
self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ')
self.b("""\
connect(adaptee, SIGNAL(%(adaptee_name)s(%(params)s)), SIGNAL(%(name)s(%(params)s)));
""" % {'name': name,
'adaptee_name': adaptee_name,
'params': ', '.join([binding.inarg for binding in argbindings])
})
def h(self, str):
self.hs.append(str)
def b(self, str):
self.bs.append(str)
def hb(self, str):
self.h(str)
self.b(str)
if __name__ == '__main__':
options, argv = gnu_getopt(argv[1:], '',
['group=',
'headerfile=',
'implfile=',
'namespace=',
'typesnamespace=',
'realinclude=',
'mocinclude=',
'prettyinclude=',
'extraincludes=',
'must-define=',
'visibility=',
'ifacexml=',
'specxml='])
Generator(dict(options))()
telepathy-qt-0.9.6~git1/tools/libtpcodegen.py 0000664 0001750 0001750 00000014722 12470405660 017127 0 ustar jr jr """Library code for language-independent D-Bus-related code generation.
The master copy of this library is in the telepathy-glib repository -
please make any changes there.
"""
# Copyright (C) 2006-2008 Collabora Limited
#
# 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
from string import ascii_letters, digits
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
_ASCII_ALNUM = ascii_letters + digits
def cmp_by_name(node1, node2):
return cmp(node1.getAttributeNode("name").nodeValue,
node2.getAttributeNode("name").nodeValue)
def escape_as_identifier(identifier):
"""Escape the given string to be a valid D-Bus object path or service
name component, using a reversible encoding to ensure uniqueness.
The reversible encoding is as follows:
* The empty string becomes '_'
* Otherwise, each non-alphanumeric character is replaced by '_' plus
two lower-case hex digits; the same replacement is carried out on
the first character, if it's a digit
"""
# '' -> '_'
if not identifier:
return '_'
# A bit of a fast path for strings which are already OK.
# We deliberately omit '_' because, for reversibility, that must also
# be escaped.
if (identifier.strip(_ASCII_ALNUM) == '' and
identifier[0] in ascii_letters):
return identifier
# The first character may not be a digit
if identifier[0] not in ascii_letters:
ret = ['_%02x' % ord(identifier[0])]
else:
ret = [identifier[0]]
# Subsequent characters may be digits or ASCII letters
for c in identifier[1:]:
if c in _ASCII_ALNUM:
ret.append(c)
else:
ret.append('_%02x' % ord(c))
return ''.join(ret)
def get_by_path(element, path):
branches = path.split('/')
branch = branches[0]
# Is the current branch an attribute, if so, return the attribute value
if branch[0] == '@':
return element.getAttribute(branch[1:])
# Find matching children for the branch
children = []
if branch == '..':
children.append(element.parentNode)
else:
for x in element.childNodes:
if x.localName == branch:
children.append(x)
ret = []
# If this is not the last path element, recursively gather results from
# children
if len(branches) > 1:
for x in children:
add = get_by_path(x, '/'.join(branches[1:]))
if isinstance(add, list):
ret += add
else:
return add
else:
ret = children
return ret
def get_docstring(element):
docstring = None
for x in element.childNodes:
if x.namespaceURI == NS_TP and x.localName == 'docstring':
docstring = x
if docstring is not None:
docstring = docstring.toxml().replace('\n', ' ').strip()
if docstring.startswith(''):
docstring = docstring[14:].lstrip()
if docstring.endswith(''):
docstring = docstring[:-15].rstrip()
if docstring in ('', ''):
docstring = ''
return docstring
def get_deprecated(element):
text = []
for x in element.childNodes:
if hasattr(x, 'data'):
text.append(x.data.replace('\n', ' ').strip())
else:
# This caters for tp:dbus-ref elements, but little else.
if x.childNodes and hasattr(x.childNodes[0], 'data'):
text.append(x.childNodes[0].data.replace('\n', ' ').strip())
return ' '.join(text)
def get_descendant_text(element_or_elements):
if not element_or_elements:
return ''
if isinstance(element_or_elements, list):
return ''.join(map(get_descendant_text, element_or_elements))
parts = []
for x in element_or_elements.childNodes:
if x.nodeType == x.TEXT_NODE:
parts.append(x.nodeValue)
elif x.nodeType == x.ELEMENT_NODE:
parts.append(get_descendant_text(x))
else:
pass
return ''.join(parts)
class _SignatureIter:
"""Iterator over a D-Bus signature. Copied from dbus-python 0.71 so we
can run genginterface in a limited environment with only Python
(like Scratchbox).
"""
def __init__(self, string):
self.remaining = string
def next(self):
if self.remaining == '':
raise StopIteration
signature = self.remaining
block_depth = 0
block_type = None
end = len(signature)
for marker in range(0, end):
cur_sig = signature[marker]
if cur_sig == 'a':
pass
elif cur_sig == '{' or cur_sig == '(':
if block_type == None:
block_type = cur_sig
if block_type == cur_sig:
block_depth = block_depth + 1
elif cur_sig == '}':
if block_type == '{':
block_depth = block_depth - 1
if block_depth == 0:
end = marker
break
elif cur_sig == ')':
if block_type == '(':
block_depth = block_depth - 1
if block_depth == 0:
end = marker
break
else:
if block_depth == 0:
end = marker
break
end = end + 1
self.remaining = signature[end:]
return Signature(signature[0:end])
class Signature(str):
"""A string, iteration over which is by D-Bus single complete types
rather than characters.
"""
def __iter__(self):
return _SignatureIter(self)
def xml_escape(s):
s = s.replace('&', '&').replace("'", ''').replace('"', '"')
return s.replace('<', '<').replace('>', '>')
telepathy-qt-0.9.6~git1/tools/libqtcodegen.py 0000664 0001750 0001750 00000041266 12470405660 017133 0 ustar jr jr """Library code for Qt D-Bus-related code generation.
The master copy of this library is in the telepathy-qt repository -
please make any changes there.
"""
# Copyright (C) 2008 Collabora Limited
# Copyright (C) 2008 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 St, Fifth Floor, Boston, MA 02110-1301 USA
from sys import maxint, stderr
import re
from libtpcodegen import get_by_path, get_descendant_text, NS_TP, xml_escape
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])
class _QtTypeBinding:
def __init__(self, val, inarg, outarg, array_val, custom_type, array_of,
array_depth=None):
self.val = val
self.inarg = inarg
self.outarg = outarg
self.array_val = array_val
self.custom_type = custom_type
self.array_of = array_of
self.array_depth = array_depth
if array_depth is None:
self.array_depth = int(bool(array_val))
elif array_depth >= 1:
assert array_val
else:
assert not array_val
class RefTarget(object):
KIND_INTERFACE, KIND_METHOD, KIND_SIGNAL, KIND_PROPERTY = 'node', 'method', 'signal', 'property'
def __init__(self, el):
self.kind = el.localName
assert self.kind in (self.KIND_INTERFACE, self.KIND_METHOD, self.KIND_SIGNAL, self.KIND_PROPERTY)
if self.kind == self.KIND_INTERFACE:
self.dbus_text = el.getAttribute('name').lstrip('/').replace('_', '') + 'Interface'
else:
self.member_text = el.getAttribute('name')
assert el.parentNode.parentNode.localName == self.KIND_INTERFACE
host_class = el.parentNode.parentNode.getAttribute('name').lstrip('/').replace('_', '') + 'Interface'
if self.kind == self.KIND_PROPERTY:
self.member_link = 'requestProperty%s()' % (self.member_text)
self.dbus_link = '%s::%s' % (host_class, self.member_link)
else:
self.member_text = '%s()' % self.member_text
self.dbus_text = '%s::%s' % (host_class, self.member_text)
class RefRegistry(object):
def __init__(self, spec):
self.targets = {}
for node in spec.getElementsByTagName('node'):
iface, = get_by_path(node, 'interface')
iface_name = iface.getAttribute('name')
self.targets[iface_name] = RefTarget(node)
for method in iface.getElementsByTagName(RefTarget.KIND_METHOD):
self.targets[iface_name + '.' + method.getAttribute('name')] = RefTarget(method)
for signal in iface.getElementsByTagName(RefTarget.KIND_SIGNAL):
self.targets[iface_name + '.' + signal.getAttribute('name')] = RefTarget(signal)
for prop in iface.getElementsByTagName(RefTarget.KIND_PROPERTY):
self.targets[iface_name + '.' + prop.getAttribute('name')] = RefTarget(prop)
def process(self, ref):
assert ref.namespaceURI == NS_TP
def get_closest_parent(el, needle):
node = el
while node is not None and node.localName != needle:
node = node.parentNode
return node
local = get_descendant_text(ref).strip()
if ref.localName == 'member-ref':
ns = get_closest_parent(ref, 'interface').getAttribute('name')
path = ns + '.' + local.strip()
else:
if ref.hasAttribute('namespace'):
ns = ref.getAttribute('namespace').replace('ofdT', 'org.freedesktop.Telepathy')
path = ns + '.' + local.strip()
else:
path = local
target = self.targets.get(path)
if target is None:
parent = get_closest_parent(ref, 'interface') or get_closest_parent(ref, 'error')
parent_name = parent.getAttribute('name')
if (path + parent_name).find('.DRAFT') == -1 and (path + parent_name).find('.FUTURE') == -1:
print >> stderr, 'WARNING: Failed to resolve %s to "%s" in "%s"' % (
ref.localName, path, parent_name)
return path
if ref.localName == 'member-ref':
if target.kind == target.KIND_PROPERTY:
return '\\link %s %s \\endlink' % (target.member_link, target.member_text)
else:
return target.member_text
else:
if target.kind == target.KIND_PROPERTY:
return '\\link %s %s \\endlink' % (target.dbus_link, target.dbus_text)
else:
return target.dbus_text
def binding_from_usage(sig, tptype, custom_lists, external=False, explicit_own_ns=None):
# 'signature' : ('qt-type', 'pass-by-reference', 'array-type')
natives = {
'y' : ('uchar', False, None),
'b' : ('bool', False, 'BoolList'),
'n' : ('short', False, 'ShortList'),
'q' : ('ushort', False, 'UShortList'),
'i' : ('int', False, 'IntList'),
'u' : ('uint', False, 'UIntList'),
'x' : ('qlonglong', False, 'LongLongList'),
't' : ('qulonglong', False, 'ULongLongList'),
'd' : ('double', False, 'DoubleList'),
's' : ('QString', True, None),
'v' : ('QDBusVariant', True, None),
'o' : ('QDBusObjectPath', True, 'ObjectPathList'),
'g' : ('QDBusSignature', True, 'SignatureList'),
'as' : ('QStringList', True, "StringListList"),
'ay' : ('QByteArray', True, "ByteArrayList"),
'av' : ('QVariantList', True, "VariantListList"),
'a{sv}' : ('QVariantMap', True, None)
}
val, inarg = None, None
custom_type = False
array_of = None
if natives.has_key(sig):
typename, pass_by_ref, array_name = natives[sig]
val = typename
inarg = (pass_by_ref and ('const %s&' % val)) or val
elif sig[0] == 'a' and natives.has_key(sig[1:]) and natives[sig[1:]][2]:
val = natives[sig[1:]][2]
if explicit_own_ns:
val = explicit_own_ns + '::' + val
inarg = 'const %s&' % val
array_of = natives[sig[1:]][0]
elif tptype:
tptype = tptype.replace('_', '')
custom_type = True
if external:
tptype = 'Tp::' + tptype
elif explicit_own_ns:
tptype = explicit_own_ns + '::' + tptype
if tptype.endswith('[]'):
tptype = tptype[:-2]
extra_list_nesting = 0
while tptype.endswith('[]'):
extra_list_nesting += 1
tptype = tptype[:-2]
assert custom_lists.has_key(tptype), ('No array version of custom type %s in the spec, but array version used' % tptype)
val = custom_lists[tptype] + 'List' * extra_list_nesting
else:
val = tptype
inarg = 'const %s&' % val
else:
assert False, 'Don\'t know how to map type (%s, %s)' % (sig, tptype)
outarg = val + '&'
return _QtTypeBinding(val, inarg, outarg, None, custom_type, array_of)
def binding_from_decl(name, array_name, array_depth=None, external=False, explicit_own_ns=''):
val = name.replace('_', '')
if external:
val = 'Tp::' + val
elif explicit_own_ns:
val = explicit_own_ns + '::' + val
inarg = 'const %s&' % val
outarg = '%s&' % val
return _QtTypeBinding(val, inarg, outarg, array_name.replace('_', ''), True, None, array_depth)
def extract_arg_or_member_info(els, custom_lists, externals, typesns, refs, docstring_indent=' * ', docstring_brackets=None, docstring_maxwidth=80):
names = []
docstrings = []
bindings = []
for el in els:
names.append(get_qt_name(el))
docstrings.append(format_docstring(el, refs, docstring_indent, docstring_brackets, docstring_maxwidth))
sig = el.getAttribute('type')
tptype = el.getAttributeNS(NS_TP, 'type')
bindings.append(binding_from_usage(sig, tptype, custom_lists, (sig, tptype) in externals, typesns))
return names, docstrings, bindings
def format_docstring(el, refs, indent=' * ', brackets=None, maxwidth=80):
docstring_el = None
for x in el.childNodes:
if x.namespaceURI == NS_TP and x.localName == 'docstring':
docstring_el = x
if not docstring_el:
return ''
lines = []
# escape backslashes, so they won't be interpreted starting doxygen commands and we can later
# insert doxygen commands we actually want
def escape_slashes(x):
if x.nodeType == x.TEXT_NODE:
x.data = x.data.replace('\\', '\\\\')
elif x.nodeType == x.ELEMENT_NODE:
for y in x.childNodes:
escape_slashes(y)
else:
return
escape_slashes(docstring_el)
doc = docstring_el.ownerDocument
for n in docstring_el.getElementsByTagNameNS(NS_TP, 'rationale'):
nested = n.getElementsByTagNameNS(NS_TP, 'rationale')
if nested:
raise Xzibit(n, nested[0])
div = doc.createElement('div')
div.setAttribute('class', 'rationale')
for rationale_body in n.childNodes:
div.appendChild(rationale_body.cloneNode(True))
n.parentNode.replaceChild(div, n)
if docstring_el.getAttribute('xmlns') == 'http://www.w3.org/1999/xhtml':
for ref in docstring_el.getElementsByTagNameNS(NS_TP, 'member-ref') + docstring_el.getElementsByTagNameNS(NS_TP, 'dbus-ref'):
nested = ref.getElementsByTagNameNS(NS_TP, 'member-ref') + ref.getElementsByTagNameNS(NS_TP, 'dbus-ref')
if nested:
raise Xzibit(n, nested[0])
text = doc.createTextNode(' \\endhtmlonly ')
text.data += refs.process(ref)
text.data += ' \\htmlonly '
ref.parentNode.replaceChild(text, ref)
splitted = ''.join([el.toxml() for el in docstring_el.childNodes]).strip(' ').strip('\n').split('\n')
level = min([not match and maxint or match.end() - 1 for match in [re.match('^ *[^ ]', line) for line in splitted]])
assert level != maxint
lines = ['\\htmlonly'] + [line[level:] for line in splitted] + ['\\endhtmlonly']
else:
content = xml_escape(get_descendant_text(docstring_el).replace('\n', ' ').strip())
while content.find(' ') != -1:
content = content.replace(' ', ' ')
left = maxwidth - len(indent) - 1
line = ''
while content:
step = (content.find(' ') + 1) or len(content)
if step > left:
lines.append(line)
line = ''
left = maxwidth - len(indent) - 1
left = left - step
line = line + content[:step]
content = content[step:]
if line:
lines.append(line)
output = []
if lines:
if brackets:
output.append(brackets[0])
else:
output.append(indent)
output.append('\n')
for line in lines:
output.append(indent)
output.append(line)
output.append('\n')
if lines and brackets:
output.append(brackets[1])
output.append('\n')
return ''.join(output)
def gather_externals(spec):
externals = []
for ext in spec.getElementsByTagNameNS(NS_TP, 'external-type'):
sig = ext.getAttribute('type')
tptype = ext.getAttribute('name')
externals.append((sig, tptype))
return externals
def gather_custom_lists(spec, typesns):
custom_lists = {}
structs = [(provider, typesns) for provider in spec.getElementsByTagNameNS(NS_TP, 'struct')]
mappings = [(provider, typesns) for provider in spec.getElementsByTagNameNS(NS_TP, 'mapping')]
exts = [(provider, 'Telepathy') for provider in spec.getElementsByTagNameNS(NS_TP, 'external-type')]
for (provider, ns) in structs + mappings + exts:
tptype = provider.getAttribute('name').replace('_', '')
array_val = provider.getAttribute('array-name').replace('_', '')
array_depth = provider.getAttribute('array-depth')
if array_depth:
array_depth = int(array_depth)
else:
array_depth = None
if array_val:
custom_lists[tptype] = array_val
custom_lists[ns + '::' + tptype] = ns + '::' + array_val
if array_depth >= 2:
for i in xrange(array_depth):
custom_lists[tptype + ('[]' * (i+1))] = (
array_val + ('List' * i))
custom_lists[ns + '::' + tptype + ('[]' * (i+1))] = (
ns + '::' + array_val + ('List' * i))
return custom_lists
def get_headerfile_cmd(realinclude, prettyinclude, indent=' * '):
prettyinclude = prettyinclude or realinclude
if realinclude:
if prettyinclude:
return indent + ('\\headerfile %s <%s>\n' % (realinclude, prettyinclude))
else:
return indent + ('\\headerfile %s <%s>\n' % (realinclude))
else:
return ''
def get_qt_name(el):
name = el.getAttribute('name')
if el.localName in ('method', 'signal', 'property'):
bname = el.getAttributeNS(NS_TP, 'name-for-bindings')
if bname:
name = bname
if not name:
return None
if name[0].isupper() and name[1].islower():
name = name[0].lower() + name[1:]
return qt_identifier_escape(name.replace('_', ''))
def qt_identifier_escape(str):
built = (str[0].isdigit() and ['_']) or []
for c in str:
if c.isalnum():
built.append(c)
else:
built.append('_')
str = ''.join(built)
# List of reserved identifiers
# Initial list from http://cs.smu.ca/~porter/csc/ref/cpp_keywords.html
# Keywords inherited from C90
reserved = ['auto',
'const',
'double',
'float',
'int',
'short',
'struct',
'unsigned',
'break',
'continue',
'else',
'for',
'long',
'signed',
'switch',
'void',
'case',
'default',
'enum',
'goto',
'register',
'sizeof',
'typedef',
'volatile',
'char',
'do',
'extern',
'if',
'return',
'static',
'union',
'while',
# C++-only keywords
'asm',
'dynamic_cast',
'namespace',
'reinterpret_cast',
'try',
'bool',
'explicit',
'new',
'static_cast',
'typeid',
'catch',
'false',
'operator',
'template',
'typename',
'class',
'friend',
'private',
'this',
'using',
'const_cast',
'inline',
'public',
'throw',
'virtual',
'delete',
'mutable',
'protected',
'true',
'wchar_t',
# Operator replacements
'and',
'bitand',
'compl',
'not_eq',
'or_eq',
'xor_eq',
'and_eq',
'bitor',
'not',
'or',
'xor',
# Predefined identifiers
'INT_MIN',
'INT_MAX',
'MAX_RAND',
'NULL',
# Qt
'SIGNAL',
'SLOT',
'signals',
'slots']
while str in reserved:
str = str + '_'
return str
telepathy-qt-0.9.6~git1/tools/glib-signals-marshal-gen.py 0000664 0001750 0001750 00000002541 12470405660 021233 0 ustar jr jr #!/usr/bin/python
import sys
import xml.dom.minidom
from string import ascii_letters, digits
from libglibcodegen import signal_to_marshal_name, method_to_glue_marshal_name
class Generator(object):
def __init__(self, dom):
self.dom = dom
self.marshallers = {}
def do_method(self, method):
marshaller = method_to_glue_marshal_name(method, 'PREFIX')
assert '__' in marshaller
rhs = marshaller.split('__', 1)[1].split('_')
self.marshallers[marshaller] = rhs
def do_signal(self, signal):
marshaller = signal_to_marshal_name(signal, 'PREFIX')
assert '__' in marshaller
rhs = marshaller.split('__', 1)[1].split('_')
self.marshallers[marshaller] = rhs
def __call__(self):
methods = self.dom.getElementsByTagName('method')
for method in methods:
self.do_method(method)
signals = self.dom.getElementsByTagName('signal')
for signal in signals:
self.do_signal(signal)
all = self.marshallers.keys()
all.sort()
for marshaller in all:
rhs = self.marshallers[marshaller]
if not marshaller.startswith('g_cclosure'):
print 'VOID:' + ','.join(rhs)
if __name__ == '__main__':
argv = sys.argv[1:]
dom = xml.dom.minidom.parse(argv[0])
Generator(dom)()
telepathy-qt-0.9.6~git1/tools/glib-ginterface-gen.py 0000664 0001750 0001750 00000072501 12470405660 020260 0 ustar jr jr #!/usr/bin/python
# glib-ginterface-gen.py: service-side interface generator
#
# Generate dbus-glib 0.x service GInterfaces from the Telepathy specification.
# The master copy of this program is in the telepathy-glib repository -
# please make any changes there.
#
# Copyright (C) 2006, 2007 Collabora Limited
#
# 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
import sys
import os.path
import xml.dom.minidom
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
NS_TP, dbus_gutils_wincaps_to_uscore, \
signal_to_marshal_name, method_to_glue_marshal_name
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
class Generator(object):
def __init__(self, dom, prefix, basename, signal_marshal_prefix,
headers, end_headers, not_implemented_func,
allow_havoc):
self.dom = dom
self.__header = []
self.__body = []
assert prefix.endswith('_')
assert not signal_marshal_prefix.endswith('_')
# The main_prefix, sub_prefix thing is to get:
# FOO_ -> (FOO_, _)
# FOO_SVC_ -> (FOO_, _SVC_)
# but
# FOO_BAR/ -> (FOO_BAR_, _)
# FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_)
if '/' in prefix:
main_prefix, sub_prefix = prefix.upper().split('/', 1)
prefix = prefix.replace('/', '_')
else:
main_prefix, sub_prefix = prefix.upper().split('_', 1)
self.MAIN_PREFIX_ = main_prefix + '_'
self._SUB_PREFIX_ = '_' + sub_prefix
self.Prefix_ = prefix
self.Prefix = prefix.replace('_', '')
self.prefix_ = prefix.lower()
self.PREFIX_ = prefix.upper()
self.basename = basename
self.signal_marshal_prefix = signal_marshal_prefix
self.headers = headers
self.end_headers = end_headers
self.not_implemented_func = not_implemented_func
self.allow_havoc = allow_havoc
def h(self, s):
self.__header.append(s)
def b(self, s):
self.__body.append(s)
def do_node(self, node):
node_name = node.getAttribute('name').replace('/', '')
node_name_mixed = self.node_name_mixed = node_name.replace('_', '')
node_name_lc = self.node_name_lc = node_name.lower()
node_name_uc = self.node_name_uc = node_name.upper()
interfaces = node.getElementsByTagName('interface')
assert len(interfaces) == 1, interfaces
interface = interfaces[0]
self.iface_name = interface.getAttribute('name')
tmp = interface.getAttribute('tp:implement-service')
if tmp == "no":
return
tmp = interface.getAttribute('tp:causes-havoc')
if tmp and not self.allow_havoc:
raise AssertionError('%s is %s' % (self.iface_name, tmp))
self.b('static const DBusGObjectInfo _%s%s_object_info;'
% (self.prefix_, node_name_lc))
self.b('')
methods = interface.getElementsByTagName('method')
signals = interface.getElementsByTagName('signal')
properties = interface.getElementsByTagName('property')
# Don't put properties in dbus-glib glue
glue_properties = []
self.b('struct _%s%sClass {' % (self.Prefix, node_name_mixed))
self.b(' GTypeInterface parent_class;')
for method in methods:
self.b(' %s %s;' % self.get_method_impl_names(method))
self.b('};')
self.b('')
if signals:
self.b('enum {')
for signal in signals:
self.b(' %s,' % self.get_signal_const_entry(signal))
self.b(' N_%s_SIGNALS' % node_name_uc)
self.b('};')
self.b('static guint %s_signals[N_%s_SIGNALS] = {0};'
% (node_name_lc, node_name_uc))
self.b('')
self.b('static void %s%s_base_init (gpointer klass);'
% (self.prefix_, node_name_lc))
self.b('')
self.b('GType')
self.b('%s%s_get_type (void)'
% (self.prefix_, node_name_lc))
self.b('{')
self.b(' static GType type = 0;')
self.b('')
self.b(' if (G_UNLIKELY (type == 0))')
self.b(' {')
self.b(' static const GTypeInfo info = {')
self.b(' sizeof (%s%sClass),' % (self.Prefix, node_name_mixed))
self.b(' %s%s_base_init, /* base_init */'
% (self.prefix_, node_name_lc))
self.b(' NULL, /* base_finalize */')
self.b(' NULL, /* class_init */')
self.b(' NULL, /* class_finalize */')
self.b(' NULL, /* class_data */')
self.b(' 0,')
self.b(' 0, /* n_preallocs */')
self.b(' NULL /* instance_init */')
self.b(' };')
self.b('')
self.b(' type = g_type_register_static (G_TYPE_INTERFACE,')
self.b(' "%s%s", &info, 0);' % (self.Prefix, node_name_mixed))
self.b(' }')
self.b('')
self.b(' return type;')
self.b('}')
self.b('')
self.h('/**')
self.h(' * %s%s:' % (self.Prefix, node_name_mixed))
self.h(' *')
self.h(' * Dummy typedef representing any implementation of this '
'interface.')
self.h(' */')
self.h('typedef struct _%s%s %s%s;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
self.h('')
self.h('/**')
self.h(' * %s%sClass:' % (self.Prefix, node_name_mixed))
self.h(' *')
self.h(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
if methods:
self.h(' *')
self.h(' * In a full implementation of this interface (i.e. all')
self.h(' * methods implemented), the interface initialization')
self.h(' * function used in G_IMPLEMENT_INTERFACE() would')
self.h(' * typically look like this:')
self.h(' *')
self.h(' * ')
self.h(' * static void')
self.h(' * implement_%s (gpointer klass,' % self.node_name_lc)
self.h(' * gpointer unused G_GNUC_UNUSED)')
self.h(' * {')
# "#" is special to gtkdoc under some circumstances; it appears
# that escaping "##" as "##" or "##" doesn't work,
# but adding an extra hash symbol does. Thanks, gtkdoc :-(
self.h(' * #define IMPLEMENT(x) %s%s_implement_###x (\\'
% (self.prefix_, self.node_name_lc))
self.h(' * klass, my_object_###x)')
for method in methods:
class_member_name = method.getAttribute('tp:name-for-bindings')
class_member_name = class_member_name.lower()
self.h(' * IMPLEMENT (%s);' % class_member_name)
self.h(' * #undef IMPLEMENT')
self.h(' * }')
self.h(' * ')
else:
self.h(' * This interface has no D-Bus methods, so an')
self.h(' * implementation can typically pass %NULL to')
self.h(' * G_IMPLEMENT_INTERFACE() as the interface')
self.h(' * initialization function.')
self.h(' */')
self.h('typedef struct _%s%sClass %s%sClass;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
self.h('')
self.h('GType %s%s_get_type (void);'
% (self.prefix_, node_name_lc))
gtype = self.current_gtype = \
self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc
classname = self.Prefix + node_name_mixed
self.h('#define %s \\\n (%s%s_get_type ())'
% (gtype, self.prefix_, node_name_lc))
self.h('#define %s%s(obj) \\\n'
' (G_TYPE_CHECK_INSTANCE_CAST((obj), %s, %s))'
% (self.PREFIX_, node_name_uc, gtype, classname))
self.h('#define %sIS%s%s(obj) \\\n'
' (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))'
% (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype))
self.h('#define %s%s_GET_CLASS(obj) \\\n'
' (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))'
% (self.PREFIX_, node_name_uc, gtype, classname))
self.h('')
self.h('')
base_init_code = []
for method in methods:
self.do_method(method)
for signal in signals:
base_init_code.extend(self.do_signal(signal))
self.b('static inline void')
self.b('%s%s_base_init_once (gpointer klass G_GNUC_UNUSED)'
% (self.prefix_, node_name_lc))
self.b('{')
if properties:
self.b(' static TpDBusPropertiesMixinPropInfo properties[%d] = {'
% (len(properties) + 1))
for m in properties:
access = m.getAttribute('access')
assert access in ('read', 'write', 'readwrite')
if access == 'read':
flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ'
elif access == 'write':
flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE'
else:
flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
% (flags, m.getAttribute('type'), m.getAttribute('name')))
self.b(' { 0, 0, NULL, 0, NULL, NULL }')
self.b(' };')
self.b(' static TpDBusPropertiesMixinIfaceInfo interface =')
self.b(' { 0, properties, NULL, NULL };')
self.b('')
self.b(' dbus_g_object_type_install_info (%s%s_get_type (),'
% (self.prefix_, node_name_lc))
self.b(' &_%s%s_object_info);'
% (self.prefix_, node_name_lc))
self.b('')
if properties:
self.b(' interface.dbus_interface = g_quark_from_static_string '
'("%s");' % self.iface_name)
for i, m in enumerate(properties):
self.b(' properties[%d].name = g_quark_from_static_string ("%s");'
% (i, m.getAttribute('name')))
self.b(' properties[%d].type = %s;'
% (i, type_to_gtype(m.getAttribute('type'))[1]))
self.b(' tp_svc_interface_set_dbus_properties_info (%s, &interface);'
% self.current_gtype)
self.b('')
for s in base_init_code:
self.b(s)
self.b('}')
self.b('static void')
self.b('%s%s_base_init (gpointer klass)'
% (self.prefix_, node_name_lc))
self.b('{')
self.b(' static gboolean initialized = FALSE;')
self.b('')
self.b(' if (!initialized)')
self.b(' {')
self.b(' initialized = TRUE;')
self.b(' %s%s_base_init_once (klass);'
% (self.prefix_, node_name_lc))
self.b(' }')
# insert anything we need to do per implementation here
self.b('}')
self.h('')
self.b('static const DBusGMethodInfo _%s%s_methods[] = {'
% (self.prefix_, node_name_lc))
method_blob, offsets = self.get_method_glue(methods)
for method, offset in zip(methods, offsets):
self.do_method_glue(method, offset)
if len(methods) == 0:
# empty arrays are a gcc extension, so put in a dummy member
self.b(" { NULL, NULL, 0 }")
self.b('};')
self.b('')
self.b('static const DBusGObjectInfo _%s%s_object_info = {'
% (self.prefix_, node_name_lc))
self.b(' 0,') # version
self.b(' _%s%s_methods,' % (self.prefix_, node_name_lc))
self.b(' %d,' % len(methods))
self.b('"' + method_blob.replace('\0', '\\0') + '",')
self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",')
self.b('"' +
self.get_property_glue(glue_properties).replace('\0', '\\0') +
'",')
self.b('};')
self.b('')
self.node_name_mixed = None
self.node_name_lc = None
self.node_name_uc = None
def get_method_glue(self, methods):
info = []
offsets = []
for method in methods:
offsets.append(len(''.join(info)))
info.append(self.iface_name + '\0')
info.append(method.getAttribute('name') + '\0')
info.append('A\0') # async
counter = 0
for arg in method.getElementsByTagName('arg'):
out = arg.getAttribute('direction') == 'out'
name = arg.getAttribute('name')
if not name:
assert out
name = 'arg%u' % counter
counter += 1
info.append(name + '\0')
if out:
info.append('O\0')
else:
info.append('I\0')
if out:
info.append('F\0') # not const
info.append('N\0') # not error or return
info.append(arg.getAttribute('type') + '\0')
info.append('\0')
return ''.join(info) + '\0', offsets
def do_method_glue(self, method, offset):
lc_name = method.getAttribute('tp:name-for-bindings')
if method.getAttribute('name') != lc_name.replace('_', ''):
raise AssertionError('Method %s tp:name-for-bindings (%s) does '
'not match' % (method.getAttribute('name'), lc_name))
lc_name = lc_name.lower()
marshaller = method_to_glue_marshal_name(method,
self.signal_marshal_prefix)
wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name
self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset))
def get_signal_glue(self, signals):
info = []
for signal in signals:
info.append(self.iface_name)
info.append(signal.getAttribute('name'))
return '\0'.join(info) + '\0\0'
# the implementation can be the same
get_property_glue = get_signal_glue
def get_method_impl_names(self, method):
dbus_method_name = method.getAttribute('name')
class_member_name = method.getAttribute('tp:name-for-bindings')
if dbus_method_name != class_member_name.replace('_', ''):
raise AssertionError('Method %s tp:name-for-bindings (%s) does '
'not match' % (dbus_method_name, class_member_name))
class_member_name = class_member_name.lower()
stub_name = (self.prefix_ + self.node_name_lc + '_' +
class_member_name)
return (stub_name + '_impl', class_member_name)
def do_method(self, method):
assert self.node_name_mixed is not None
in_class = []
# Examples refer to Thing.DoStuff (su) -> ii
# DoStuff
dbus_method_name = method.getAttribute('name')
# do_stuff
class_member_name = method.getAttribute('tp:name-for-bindings')
if dbus_method_name != class_member_name.replace('_', ''):
raise AssertionError('Method %s tp:name-for-bindings (%s) does '
'not match' % (dbus_method_name, class_member_name))
class_member_name = class_member_name.lower()
# void tp_svc_thing_do_stuff (TpSvcThing *, const char *, guint,
# DBusGMethodInvocation *);
stub_name = (self.prefix_ + self.node_name_lc + '_' +
class_member_name)
# typedef void (*tp_svc_thing_do_stuff_impl) (TpSvcThing *,
# const char *, guint, DBusGMethodInvocation);
impl_name = stub_name + '_impl'
# void tp_svc_thing_return_from_do_stuff (DBusGMethodInvocation *,
# gint, gint);
ret_name = (self.prefix_ + self.node_name_lc + '_return_from_' +
class_member_name)
# Gather arguments
in_args = []
out_args = []
for i in method.getElementsByTagName('arg'):
name = i.getAttribute('name')
direction = i.getAttribute('direction') or 'in'
dtype = i.getAttribute('type')
assert direction in ('in', 'out')
if name:
name = direction + '_' + name
elif direction == 'in':
name = direction + str(len(in_args))
else:
name = direction + str(len(out_args))
ctype, gtype, marshaller, pointer = type_to_gtype(dtype)
if pointer:
ctype = 'const ' + ctype
struct = (ctype, name)
if direction == 'in':
in_args.append(struct)
else:
out_args.append(struct)
# Implementation type declaration (in header, docs in body)
self.b('/**')
self.b(' * %s:' % impl_name)
self.b(' * @self: The object implementing this interface')
for (ctype, name) in in_args:
self.b(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
self.b(' * @context: Used to return values or throw an error')
self.b(' *')
self.b(' * The signature of an implementation of the D-Bus method')
self.b(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
self.b(' */')
self.h('typedef void (*%s) (%s%s *self,'
% (impl_name, self.Prefix, self.node_name_mixed))
for (ctype, name) in in_args:
self.h(' %s%s,' % (ctype, name))
self.h(' DBusGMethodInvocation *context);')
# Class member (in class definition)
in_class.append(' %s %s;' % (impl_name, class_member_name))
# Stub definition (in body only - it's static)
self.b('static void')
self.b('%s (%s%s *self,'
% (stub_name, self.Prefix, self.node_name_mixed))
for (ctype, name) in in_args:
self.b(' %s%s,' % (ctype, name))
self.b(' DBusGMethodInvocation *context)')
self.b('{')
self.b(' %s impl = (%s%s_GET_CLASS (self)->%s);'
% (impl_name, self.PREFIX_, self.node_name_uc, class_member_name))
self.b('')
self.b(' if (impl != NULL)')
tmp = ['self'] + [name for (ctype, name) in in_args] + ['context']
self.b(' {')
self.b(' (impl) (%s);' % ',\n '.join(tmp))
self.b(' }')
self.b(' else')
self.b(' {')
if self.not_implemented_func:
self.b(' %s (context);' % self.not_implemented_func)
else:
self.b(' GError e = { DBUS_GERROR, ')
self.b(' DBUS_GERROR_UNKNOWN_METHOD,')
self.b(' "Method not implemented" };')
self.b('')
self.b(' dbus_g_method_return_error (context, &e);')
self.b(' }')
self.b('}')
self.b('')
# Implementation registration (in both header and body)
self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);'
% (self.prefix_, self.node_name_lc, class_member_name,
self.Prefix, self.node_name_mixed, impl_name))
self.b('/**')
self.b(' * %s%s_implement_%s:'
% (self.prefix_, self.node_name_lc, class_member_name))
self.b(' * @klass: A class whose instances implement this interface')
self.b(' * @impl: A callback used to implement the %s D-Bus method'
% dbus_method_name)
self.b(' *')
self.b(' * Register an implementation for the %s method in the vtable'
% dbus_method_name)
self.b(' * of an implementation of this interface. To be called from')
self.b(' * the interface init function.')
self.b(' */')
self.b('void')
self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)'
% (self.prefix_, self.node_name_lc, class_member_name,
self.Prefix, self.node_name_mixed, impl_name))
self.b('{')
self.b(' klass->%s = impl;' % class_member_name)
self.b('}')
self.b('')
# Return convenience function (static inline, in header)
self.h('/**')
self.h(' * %s:' % ret_name)
self.h(' * @context: The D-Bus method invocation context')
for (ctype, name) in out_args:
self.h(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
self.h(' *')
self.h(' * Return successfully by calling dbus_g_method_return().')
self.h(' * This inline function exists only to provide type-safety.')
self.h(' */')
tmp = (['DBusGMethodInvocation *context'] +
[ctype + name for (ctype, name) in out_args])
self.h('static inline')
self.h('/* this comment is to stop gtkdoc realising this is static */')
self.h(('void %s (' % ret_name) + (',\n '.join(tmp)) + ');')
self.h('static inline void')
self.h(('%s (' % ret_name) + (',\n '.join(tmp)) + ')')
self.h('{')
tmp = ['context'] + [name for (ctype, name) in out_args]
self.h(' dbus_g_method_return (' + ',\n '.join(tmp) + ');')
self.h('}')
self.h('')
return in_class
def get_signal_const_entry(self, signal):
assert self.node_name_uc is not None
return ('SIGNAL_%s_%s'
% (self.node_name_uc, signal.getAttribute('name')))
def do_signal(self, signal):
assert self.node_name_mixed is not None
in_base_init = []
# for signal: Thing::StuffHappened (s, u)
# we want to emit:
# void tp_svc_thing_emit_stuff_happened (gpointer instance,
# const char *arg0, guint arg1);
dbus_name = signal.getAttribute('name')
ugly_name = signal.getAttribute('tp:name-for-bindings')
if dbus_name != ugly_name.replace('_', ''):
raise AssertionError('Signal %s tp:name-for-bindings (%s) does '
'not match' % (dbus_name, ugly_name))
stub_name = (self.prefix_ + self.node_name_lc + '_emit_' +
ugly_name.lower())
const_name = self.get_signal_const_entry(signal)
# Gather arguments
args = []
for i in signal.getElementsByTagName('arg'):
name = i.getAttribute('name')
dtype = i.getAttribute('type')
tp_type = i.getAttribute('tp:type')
if name:
name = 'arg_' + name
else:
name = 'arg' + str(len(args))
ctype, gtype, marshaller, pointer = type_to_gtype(dtype)
if pointer:
ctype = 'const ' + ctype
struct = (ctype, name, gtype)
args.append(struct)
tmp = (['gpointer instance'] +
[ctype + name for (ctype, name, gtype) in args])
self.h(('void %s (' % stub_name) + (',\n '.join(tmp)) + ');')
# FIXME: emit docs
self.b('/**')
self.b(' * %s:' % stub_name)
self.b(' * @instance: The object implementing this interface')
for (ctype, name, gtype) in args:
self.b(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
self.b(' *')
self.b(' * Type-safe wrapper around g_signal_emit to emit the')
self.b(' * %s signal on interface %s.'
% (dbus_name, self.iface_name))
self.b(' */')
self.b('void')
self.b(('%s (' % stub_name) + (',\n '.join(tmp)) + ')')
self.b('{')
self.b(' g_assert (instance != NULL);')
self.b(' g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));'
% (self.current_gtype))
tmp = (['instance', '%s_signals[%s]' % (self.node_name_lc, const_name),
'0'] + [name for (ctype, name, gtype) in args])
self.b(' g_signal_emit (' + ',\n '.join(tmp) + ');')
self.b('}')
self.b('')
signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_',
'-')
in_base_init.append(' /**')
in_base_init.append(' * %s%s::%s:'
% (self.Prefix, self.node_name_mixed, signal_name))
for (ctype, name, gtype) in args:
in_base_init.append(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
in_base_init.append(' *')
in_base_init.append(' * The %s D-Bus signal is emitted whenever '
'this GObject signal is.' % dbus_name)
in_base_init.append(' */')
in_base_init.append(' %s_signals[%s] ='
% (self.node_name_lc, const_name))
in_base_init.append(' g_signal_new ("%s",' % signal_name)
in_base_init.append(' G_OBJECT_CLASS_TYPE (klass),')
in_base_init.append(' G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
in_base_init.append(' 0,')
in_base_init.append(' NULL, NULL,')
in_base_init.append(' %s,'
% signal_to_marshal_name(signal, self.signal_marshal_prefix))
in_base_init.append(' G_TYPE_NONE,')
tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
in_base_init.append(' %s);' % ',\n '.join(tmp))
in_base_init.append('')
return in_base_init
def have_properties(self, nodes):
for node in nodes:
interface = node.getElementsByTagName('interface')[0]
if interface.getElementsByTagName('property'):
return True
return False
def __call__(self):
nodes = self.dom.getElementsByTagName('node')
nodes.sort(cmp_by_name)
self.h('#include ')
self.h('#include ')
if self.have_properties(nodes):
self.h('#include ')
self.h('')
self.h('G_BEGIN_DECLS')
self.h('')
self.b('#include "%s.h"' % self.basename)
self.b('')
for header in self.headers:
self.b('#include %s' % header)
self.b('')
for node in nodes:
self.do_node(node)
self.h('')
self.h('G_END_DECLS')
self.b('')
for header in self.end_headers:
self.b('#include %s' % header)
self.h('')
self.b('')
open(self.basename + '.h', 'w').write('\n'.join(self.__header))
open(self.basename + '.c', 'w').write('\n'.join(self.__body))
def cmdline_error():
print """\
usage:
gen-ginterface [OPTIONS] xmlfile Prefix_
options:
--include='' (may be repeated)
--include='"header.h"' (ditto)
--include-end='"header.h"' (ditto)
Include extra headers in the generated .c file
--signal-marshal-prefix='prefix'
Use the given prefix on generated signal marshallers (default is
prefix.lower()).
--filename='BASENAME'
Set the basename for the output files (default is prefix.lower()
+ 'ginterfaces')
--not-implemented-func='symbol'
Set action when methods not implemented in the interface vtable are
called. symbol must have signature
void symbol (DBusGMethodInvocation *context)
and return some sort of "not implemented" error via
dbus_g_method_return_error (context, ...)
"""
sys.exit(1)
if __name__ == '__main__':
from getopt import gnu_getopt
options, argv = gnu_getopt(sys.argv[1:], '',
['filename=', 'signal-marshal-prefix=',
'include=', 'include-end=',
'allow-unstable',
'not-implemented-func='])
try:
prefix = argv[1]
except IndexError:
cmdline_error()
basename = prefix.lower() + 'ginterfaces'
signal_marshal_prefix = prefix.lower().rstrip('_')
headers = []
end_headers = []
not_implemented_func = ''
allow_havoc = False
for option, value in options:
if option == '--filename':
basename = value
elif option == '--signal-marshal-prefix':
signal_marshal_prefix = value
elif option == '--include':
if value[0] not in '<"':
value = '"%s"' % value
headers.append(value)
elif option == '--include-end':
if value[0] not in '<"':
value = '"%s"' % value
end_headers.append(value)
elif option == '--not-implemented-func':
not_implemented_func = value
elif option == '--allow-unstable':
allow_havoc = True
try:
dom = xml.dom.minidom.parse(argv[0])
except IndexError:
cmdline_error()
Generator(dom, prefix, basename, signal_marshal_prefix, headers,
end_headers, not_implemented_func, allow_havoc)()
telepathy-qt-0.9.6~git1/tools/with-session-bus.sh 0000664 0001750 0001750 00000004274 12470405660 017676 0 ustar jr jr #!/bin/sh
# with-session-bus.sh - run a program with a temporary D-Bus session daemon
#
# The canonical location of this program is the telepathy-glib tools/
# directory, please synchronize any changes with that copy.
#
# Copyright (C) 2007-2008 Collabora Ltd.
#
# 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.
set -e
me=with-session-bus
dbus_daemon_args="--print-address=5 --print-pid=6 --fork"
sleep=0
usage ()
{
echo "usage: $me [options] -- program [program_options]" >&2
echo "Requires write access to the current directory." >&2
echo "" >&2
echo "If \$WITH_SESSION_BUS_FORK_DBUS_MONITOR is set, fork dbus-monitor" >&2
echo "with the arguments in \$WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT." >&2
echo "The output of dbus-monitor is saved in $me-.dbus-monitor-logs" >&2
exit 2
}
while test "z$1" != "z--"; do
case "$1" in
--sleep=*)
sleep="$1"
sleep="${sleep#--sleep=}"
shift
;;
--session)
dbus_daemon_args="$dbus_daemon_args --session"
shift
;;
--config-file=*)
# FIXME: assumes config file doesn't contain any special characters
dbus_daemon_args="$dbus_daemon_args $1"
shift
;;
*)
usage
;;
esac
done
shift
if test "z$1" = "z"; then usage; fi
exec 5> $me-$$.address
exec 6> $me-$$.pid
cleanup ()
{
pid=`head -n1 $me-$$.pid`
if test -n "$pid" ; then
echo "Killing temporary bus daemon: $pid" >&2
kill -INT "$pid"
fi
rm -f $me-$$.address
rm -f $me-$$.pid
}
trap cleanup INT HUP TERM
dbus-daemon $dbus_daemon_args
{ echo -n "Temporary bus daemon is "; cat $me-$$.address; } >&2
{ echo -n "Temporary bus daemon PID is "; head -n1 $me-$$.pid; } >&2
e=0
DBUS_SESSION_BUS_ADDRESS="`cat $me-$$.address`"
export DBUS_SESSION_BUS_ADDRESS
if [ -n "$WITH_SESSION_BUS_FORK_DBUS_MONITOR" ] ; then
echo -n "Forking dbus-monitor $WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT" >&2
dbus-monitor $WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT \
> $me-$$.dbus-monitor-logs 2>&1 &
fi
"$@" || e=$?
if test $sleep != 0; then
sleep $sleep
fi
trap - INT HUP TERM
cleanup
exit $e
telepathy-qt-0.9.6~git1/tools/xincludator.py 0000664 0001750 0001750 00000002413 12470405660 017016 0 ustar jr jr #!/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')
telepathy-qt-0.9.6~git1/cmake/ 0000775 0001750 0001750 00000000000 12470405660 014030 5 ustar jr jr telepathy-qt-0.9.6~git1/cmake/modules/ 0000775 0001750 0001750 00000000000 12470405660 015500 5 ustar jr jr telepathy-qt-0.9.6~git1/cmake/modules/FindGObject.cmake 0000664 0001750 0001750 00000004271 12470405660 020624 0 ustar jr jr # - Try to find GObject
# Once done this will define
#
# GOBJECT_FOUND - system has GObject
# GOBJECT_INCLUDE_DIR - the GObject include directory
# GOBJECT_LIBRARIES - the libraries needed to use GObject
# GOBJECT_DEFINITIONS - Compiler switches required for using GObject
# Copyright (c) 2008 Helio Chissini de Castro,
# (c)2006, Tim Beaulen
IF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
# in cache already
SET(GObject_FIND_QUIETLY TRUE)
ELSE (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
SET(GObject_FIND_QUIETLY FALSE)
ENDIF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
IF (NOT WIN32)
FIND_PACKAGE(PkgConfig REQUIRED)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
PKG_CHECK_MODULES(PKG_GOBJECT2 REQUIRED gobject-2.0)
SET(GOBJECT_DEFINITIONS ${PKG_GOBJECT2_CFLAGS})
ENDIF (NOT WIN32)
FIND_PATH(GOBJECT_INCLUDE_DIR gobject/gobject.h
PATHS
${PKG_GOBJECT2_INCLUDE_DIRS}
/usr/include/glib-2.0/
PATH_SUFFIXES glib-2.0
)
FIND_LIBRARY(_GObjectLibs NAMES gobject-2.0
PATHS
${PKG_GOBJECT2_LIBRARY_DIRS}
)
FIND_LIBRARY(_GModuleLibs NAMES gmodule-2.0
PATHS
${PKG_GOBJECT2_LIBRARY_DIRS}
)
FIND_LIBRARY(_GThreadLibs NAMES gthread-2.0
PATHS
${PKG_GOBJECT2_LIBRARY_DIRS}
)
FIND_LIBRARY(_GLibs NAMES glib-2.0
PATHS
${PKG_GOBJECT2_LIBRARY_DIRS}
)
IF (WIN32)
SET (GOBJECT_LIBRARIES ${_GObjectLibs} ${_GModuleLibs} ${_GThreadLibs} ${_GLibs})
ELSE (WIN32)
SET (GOBJECT_LIBRARIES ${PKG_GOBJECT2_LIBRARIES})
ENDIF (WIN32)
IF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
SET(GOBJECT_FOUND TRUE)
ELSE (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
SET(GOBJECT_FOUND FALSE)
ENDIF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
IF (GOBJECT_FOUND)
IF (NOT GObject_FIND_QUIETLY)
MESSAGE(STATUS "Found GObject libraries: ${GOBJECT_LIBRARIES}")
MESSAGE(STATUS "Found GObject includes : ${GOBJECT_INCLUDE_DIR}")
ENDIF (NOT GObject_FIND_QUIETLY)
ELSE (GOBJECT_FOUND)
IF (GObject_FIND_REQUIRED)
MESSAGE(STATUS "Could NOT find GObject")
ENDIF(GObject_FIND_REQUIRED)
ENDIF (GOBJECT_FOUND)
MARK_AS_ADVANCED(GOBJECT_INCLUDE_DIR GOBJECT_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/FindDBusGLib.cmake 0000664 0001750 0001750 00000004054 12470405660 020701 0 ustar jr jr # Try to find the GLib binding of the DBus library
# DBUS_GLIB_FOUND - system has dbus-glib
# DBUS_GLIB_INCLUDE_DIR - the dbus-glib include directory
# DBUS_GLIB_LIBRARIES - Link these to use dbus-glib
# Copyright (c) 2008, Allen Winter
# Copyright (c) 2009, Andre Moreira Magalhaes
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
set(DBUS_GLIB_FIND_REQUIRED ${DBusGLib_FIND_REQUIRED})
if(DBUS_GLIB_INCLUDE_DIR AND DBUS_GLIB_LIBRARIES)
# Already in cache, be silent
set(DBUS_GLIB_FIND_QUIETLY TRUE)
endif(DBUS_GLIB_INCLUDE_DIR AND DBUS_GLIB_LIBRARIES)
if(NOT WIN32)
find_package(PkgConfig)
if (DBusGLib_FIND_VERSION_EXACT)
pkg_check_modules(PC_DBUS_GLIB QUIET dbus-glib-1=${DBusGLib_FIND_VERSION})
else (DBusGLib_FIND_VERSION_EXACT)
if (DBusGLib_FIND_VERSION)
pkg_check_modules(PC_DBUS_GLIB REQUIRED dbus-glib-1>=${DBusGLib_FIND_VERSION})
else (DBusGLib_FIND_VERSION)
pkg_check_modules(PC_DBUS_GLIB REQUIRED dbus-glib-1)
endif (DBusGLib_FIND_VERSION)
endif (DBusGLib_FIND_VERSION_EXACT)
endif(NOT WIN32)
find_path(DBUS_GLIB_INCLUDE_DIR
NAMES dbus-1.0/dbus/dbus-glib.h
HINTS
${PC_DBUS_GLIB_INCLUDEDIR}
${PC_DBUS_GLIB_INCLUDE_DIRS}
)
find_path(DBUS_GLIB_LOWLEVEL_INCLUDE_DIR
NAMES dbus/dbus-arch-deps.h
HINTS
${PC_DBUS_GLIB_INCLUDEDIR}
${PC_DBUS_GLIB_INCLUDE_DIRS}
)
# HACK! Workaround appending "/dbus-1.0" to the HINTS above not working for some reason.
set(DBUS_GLIB_INCLUDE_DIRS
"${DBUS_GLIB_INCLUDE_DIR}/dbus-1.0" "${DBUS_GLIB_LOWLEVEL_INCLUDE_DIR}"
)
find_library(DBUS_GLIB_LIBRARIES
NAMES dbus-glib-1
HINTS
${PC_DBUS_GLIB_LIBDIR}
${PC_DBUS_GLIB_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DBUS_GLIB DEFAULT_MSG
DBUS_GLIB_LIBRARIES DBUS_GLIB_INCLUDE_DIR)
telepathy-qt-0.9.6~git1/cmake/modules/Qt5Macros.cmake 0000664 0001750 0001750 00000005247 12470405660 020330 0 ustar jr jr # This file is included by FindQt5.cmake, don't include it directly.
# Copyright (C) 2001-2009 Kitware, Inc.
# Copyright (C) 2011 Collabora Ltd.
# Copyright (C) 2011 Nokia Corporation
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
MACRO (QT5_GET_MOC_FLAGS _moc_flags)
SET(${_moc_flags})
GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
FOREACH(_current ${_inc_DIRS})
IF("${_current}" MATCHES "\\.framework/?$")
STRING(REGEX REPLACE "/[^/]+\\.framework" "" framework_path "${_current}")
SET(${_moc_flags} ${${_moc_flags}} "-F${framework_path}")
ELSE("${_current}" MATCHES "\\.framework/?$")
SET(${_moc_flags} ${${_moc_flags}} "-I${_current}")
ENDIF("${_current}" MATCHES "\\.framework/?$")
ENDFOREACH(_current ${_inc_DIRS})
GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS)
FOREACH(_current ${_defines})
SET(${_moc_flags} ${${_moc_flags}} "-D${_current}")
ENDFOREACH(_current ${_defines})
IF(Q_WS_WIN)
SET(${_moc_flags} ${${_moc_flags}} -DWIN32)
ENDIF(Q_WS_WIN)
ENDMACRO (QT5_GET_MOC_FLAGS)
# helper macro to set up a moc rule
MACRO (QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options)
# For Windows, create a parameters file to work around command line length limit
IF (WIN32)
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
# just the file name. This is necessary because the moc tool on
# MinGW builds does not seem to handle spaces in the path to the
# file given with the @ syntax.
GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME)
GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH)
IF(_moc_outfile_dir)
SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir})
ENDIF(_moc_outfile_dir)
SET (_moc_parameters_file ${outfile}_parameters)
SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}")
STRING (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}")
FILE (WRITE ${_moc_parameters_file} "${_moc_parameters}")
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters
DEPENDS ${infile}
${_moc_working_dir}
VERBATIM)
ELSE (WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile}
DEPENDS ${infile})
ENDIF (WIN32)
ENDMACRO (QT5_CREATE_MOC_COMMAND)
telepathy-qt-0.9.6~git1/cmake/modules/BasicFindPackageVersion.cmake.in 0000664 0001750 0001750 00000002624 12470405660 023557 0 ustar jr jr # This is a very basic file for the new style find_package() search mode,
# i.e. Config-mode. It is used by MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() from
# MacroWriteBasicCMakeVersionFile.cmake.
# In this mode find_package() searches for a Config.cmake
# file and an associated Version.cmake file, which it loads to check
# the version number.
# This file can be used with configure_file() to generate such a file for a project
# with very basic logic.
# It sets PACKAGE_VERSION_EXACT if the current version string and the requested
# version string are exactly the same and it sets PACKAGE_VERSION_COMPATIBLE
# if the current version is >= requested version.
# If this is not good enough for your project, you need to write your own
# improved Version.cmake file.
# This file requires the following three variables to be set:
# PROJECT_VERSION_MAJOR
# PROJECT_VERSION_MINOR
# PROJECT_VERSION_PATCH
set(PACKAGE_VERSION @PROJECT_VERSION_FULL@)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
telepathy-qt-0.9.6~git1/cmake/modules/FindQt5.cmake 0000664 0001750 0001750 00000013123 12470405660 017754 0 ustar jr jr # - Find Qt5
# This module can be used to find Qt5.
# The most important issues are that Qt5 pkgconfig files are installed with PKG_CONFIG_PATH properly
# set, and that Qt5 qmake is available via the system path.
# This module defines a number of key variables and macros.
#
# Below is a detailed list of variables that FindQt5.cmake sets.
# QT_FOUND If false, don't try to use Qt.
# QT5_FOUND If false, don't try to use Qt5.
#
# QT_VERSION_MAJOR The major version of Qt found.
# QT_VERSION_MINOR The minor version of Qt found.
# QT_VERSION_PATCH The patch version of Qt found.
#
# QT_BINARY_DIR Path to "bin" of Qt5
# QT_DOC_DIR Path to "doc" of Qt5
#
# QT_INCLUDES List of paths to all include directories of Qt5.
#
# QT_LIBRARIES List of paths to all libraries of Qt5.
# QT_QTCORE_LIBRARY The QtCore library
# QT_QTDBUS_LIBRARY The QtDBus library
# QT_QTGUI_LIBRARY The QtGui library
# QT_QTNETWORK_LIBRARY The QtNetwork library
# QT_QTTEST_LIBRARY The QtTest library
# QT_QTWIDGETS_LIBRARY The QtWidgets library
# QT_QTXML_LIBRARY The QtXml library
#
# also defined, but NOT for general use are
# QT_MOC_EXECUTABLE Where to find the moc tool
# QT_CONFIG_FLAGS Flags used when building Qt
# Copyright (C) 2001-2009 Kitware, Inc.
# Copyright (C) 2011 Collabora Ltd.
# Copyright (C) 2011 Nokia Corporation
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF(QT_INCLUDES AND QT_LIBRARIES AND QT_MAJOR_VERSION MATCHES 5)
# Already in cache, be silent
SET(QT_FOUND TRUE)
SET(QT5_FOUND TRUE)
RETURN()
ENDIF(QT_INCLUDES AND QT_LIBRARIES AND QT_MAJOR_VERSION MATCHES 5)
IF(NOT Qt5Core_DIR )
IF(NOT QT_QMAKE_EXECUTABLE)
FIND_PROGRAM(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake qmake5 qmake-qt5
PATHS "${QT_SEARCH_PATH}/bin" "$ENV{QTDIR}/bin")
SET(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE_FINDQT} CACHE PATH "Qt qmake program.")
ENDIF(NOT QT_QMAKE_EXECUTABLE)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION)
IF(NOT QTVERSION MATCHES "5.*")
SET(QT_FOUND FALSE)
SET(QT5_FOUND FALSE)
IF(Qt5_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "CMake was unable to find Qt5, put qmake in your path or set QTDIR/QT_QMAKE_EXECUTABLE.")
ENDIF(Qt5_FIND_REQUIRED)
RETURN()
ENDIF(NOT QTVERSION MATCHES "5.*")
ENDIF(NOT Qt5Core_DIR )
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5DBus ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5Test ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5Network ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt5Xml ${REQUIRED_QT_VERSION} REQUIRED)
# Copy includes and library names into the same style as pkgconfig used for Qt4
set(QT_INCLUDES ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Test_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS})
set(QT_QTCORE_LIBRARY ${Qt5Core_LIBRARIES})
set(QT_QTDBUS_LIBRARY ${Qt5DBus_LIBRARIES})
set(QT_QTGUI_LIBRARY ${Qt5Gui_LIBRARIES})
set(QT_QTNETWORK_LIBRARY ${Qt5Network_LIBRARIES})
set(QT_QTTEST_LIBRARY ${Qt5Test_LIBRARIES})
set(QT_QTWIDGETS_LIBRARY ${Qt5Widgets_LIBRARIES})
set(QT_QTXML_LIBRARY ${Qt5Xml_LIBRARIES})
set(QT_LIBRARIES ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTTEST_LIBRARY} ${QT_QTWIDGETS_LIBRARY} ${QT_QTXML_LIBRARY})
SET(QT_VERSION_MAJOR ${Qt5Core_VERSION_MAJOR})
SET(QT_VERSION_MINOR ${Qt5Core_VERSION_MINOR})
SET(QT_VERSION_PATCH ${Qt5Core_VERSION_PATCH})
SET(QT_VERSION ${Qt5Core_VERSION})
GET_PROPERTY(QT_QMAKE_EXECUTABLE TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORTED_LOCATION)
IF(NOT QT_INCLUDE_DIR)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_HEADERS" OUTPUT_VARIABLE QTHEADERS)
SET(QT_INCLUDE_DIR ${QTHEADERS} CACHE INTERNAL "" FORCE)
ENDIF(NOT QT_INCLUDE_DIR)
IF(NOT QT_LIBRARY_DIR)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_LIBS" OUTPUT_VARIABLE QTLIBS)
SET(QT_LIBRARY_DIR ${QTLIBS} CACHE INTERNAL "" FORCE)
ENDIF(NOT QT_LIBRARY_DIR)
IF(NOT QT_BINARY_DIR)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_BINS" OUTPUT_VARIABLE QTBINS)
SET(QT_BINARY_DIR ${QTBINS} CACHE INTERNAL "" FORCE)
ENDIF(NOT QT_BINARY_DIR)
IF(NOT QT_DOC_DIR)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DOCS" OUTPUT_VARIABLE QTDOCS)
SET(QT_DOC_DIR ${QTDOCS} CACHE INTERNAL "" FORCE)
ENDIF(NOT QT_DOC_DIR)
IF(NOT QT_MOC_EXECUTABLE)
FIND_PROGRAM(QT_MOC_EXECUTABLE NAMES moc moc5 moc-qt5 PATHS ${QT_BINARY_DIR}
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
ENDIF(NOT QT_MOC_EXECUTABLE)
MARK_AS_ADVANCED(QT_INCLUDES QT_INCLUDE_DIR
QT_LIBRARIES QT_LIBRARY_DIR
QT_BINARY_DIR
QT_DOC_DIR
QT_QMAKE_EXECUTABLE_FINDQT QT_QMAKE_EXECUTABLE QT_MOC_EXECUTABLE)
# Invokes pkgconfig, cleans up the result and sets variables
EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable qt_config QtCore
OUTPUT_VARIABLE _pkgconfig_flags
RESULT_VARIABLE _pkgconfig_failed)
STRING(REPLACE " " ";" QT_CONFIG_FLAGS "${_pkgconfig_flags}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
INCLUDE(Qt5Macros)
SET(QT_FOUND TRUE)
SET(QT5_FOUND TRUE)
telepathy-qt-0.9.6~git1/cmake/modules/FindLibPython.py 0000664 0001750 0001750 00000001012 12470405660 020555 0 ustar jr jr # Copyright (c) 2007, Simon Edwards
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
import sys
import distutils.sysconfig
print("exec_prefix:%s" % sys.exec_prefix)
print("short_version:%s" % sys.version[:3])
print("long_version:%s" % sys.version.split()[0])
print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc())
print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1))
telepathy-qt-0.9.6~git1/cmake/modules/FindGStreamer.cmake 0000664 0001750 0001750 00000005150 12470405660 021175 0 ustar jr jr # - Try to find GStreamer
# Once done this will define
#
# GSTREAMER_FOUND - system has GStreamer
# GSTREAMER_INCLUDE_DIR - the GStreamer include directory
# GSTREAMER_LIBRARIES - the libraries needed to use GStreamer
# GSTREAMER_DEFINITIONS - Compiler switches required for using GStreamer
# Copyright (c) 2006, Tim Beaulen
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# TODO: Other versions --> GSTREAMER_X_Y_FOUND (Example: GSTREAMER_0_8_FOUND and GSTREAMER_0_10_FOUND etc)
IF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY)
# in cache already
SET(GSTREAMER_FIND_QUIETLY TRUE)
ELSE (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY)
SET(GSTREAMER_FIND_QUIETLY FALSE)
ENDIF (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARIES AND GSTREAMER_BASE_LIBRARY AND GSTREAMER_INTERFACE_LIBRARY)
IF (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_GSTREAMER gstreamer-1.0)
#MESSAGE(STATUS "DEBUG: GStreamer include directory = ${GSTREAMER_INCLUDE_DIRS}")
#MESSAGE(STATUS "DEBUG: GStreamer link directory = ${GSTREAMER_LIBRARY_DIRS}")
#MESSAGE(STATUS "DEBUG: GStreamer CFlags = ${GSTREAMER_CFLAGS_OTHER}")
SET(GSTREAMER_DEFINITIONS ${PC_GSTREAMER_CFLAGS_OTHER})
ENDIF (NOT WIN32)
FIND_PATH(GSTREAMER_INCLUDE_DIR gst/gst.h
PATHS
${PC_GSTREAMER_INCLUDEDIR}
${PC_GSTREAMER_INCLUDE_DIRS}
PATH_SUFFIXES gstreamer-1.0
)
FIND_LIBRARY(GSTREAMER_LIBRARIES NAMES gstreamer-1.0
PATHS
${PC_GSTREAMER_LIBDIR}
${PC_GSTREAMER_LIBRARY_DIRS}
)
FIND_LIBRARY(GSTREAMER_BASE_LIBRARY NAMES gstbase-1.0
PATHS
${PC_GSTREAMER_LIBDIR}
${PC_GSTREAMER_LIBRARY_DIRS}
)
IF (GSTREAMER_INCLUDE_DIR)
#MESSAGE(STATUS "DEBUG: Found GStreamer include dir: ${GSTREAMER_INCLUDE_DIR}")
ELSE (GSTREAMER_INCLUDE_DIR)
MESSAGE(STATUS "GStreamer: WARNING: include dir not found")
ENDIF (GSTREAMER_INCLUDE_DIR)
IF (GSTREAMER_LIBRARIES)
#MESSAGE(STATUS "DEBUG: Found GStreamer library: ${GSTREAMER_LIBRARIES}")
ELSE (GSTREAMER_LIBRARIES)
MESSAGE(STATUS "GStreamer: WARNING: library not found")
ENDIF (GSTREAMER_LIBRARIES)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GStreamer DEFAULT_MSG GSTREAMER_LIBRARIES GSTREAMER_INCLUDE_DIR GSTREAMER_BASE_LIBRARY)
MARK_AS_ADVANCED(GSTREAMER_INCLUDE_DIR GSTREAMER_LIBRARIES GSTREAMER_BASE_LIBRARY)
telepathy-qt-0.9.6~git1/cmake/modules/Doxygen.cmake 0000664 0001750 0001750 00000002602 12470405660 020117 0 ustar jr jr # generate documentation on 'make doxygen-doc'
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/doc)
find_package(Doxygen)
if(DOXYGEN_FOUND)
find_program(QHELPGENERATOR_EXECUTABLE qhelpgenerator)
mark_as_advanced(QHELPGENERATOR_EXECUTABLE)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(QHELPGENERATOR DEFAULT_MSG QHELPGENERATOR_EXECUTABLE)
set(QT_TAGS_FILE ${QT_DOC_DIR}/html/qt.tags)
if(EXISTS ${QT_TAGS_FILE})
find_package(Perl)
if (NOT PERL_FOUND)
message(WARNING "Perl was not found. Qt crosslinks in uploaded docs won't be valid.")
endif (NOT PERL_FOUND)
else(EXISTS ${QT_TAGS_FILE})
message(WARNING "html/qt.tags not found in ${QT_DOC_DIR}. Set the QT_DOC_DIR variable to
point to its location to enable crosslinking.")
unset(QT_TAGS_FILE)
endif(EXISTS ${QT_TAGS_FILE})
set(abs_top_builddir ${CMAKE_BINARY_DIR})
set(abs_top_srcdir ${CMAKE_SOURCE_DIR})
set(GENERATE_HTML YES)
set(GENERATE_RTF NO)
set(GENERATE_CHM NO)
set(GENERATE_CHI NO)
set(GENERATE_LATEX NO)
set(GENERATE_MAN NO)
set(GENERATE_XML NO)
set(GENERATE_QHP ${QHELPGENERATOR_FOUND})
configure_file(doxygen.cfg.in ${CMAKE_BINARY_DIR}/doxygen.cfg)
add_custom_target(doxygen-doc ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/doxygen.cfg)
endif(DOXYGEN_FOUND)
telepathy-qt-0.9.6~git1/cmake/modules/MacroWriteBasicCMakeVersionFile.cmake 0000664 0001750 0001750 00000002153 12470405660 024570 0 ustar jr jr # MACRO_WRITE_BASIC_CMAKE_VERSION_FILE( _filename _major _minor _patch)
# Writes a file for use as ConfigVersion.cmake file to <_filename>.
# See the documentation of FIND_PACKAGE() for details on this.
# _filename is the output filename, it should be in the build tree.
# _major is the major version number of the project to be installed
# _minor is the minor version number of the project to be installed
# _patch is the patch version number of the project to be installed
#
# Copyright (c) 2008, Alexander Neundorf,
# Copyright (c) 2010, Collabora Ltd.,
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(MACRO_WRITE_BASIC_CMAKE_VERSION_FILE _filename _version)
set(PROJECT_VERSION_FULL ${_version})
configure_file(${_currentListFileDir}/BasicFindPackageVersion.cmake.in "${_filename}" @ONLY)
endfunction(MACRO_WRITE_BASIC_CMAKE_VERSION_FILE _major _minor _patch)
telepathy-qt-0.9.6~git1/cmake/modules/TelepathyDist.cmake 0000664 0001750 0001750 00000012365 12470405660 021274 0 ustar jr jr # setup make dist
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
COMMAND git archive --format=tar --prefix=${PACKAGE_NAME}-${PACKAGE_VERSION}/ HEAD |
gzip > ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
add_custom_target(create-source-working-dir
rm -rf ${PACKAGE_NAME}-${PACKAGE_VERSION} &&
gzip -df ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz &&
tar -xf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar &&
rm ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar* &&
cd ${PACKAGE_NAME}-${PACKAGE_VERSION}/ &&
rm -rf doc && mkdir doc && cp -R ${CMAKE_BINARY_DIR}/doc/html doc/
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
COMMENT "Generating working source dir for the dist tarball")
add_dependencies(create-source-working-dir doxygen-doc)
add_custom_target(dist-hook
chmod u+w ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}/ChangeLog &&
git log --stat > ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}/ChangeLog ||
git log > ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}/ChangeLog
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Updating Changelog")
add_dependencies(dist-hook create-source-working-dir)
add_custom_target(dist tar --format=ustar -chf - ${PACKAGE_NAME}-${PACKAGE_VERSION} |
GZIP=--best gzip -c > ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.gz
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating dist tarball")
add_dependencies(dist dist-hook)
# setup make distcheck
add_custom_target(distcheck rm -rf build && mkdir build && cd build && cmake .. && make && make check
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}/
COMMENT "Testing successful tarball build")
add_dependencies(distcheck dist)
# CPack
set(ENABLE_CPACK OFF CACHE BOOL "Enables CPack targets generation")
if (ENABLE_CPACK)
include(InstallRequiredSystemLibraries)
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A high-level binding for Telepathy in Qt")
SET(CPACK_PACKAGE_VENDOR "Collabora Ltd.")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
SET(CPACK_PACKAGE_VERSION_MAJOR ${TP_QT_MAJOR_VERSION})
SET(CPACK_PACKAGE_VERSION_MINOR ${TP_QT_MINOR_VERSION})
SET(CPACK_PACKAGE_VERSION_PATCH ${TP_QT_MICRO_VERSION})
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "TelepathyQt")
SET(CPACK_PACKAGE_CONTACT "telepathy@lists.freedesktop.org")
set(CPACK_SOURCE_IGNORE_FILES
"/build/;/.bzr/;~$;/.git/;/.kdev4/;${CPACK_SOURCE_IGNORE_FILES}")
IF(WIN32 AND NOT UNIX)
# There is a bug in NSI that does not handle full unix paths properly. Make
# sure there is at least one set of four (4) backlasshes.
#SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
#SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe")
SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} TelepathyQt")
#SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.github.com")
#SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.my-personal-home-page.com")
#SET(CPACK_NSIS_CONTACT "me@my-personal-home-page.com")
SET(CPACK_NSIS_MODIFY_PATH ON)
ELSE(WIN32 AND NOT UNIX)
#SET(CPACK_STRIP_FILES "bin/MyExecutable")
SET(CPACK_SOURCE_STRIP_FILES "")
ENDIF(WIN32 AND NOT UNIX)
#SET(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable")
if (APPLE)
set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_RELOCATABLE OFF)
endif (APPLE)
#name components
set(CPACK_COMPONENT_MAINLIBRARY_DISPLAY_NAME "TelepathyQt main components")
set(CPACK_COMPONENT_FARSTREAM_DISPLAY_NAME "TelepathyQt Farstream support")
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Development files for TelepathyQt")
set(CPACK_COMPONENT_FARSTREAM_HEADERS_DISPLAY_NAME "Development files for TelepathyQt-Farstream")
#components description
set(CPACK_COMPONENT_MAINLIBRARY_DESCRIPTION
"The main TelepathyQt library")
set(CPACK_COMPONENT_FARSTREAM_DESCRIPTION
"The TelepathyQt-Farstream library")
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
"Development files for TelepathyQt")
set(CPACK_COMPONENT_FARSTREAM_HEADERS_DESCRIPTION
"Development files for TelepathyQt-Farstream")
set(CPACK_COMPONENT_HEADERS_DEPENDS mainlibrary)
set(CPACK_COMPONENT_FARSTREAM_DEPENDS mainlibrary)
set(CPACK_COMPONENT_FARSTREAM_HEADERS_DEPENDS mainlibrary farstream)
#installation types
set(CPACK_ALL_INSTALL_TYPES User Developer Minimal)
set(CPACK_COMPONENT_MAINLIBRARY_INSTALL_TYPES User Developer Minimal)
set(CPACK_COMPONENT_FARSTREAM_INSTALL_TYPES User Developer)
set(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer)
set(CPACK_COMPONENT_FARSTREAM_HEADERS_INSTALL_TYPES Developer)
# Leave this as the last declaration, always!!!
include(CPack)
endif (ENABLE_CPACK)
telepathy-qt-0.9.6~git1/cmake/modules/TelepathyDefaults.cmake 0000664 0001750 0001750 00000015720 12470405660 022136 0 ustar jr jr # Enable testing using CTest
enable_testing()
# Always include srcdir and builddir in include path
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} in about every subdir
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# put the include dirs which are in the source or build tree
# before all other include dirs, so the headers in the sources
# are prefered over the already installed ones
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
# Use colored output
set(CMAKE_COLOR_MAKEFILE ON)
# Add an option to decide where to install the config files
if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} VERSION_GREATER 2.6.2)
option(USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR "Prefer to install the Config.cmake files to lib/cmake/ instead of lib//cmake" TRUE)
endif (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} VERSION_GREATER 2.6.2)
# Set compiler flags
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O2 -fno-reorder-blocks -fno-schedule-insns -fno-inline")
set(CMAKE_CXX_FLAGS_DEBUGFULL "-O0 -g3 -ggdb -fno-inline")
set(CMAKE_CXX_FLAGS_PROFILE "-pg -g3 -ggdb -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-ggdb -O2 -fno-reorder-blocks -fno-schedule-insns -fno-inline")
set(CMAKE_C_FLAGS_DEBUGFULL "-O0 -g3 -ggdb -fno-inline")
set(CMAKE_C_FLAGS_PROFILE "-pg -g3 -ggdb -DNDEBUG")
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-pg -ggdb")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "-pg -ggdb")
set(DISABLE_WERROR 0 CACHE BOOL "compile without -Werror (normally enabled in development builds)")
include(CompilerWarnings)
include(TestCXXAcceptsFlag)
CHECK_CXX_ACCEPTS_FLAG("-fvisibility=hidden" CXX_FVISIBILITY_HIDDEN)
if (CXX_FVISIBILITY_HIDDEN)
set(VISIBILITY_HIDDEN_FLAGS "-fvisibility=hidden")
else (CXX_FVISIBILITY_HIDDEN)
set(VISIBILITY_HIDDEN_FLAGS)
endif (CXX_FVISIBILITY_HIDDEN)
CHECK_CXX_ACCEPTS_FLAG("-fvisibility-inlines-hidden" CXX_FVISIBILITY_INLINES_HIDDEN)
if (CXX_FVISIBILITY_INLINES_HIDDEN)
set(VISIBILITY_HIDDEN_FLAGS "${VISIBILITY_HIDDEN_FLAGS} -fvisibility-inlines-hidden")
endif (CXX_FVISIBILITY_INLINES_HIDDEN)
CHECK_CXX_ACCEPTS_FLAG("-Wdeprecated-declarations" CXX_DEPRECATED_DECLARATIONS)
if (CXX_DEPRECATED_DECLARATIONS)
set(DEPRECATED_DECLARATIONS_FLAGS "-Wdeprecated-declarations -DTP_QT_DEPRECATED_WARNINGS")
else (CXX_DEPRECATED_DECLARATIONS)
set(DEPRECATED_DECLARATIONS_FLAGS)
endif (CXX_DEPRECATED_DECLARATIONS)
if(${TP_QT_NANO_VERSION} EQUAL 0)
set(NOT_RELEASE 0)
else(${TP_QT_NANO_VERSION} EQUAL 0)
set(NOT_RELEASE 1)
endif(${TP_QT_NANO_VERSION} EQUAL 0)
set(desired
all
extra
sign-compare
pointer-arith
format-security
init-self
non-virtual-dtor)
set(undesired
missing-field-initializers
unused-parameter
unused-local-typedefs)
compiler_warnings(CMAKE_CXX_FLAGS_WARNINGS cxx ${NOT_RELEASE} "${desired}" "${undesired}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_WARNINGS}")
set(desired_c
all
extra
declaration-after-statement
shadow
strict-prototypes
missing-prototypes
sign-compare
nested-externs
pointer-arith
format-security
init-self)
set(undesired_c
missing-field-initializers
unused-parameter
unused-local-typedefs)
compiler_warnings(CMAKE_C_FLAGS_WARNINGS c ${NOT_RELEASE} "${desired_c}" "${undesired_c}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_WARNINGS}")
# Link development builds with -Wl,--no-add-needed
# TODO: binutils 2.21 renames the flag to --no-copy-dt-needed-entries, though it keeps the old
# one as a deprecated alias.
if(${NOT_RELEASE} EQUAL 1)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-add-needed")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-add-needed")
endif(${NOT_RELEASE} EQUAL 1)
if(CMAKE_SYSTEM_NAME MATCHES Linux)
add_definitions(-D_BSD_SOURCE)
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
# Compiler coverage
set(ENABLE_COMPILER_COVERAGE OFF CACHE BOOL "Enables compiler coverage tests through lcov. Enabling this option will build
Telepathy-Qt as a static library.")
if (ENABLE_COMPILER_COVERAGE)
check_cxx_accepts_flag("-fprofile-arcs -ftest-coverage" CXX_FPROFILE_ARCS)
check_cxx_accepts_flag("-ftest-coverage" CXX_FTEST_COVERAGE)
if (CXX_FPROFILE_ARCS AND CXX_FTEST_COVERAGE)
find_program(LCOV lcov)
find_program(LCOV_GENHTML genhtml)
if (NOT LCOV OR NOT LCOV_GENHTML)
message(FATAL_ERROR "You chose to use compiler coverage tests, but lcov or genhtml could not be found in your PATH.")
else (NOT LCOV OR NOT LCOV_GENHTML)
message(STATUS "Compiler coverage tests enabled - Telepathy-Qt will be compiled as a static library")
set(COMPILER_COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage")
endif (NOT LCOV OR NOT LCOV_GENHTML)
else (CXX_FPROFILE_ARCS AND CXX_FTEST_COVERAGE)
message(FATAL_ERROR "You chose to use compiler coverage tests, but it appears your compiler is not able to support them.")
endif (CXX_FPROFILE_ARCS AND CXX_FTEST_COVERAGE)
else (ENABLE_COMPILER_COVERAGE)
set(COMPILER_COVERAGE_FLAGS)
endif (ENABLE_COMPILER_COVERAGE)
# gcc under Windows
if(MINGW)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--export-all-symbols -Wl,--disable-auto-import")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--export-all-symbols -Wl,--disable-auto-import")
# we always link against the release version of QT with mingw
# (even for debug builds). So we need to define QT_NO_DEBUG
# or else QPluginLoader rejects plugins because it thinks
# they're built against the wrong QT.
add_definitions(-DQT_NO_DEBUG)
endif(MINGW)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
set(ESCAPE_CHAR ^)
endif(MSVC)
set(LIB_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory where libraries will be installed (default is ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})" FORCE)
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "The subdirectory where header files will be installed (default is ${CMAKE_INSTALL_PREFIX}/include)" FORCE)
set(DATA_INSTALL_DIR "share/telepathy" CACHE PATH "The subdirectory where data files will be installed (default is ${CMAKE_INSTALL_PREFIX}/share/telepathy)" FORCE)
telepathy-qt-0.9.6~git1/cmake/modules/MacroLogFeature.cmake 0000664 0001750 0001750 00000013110 12470405660 021515 0 ustar jr jr # This file defines the Feature Logging macros.
#
# MACRO_LOG_FEATURE(VAR FEATURE DESCRIPTION URL [REQUIRED [MIN_VERSION [COMMENTS]]])
# Logs the information so that it can be displayed at the end
# of the configure run
# VAR : TRUE or FALSE, indicating whether the feature is supported
# FEATURE: name of the feature, e.g. "libjpeg"
# DESCRIPTION: description what this feature provides
# URL: home page
# REQUIRED: TRUE or FALSE, indicating whether the featue is required
# MIN_VERSION: minimum version number. empty string if unneeded
# COMMENTS: More info you may want to provide. empty string if unnecessary
#
# MACRO_DISPLAY_FEATURE_LOG()
# Call this to display the collected results.
# Exits CMake with a FATAL error message if a required feature is missing
#
# Example:
#
# INCLUDE(MacroLogFeature)
#
# FIND_PACKAGE(JPEG)
# MACRO_LOG_FEATURE(JPEG_FOUND "libjpeg" "Support JPEG images" "http://www.ijg.org" TRUE "3.2a" "")
# ...
# MACRO_DISPLAY_FEATURE_LOG()
# Copyright (c) 2006, Alexander Neundorf,
# Copyright (c) 2006, Allen Winter,
# Copyright (c) 2009, Sebastian Trueg,
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF (NOT _macroLogFeatureAlreadyIncluded)
SET(_file ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_file ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_file ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_macroLogFeatureAlreadyIncluded TRUE)
ENDIF (NOT _macroLogFeatureAlreadyIncluded)
MACRO(MACRO_LOG_FEATURE _var _package _description _url ) # _required _minvers _comments)
STRING(TOUPPER "${ARGV4}" _required)
SET(_minvers "${ARGV5}")
SET(_comments "${ARGV6}")
IF (${_var})
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
ELSE (${_var})
IF ("${_required}" STREQUAL "TRUE")
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
ELSE ("${_required}" STREQUAL "TRUE")
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
ENDIF ("${_required}" STREQUAL "TRUE")
ENDIF (${_var})
SET(_logtext " * ${_package}")
IF (NOT ${_var})
IF (${_minvers} MATCHES ".*")
SET(_logtext "${_logtext} (${_minvers} or higher)")
ENDIF (${_minvers} MATCHES ".*")
SET(_logtext "${_logtext} <${_url}>\n ")
ELSE (NOT ${_var})
SET(_logtext "${_logtext} - ")
ENDIF (NOT ${_var})
SET(_logtext "${_logtext}${_description}")
IF (NOT ${_var})
IF (${_comments} MATCHES ".*")
SET(_logtext "${_logtext}\n ${_comments}")
ENDIF (${_comments} MATCHES ".*")
# SET(_logtext "${_logtext}\n") #double-space missing features?
ENDIF (NOT ${_var})
FILE(APPEND "${_LOGFILENAME}" "${_logtext}\n")
ENDMACRO(MACRO_LOG_FEATURE)
MACRO(MACRO_DISPLAY_FEATURE_LOG)
SET(_missingFile ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
SET(_enabledFile ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
SET(_disabledFile ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
IF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile})
SET(_printSummary TRUE)
ENDIF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile})
IF(_printSummary)
SET(_missingDeps 0)
IF (EXISTS ${_enabledFile})
FILE(READ ${_enabledFile} _enabled)
FILE(REMOVE ${_enabledFile})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following external packages were located on your system.\n-- This installation will have the extra features provided by these packages.\n-----------------------------------------------------------------------------\n${_enabled}")
ENDIF (EXISTS ${_enabledFile})
IF (EXISTS ${_disabledFile})
SET(_missingDeps 1)
FILE(READ ${_disabledFile} _disabled)
FILE(REMOVE ${_disabledFile})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following OPTIONAL packages could NOT be located on your system.\n-- Consider installing them to enable more features from this software.\n-----------------------------------------------------------------------------\n${_disabled}")
ENDIF (EXISTS ${_disabledFile})
IF (EXISTS ${_missingFile})
SET(_missingDeps 1)
FILE(READ ${_missingFile} _requirements)
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following REQUIRED packages could NOT be located on your system.\n-- You must install these packages before continuing.\n-----------------------------------------------------------------------------\n${_requirements}")
FILE(REMOVE ${_missingFile})
SET(_haveMissingReq 1)
ENDIF (EXISTS ${_missingFile})
IF (NOT ${_missingDeps})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- Congratulations! All external packages have been found.")
ENDIF (NOT ${_missingDeps})
MESSAGE(${_summary})
MESSAGE("-----------------------------------------------------------------------------\n")
IF(_haveMissingReq)
MESSAGE(FATAL_ERROR "Exiting: Missing Requirements")
ENDIF(_haveMissingReq)
ENDIF(_printSummary)
ENDMACRO(MACRO_DISPLAY_FEATURE_LOG)
telepathy-qt-0.9.6~git1/cmake/modules/FindFarstream.cmake 0000664 0001750 0001750 00000003405 12470405660 021231 0 ustar jr jr # - Try to find Farstream
# Once done this will define
#
# FARSTREAM_FOUND - system has Farstream
# FARSTREAM_INCLUDE_DIR - the Farstream include directory
# FARSTREAM_LIBRARIES - the libraries needed to use Farstream
# FARSTREAM_DEFINITIONS - Compiler switches required for using Farstream
# Copyright (c) 2010, Dario Freddi
# Copyright (c) 2012, George Kiagiadakis
#
# Redistribution and use is allowed according to the terms of the BSD license.
if (FARSTREAM_INCLUDE_DIR AND FARSTREAM_LIBRARIES)
# in cache already
set(Farstream_FIND_QUIETLY TRUE)
else (FARSTREAM_INCLUDE_DIR AND FARSTREAM_LIBRARIES)
set(Farstream_FIND_QUIETLY FALSE)
endif (FARSTREAM_INCLUDE_DIR AND FARSTREAM_LIBRARIES)
if (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the find_path() and find_library() calls
find_package(PkgConfig)
if (FARSTREAM_MIN_VERSION)
PKG_CHECK_MODULES(PC_FARSTREAM farstream-0.2>=${FARSTREAM_MIN_VERSION})
else (FARSTREAM_MIN_VERSION)
PKG_CHECK_MODULES(PC_FARSTREAM farstream-0.2)
endif (FARSTREAM_MIN_VERSION)
set(FARSTREAM_DEFINITIONS ${PC_FARSTREAM_CFLAGS_OTHER})
endif (NOT WIN32)
find_path(FARSTREAM_INCLUDE_DIR farstream/fs-conference.h
PATHS
${PC_FARSTREAM_INCLUDEDIR}
${PC_FARSTREAM_INCLUDE_DIRS}
PATH_SUFFIXES farstream-0.2
)
find_library(FARSTREAM_LIBRARIES NAMES farstream-0.2
PATHS
${PC_FARSTREAM_LIBDIR}
${PC_FARSTREAM_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Farstream DEFAULT_MSG FARSTREAM_LIBRARIES
FARSTREAM_INCLUDE_DIR)
mark_as_advanced(FARSTREAM_INCLUDE_DIR FARSTREAM_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/FindPythonLibrary.cmake 0000664 0001750 0001750 00000007031 12470405660 022112 0 ustar jr jr # FindPythonLibrary.cmake
# ~~~~~~~~~~~~~~~~~~~~~~~
# Find the Python interpreter and related Python directories.
#
# This file defines the following variables:
#
# PYTHON_EXECUTABLE - The path and filename of the Python interpreter.
#
# PYTHON_SHORT_VERSION - The version of the Python interpreter found,
# excluding the patch version number. (e.g. 2.5 and not 2.5.1))
#
# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human
# readable string.
#
# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory.
#
# PYTHON_INCLUDE_PATH - Directory holding the python.h include file.
#
# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library.
# Copyright (c) 2007, Simon Edwards
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CMakeFindFrameworks)
if(EXISTS PYTHON_LIBRARY)
# Already in cache, be silent
set(PYTHONLIBRARY_FOUND TRUE)
else(EXISTS PYTHON_LIBRARY)
FIND_PACKAGE(PythonInterp)
if(PYTHONINTERP_FOUND)
FIND_FILE(_find_lib_python_py FindLibPython.py PATHS ${CMAKE_MODULE_PATH})
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_lib_python_py} OUTPUT_VARIABLE python_config)
if(python_config)
STRING(REGEX REPLACE ".*exec_prefix:([^\n]+).*$" "\\1" PYTHON_PREFIX ${python_config})
STRING(REGEX REPLACE ".*\nshort_version:([^\n]+).*$" "\\1" PYTHON_SHORT_VERSION ${python_config})
STRING(REGEX REPLACE ".*\nlong_version:([^\n]+).*$" "\\1" PYTHON_LONG_VERSION ${python_config})
STRING(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_PATH ${python_config})
STRING(REGEX REPLACE ".*\nsite_packages_dir:([^\n]+).*$" "\\1" PYTHON_SITE_PACKAGES_DIR ${python_config})
STRING(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_SHORT_VERSION_NO_DOT ${PYTHON_SHORT_VERSION})
set(PYTHON_LIBRARY_NAMES python${PYTHON_SHORT_VERSION} python${PYTHON_SHORT_VERSION_NO_DOT})
if(WIN32)
STRING(REPLACE "\\" "/" PYTHON_SITE_PACKAGES_DIR ${PYTHON_SITE_PACKAGES_DIR})
endif(WIN32)
FIND_LIBRARY(PYTHON_LIBRARY NAMES ${PYTHON_LIBRARY_NAMES} PATHS ${PYTHON_PREFIX}/lib ${PYTHON_PREFIX}/libs NO_DEFAULT_PATH)
set(PYTHONLIBRARY_FOUND TRUE)
endif(python_config)
# adapted from cmake's builtin FindPythonLibs
if(APPLE)
CMAKE_FIND_FRAMEWORKS(Python)
set(PYTHON_FRAMEWORK_INCLUDES)
if(Python_FRAMEWORKS)
# If a framework has been selected for the include path,
# make sure "-framework" is used to link it.
if("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
set(PYTHON_LIBRARY "")
set(PYTHON_DEBUG_LIBRARY "")
endif("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
if(NOT PYTHON_LIBRARY)
set (PYTHON_LIBRARY "-framework Python" CACHE FILEPATH "Python Framework" FORCE)
endif(NOT PYTHON_LIBRARY)
set(PYTHONLIBRARY_FOUND TRUE)
endif(Python_FRAMEWORKS)
endif(APPLE)
endif(PYTHONINTERP_FOUND)
if(PYTHONLIBRARY_FOUND)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARY})
if(NOT PYTHONLIBRARY_FIND_QUIETLY)
message(STATUS "Found Python executable: ${PYTHON_EXECUTABLE}")
message(STATUS "Found Python version: ${PYTHON_LONG_VERSION}")
endif(NOT PYTHONLIBRARY_FIND_QUIETLY)
else(PYTHONLIBRARY_FOUND)
if(PYTHONLIBRARY_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Python")
endif(PYTHONLIBRARY_FIND_REQUIRED)
endif(PYTHONLIBRARY_FOUND)
endif (EXISTS PYTHON_LIBRARY)
telepathy-qt-0.9.6~git1/cmake/modules/FindTelepathyGlib.cmake 0000664 0001750 0001750 00000004312 12470405660 022040 0 ustar jr jr # - Try to find Telepathy-Glib
# Once done this will define
#
# TELEPATHY_GLIB_FOUND - system has Telepathy-Glib
# TELEPATHY_GLIB_INCLUDE_DIR - the Telepathy-Glib include directory
# TELEPATHY_GLIB_LIBRARIES - the libraries needed to use Telepathy-Glib
# TELEPATHY_GLIB_DEFINITIONS - Compiler switches required for using Telepathy-Glib
# Copyright (c) 2010, Dario Freddi
#
# Redistribution and use is allowed according to the terms of the BSD license.
if (TELEPATHY_GLIB_INCLUDE_DIR AND TELEPATHY_GLIB_LIBRARIES)
# in cache already
set(TELEPATHYGLIB_FIND_QUIETLY TRUE)
else (TELEPATHY_GLIB_INCLUDE_DIR AND TELEPATHY_GLIB_LIBRARIES)
set(TELEPATHYGLIB_FIND_QUIETLY FALSE)
endif (TELEPATHY_GLIB_INCLUDE_DIR AND TELEPATHY_GLIB_LIBRARIES)
if (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the find_path() and find_library() calls
find_package(PkgConfig)
if (TELEPATHY_GLIB_MIN_VERSION)
PKG_CHECK_MODULES(PC_TELEPATHY_GLIB telepathy-glib>=${TELEPATHY_GLIB_MIN_VERSION})
else (TELEPATHY_GLIB_MIN_VERSION)
PKG_CHECK_MODULES(PC_TELEPATHY_GLIB telepathy-glib)
endif (TELEPATHY_GLIB_MIN_VERSION)
set(TELEPATHY_GLIB_DEFINITIONS ${PC_TELEPATHY_GLIB_CFLAGS_OTHER})
endif (NOT WIN32)
if (TELEPATHY_GLIB_MIN_VERSION AND NOT PC_TELEPATHY_GLIB_FOUND)
message(STATUS "Telepathy-glib not found or its version is < ${TELEPATHY_GLIB_MIN_VERSION}")
else (TELEPATHY_GLIB_MIN_VERSION AND NOT PC_TELEPATHY_GLIB_FOUND)
find_path(TELEPATHY_GLIB_INCLUDE_DIR telepathy-glib/client.h
PATHS
${PC_TELEPATHY_GLIB_INCLUDEDIR}
${PC_TELEPATHY_GLIB_INCLUDE_DIRS}
PATH_SUFFIXES telepathy-1.0
)
find_library(TELEPATHY_GLIB_LIBRARIES NAMES telepathy-glib
PATHS
${PC_TELEPATHY_GLIB_LIBDIR}
${PC_TELEPATHY_GLIB_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TelepathyGlib DEFAULT_MSG TELEPATHY_GLIB_LIBRARIES
TELEPATHY_GLIB_INCLUDE_DIR)
mark_as_advanced(TELEPATHY_GLIB_INCLUDE_DIR TELEPATHY_GLIB_LIBRARIES)
endif (TELEPATHY_GLIB_MIN_VERSION AND NOT PC_TELEPATHY_GLIB_FOUND)
telepathy-qt-0.9.6~git1/cmake/modules/CompilerWarnings.cmake 0000664 0001750 0001750 00000004315 12470405660 021770 0 ustar jr jr include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
macro(check_lang_compiler_flag lang flag variable)
if(${lang} STREQUAL c)
check_c_compiler_flag(${flag} ${variable})
endif(${lang} STREQUAL c)
if(${lang} STREQUAL cxx)
check_cxx_compiler_flag(${flag} ${variable})
endif(${lang} STREQUAL cxx)
endmacro(check_lang_compiler_flag flag variable)
macro(compiler_warnings ret lang werror_by_default desirable_flags undesirable_flags)
set(warning_flags "")
foreach(flag ${desirable_flags})
check_lang_compiler_flag(${lang} -W${flag} ${flag}_${lang}_result)
if(${${flag}_${lang}_result})
set(warning_flags "${warning_flags} -W${flag}")
endif( ${${flag}_${lang}_result} )
endforeach(flag ${desirable_flags})
check_lang_compiler_flag(${lang} -Werror error_${lang}_result)
if(${error_${lang}_result})
set(error_flags "-Werror")
endif(${error_${lang}_result})
set(all_nowarning_flags_supported 1)
foreach(flag ${undesirable_flags})
check_lang_compiler_flag(${lang} -Wno-${flag} ${flag}_${lang}_result)
if(${${flag}_${lang}_result})
set(warning_flags "${warning_flags} -Wno-${flag}")
else(${${flag}_${lang}_result})
set(all_nowarning_flags_supported 0)
break()
endif(${${flag}_${lang}_result})
check_lang_compiler_flag(${lang} -Wno-error=${flag} noerror_${flag}_${lang}_result)
if(${noerror_${flag}_${lang}_result})
set(error_flags "${error_flags} -Wno-error=${flag}")
endif(${noerror_${flag}_${lang}_result})
endforeach(flag ${undesirable_flags})
if(DISABLE_WERROR)
set(enable_werror 0)
else(DISABLE_WERROR)
set(enable_werror 1)
endif(DISABLE_WERROR)
if(${werror_by_default} AND ${enable_werror} AND ${all_nowarning_flags_supported})
set(${ret} "${warning_flags} ${error_flags}")
else(${werror_by_default} AND ${enable_werror} AND ${all_nowarning_flags_supported})
set(${ret} "${warning_flags}")
endif(${werror_by_default} AND ${enable_werror} AND ${all_nowarning_flags_supported})
endmacro(compiler_warnings ret lang werror_by_default desirable_flags undesirable_flags)
telepathy-qt-0.9.6~git1/cmake/modules/FindDBus.cmake 0000664 0001750 0001750 00000002674 12470405660 020151 0 ustar jr jr # - Try to find the low-level D-Bus library
# Once done this will define
#
# DBUS_FOUND - system has D-Bus
# DBUS_INCLUDE_DIRS - the D-Bus include directories
# DBUS_INCLUDE_DIR - the D-Bus include directory
# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory
# DBUS_LIBRARIES - the libraries needed to use D-Bus
# Copyright (c) 2012, George Kiagiadakis
# Copyright (c) 2008, Kevin Kofler,
# modeled after FindLibArt.cmake:
# Copyright (c) 2006, Alexander Neundorf,
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if (NOT WIN32)
find_package(PkgConfig)
pkg_check_modules(PC_DBUS dbus-1)
endif (NOT WIN32)
find_path(DBUS_INCLUDE_DIR dbus/dbus.h
PATHS ${PC_DBUS_INCLUDE_DIRS}
PATH_SUFFIXES dbus-1.0
)
find_path(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h
PATHS ${PC_DBUS_INCLUDE_DIRS}
HINTS ${CMAKE_LIBRARY_PATH}/dbus-1.0/include
${CMAKE_SYSTEM_LIBRARY_PATH}/dbus-1.0/include
)
find_library(DBUS_LIBRARIES NAMES dbus-1
PATHS ${PC_DBUS_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DBus DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES)
set(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
mark_as_advanced(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/FindGIOUnix.cmake 0000664 0001750 0001750 00000001721 12470405660 020566 0 ustar jr jr # - Try to find the GIO unix libraries
# Once done this will define
#
# GIOUNIX_FOUND - system has GIO unix
# GIOUNIX_INCLUDE_DIR - the GIO unix include directory
#
# Copyright (C) 2011 Collabora Ltd.
# Copyright (C) 2011 Nokia Corporation
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(GIOUNIX_INCLUDE_DIR)
# Already in cache, be silent
set(GIOUNIX_FIND_QUIETLY TRUE)
endif(GIOUNIX_INCLUDE_DIR)
include(UsePkgConfig)
pkg_check_modules(PC_LibGIOUnix gio-unix-2.0)
find_path(GIOUNIX_MAIN_INCLUDE_DIR
NAMES gio/gunixconnection.h
HINTS ${PC_LibGIOUnix_INCLUDEDIR}
PATH_SUFFIXES gio-unix-2.0)
set(GIOUNIX_INCLUDE_DIR "${GIOUNIX_MAIN_INCLUDE_DIR}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GIOUNIX DEFAULT_MSG GIOUNIX_MAIN_INCLUDE_DIR)
mark_as_advanced(GIOUNIX_INCLUDE_DIR)
telepathy-qt-0.9.6~git1/cmake/modules/FindGIO.cmake 0000664 0001750 0001750 00000002131 12470405660 017716 0 ustar jr jr # - Try to find the GIO libraries
# Once done this will define
#
# GIO_FOUND - system has GIO
# GIO_INCLUDE_DIR - the GIO include directory
# GIO_LIBRARIES - GIO library
#
# Copyright (C) 2011 Collabora Ltd.
# Copyright (C) 2011 Nokia Corporation
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(GIO_INCLUDE_DIR AND GIO_LIBRARIES)
# Already in cache, be silent
set(GIO_FIND_QUIETLY TRUE)
endif(GIO_INCLUDE_DIR AND GIO_LIBRARIES)
include(UsePkgConfig)
pkg_check_modules(PC_LibGIO gio-2.0)
find_path(GIO_MAIN_INCLUDE_DIR
NAMES gio/gio.h
HINTS ${PC_LibGIO_INCLUDEDIR}
PATH_SUFFIXES glib-2.0)
find_library(GIO_LIBRARY
NAMES gio-2.0
HINTS ${PC_LibGIO_LIBDIR})
set(GIO_INCLUDE_DIR "${GIO_MAIN_INCLUDE_DIR}")
set(GIO_LIBRARIES "${GIO_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GIO DEFAULT_MSG GIO_LIBRARIES GIO_MAIN_INCLUDE_DIR)
mark_as_advanced(GIO_INCLUDE_DIR GIO_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/FindTelepathyFarstream.cmake 0000664 0001750 0001750 00000004203 12470405660 023106 0 ustar jr jr # - Try to find Telepathy-Farstream
# Once done this will define
#
# TELEPATHY_FARSTREAM_FOUND - system has TelepathyFarstream
# TELEPATHY_FARSTREAM_INCLUDE_DIR - the TelepathyFarstream include directory
# TELEPATHY_FARSTREAM_LIBRARIES - the libraries needed to use TelepathyFarstream
# TELEPATHY_FARSTREAM_DEFINITIONS - Compiler switches required for using TelepathyFarstream
# Copyright (c) 2010, Dario Freddi
# Copyright (c) 2011, Mateu Batle
#
# Redistribution and use is allowed according to the terms of the BSD license.
if (TELEPATHY_FARSTREAM_INCLUDE_DIR AND TELEPATHY_FARSTREAM_LIBRARIES)
# in cache already
set(TelepathyFarstream_FIND_QUIETLY TRUE)
else (TELEPATHY_FARSTREAM_INCLUDE_DIR AND TELEPATHY_FARSTREAM_LIBRARIES)
set(TelepathyFarstream_FIND_QUIETLY FALSE)
endif (TELEPATHY_FARSTREAM_INCLUDE_DIR AND TELEPATHY_FARSTREAM_LIBRARIES)
if (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the find_path() and find_library() calls
find_package(PkgConfig)
if (TELEPATHY_FARSTREAM_MIN_VERSION)
PKG_CHECK_MODULES(PC_TELEPATHY_FARSTREAM telepathy-farstream>=${TELEPATHY_FARSTREAM_MIN_VERSION})
else (TELEPATHY_FARSTREAM_MIN_VERSION)
PKG_CHECK_MODULES(PC_TELEPATHY_FARSTREAM telepathy-farstream)
endif (TELEPATHY_FARSTREAM_MIN_VERSION)
set(TELEPATHY_FARSTREAM_DEFINITIONS ${PC_TELEPATHY_FARSTREAM_CFLAGS_OTHER})
endif (NOT WIN32)
find_path(TELEPATHY_FARSTREAM_INCLUDE_DIR telepathy-farstream/telepathy-farstream.h
PATHS
${PC_TELEPATHY_FARSTREAM_INCLUDEDIR}
${PC_TELEPATHY_FARSTREAM_INCLUDE_DIRS}
PATH_SUFFIXES telepathy-1.0
)
find_library(TELEPATHY_FARSTREAM_LIBRARIES NAMES telepathy-farstream
PATHS
${PC_TELEPATHY_FARSTREAM_LIBDIR}
${PC_TELEPATHY_FARSTREAM_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TelepathyFarstream DEFAULT_MSG TELEPATHY_FARSTREAM_LIBRARIES
TELEPATHY_FARSTREAM_INCLUDE_DIR)
mark_as_advanced(TELEPATHY_FARSTREAM_INCLUDE_DIR TELEPATHY_FARSTREAM_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/FindQt.cmake 0000664 0001750 0001750 00000010125 12470405660 017666 0 ustar jr jr # - Searches for Qt4 or Qt5.
# Copyright (C) 2001-2009 Kitware, Inc.
# Copyright (C) 2011 Collabora Ltd.
# Copyright (C) 2011 Nokia Corporation
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF(DESIRED_QT_VERSION MATCHES 5)
# Qt5 was explicitly requested, so use its CMakeConfig instead of qmake which may not be at a global location
find_package(Qt5Core QUIET)
IF( Qt5Core_DIR )
SET(QT5_INSTALLED TRUE)
ENDIF( Qt5Core_DIR )
ENDIF(DESIRED_QT_VERSION MATCHES 5)
#Otherwise search for installed qmakes
IF(NOT QT5_INSTALLED)
IF(NOT QT_QMAKE_EXECUTABLE)
FIND_PROGRAM(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake qmake4 qmake-qt4 qmake5 qmake-qt5
PATHS "${QT_SEARCH_PATH}/bin" "$ENV{QTDIR}/bin")
SET(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE_FINDQT} CACHE PATH "Qt qmake program.")
ENDIF(NOT QT_QMAKE_EXECUTABLE)
# now find qmake
IF(QT_QMAKE_EXECUTABLE)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION)
IF(QTVERSION MATCHES "4.*")
SET(QT4_INSTALLED TRUE)
ENDIF(QTVERSION MATCHES "4.*")
IF(QTVERSION MATCHES "5.*")
SET(QT5_INSTALLED TRUE)
ENDIF(QTVERSION MATCHES "5.*")
ENDIF(QT_QMAKE_EXECUTABLE)
ENDIF(NOT QT5_INSTALLED)
IF(NOT DESIRED_QT_VERSION)
IF(QT4_INSTALLED)
SET(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 4 or 5")
ENDIF(QT4_INSTALLED)
IF(QT5_INSTALLED)
SET(DESIRED_QT_VERSION 5 CACHE STRING "Pick a version of Qt to use: 4 or 5")
ENDIF(QT5_INSTALLED)
ENDIF(NOT DESIRED_QT_VERSION)
IF(DESIRED_QT_VERSION MATCHES 4)
SET(Qt4_FIND_REQUIRED ${Qt_FIND_REQUIRED})
SET(Qt4_FIND_QUIETLY ${Qt_FIND_QUIETLY})
SET(QT_MIN_VERSION ${QT4_MIN_VERSION})
SET(QT_MAX_VERSION ${QT4_MAX_VERSION})
INCLUDE(FindQt4)
ENDIF(DESIRED_QT_VERSION MATCHES 4)
IF(DESIRED_QT_VERSION MATCHES 5)
SET(Qt5_FIND_REQUIRED ${Qt_FIND_REQUIRED})
SET(Qt5_FIND_QUIETLY ${Qt_FIND_QUIETLY})
SET(QT_MIN_VERSION ${QT5_MIN_VERSION})
SET(QT_MAX_VERSION ${QT5_MAX_VERSION})
INCLUDE(FindQt5)
ENDIF(DESIRED_QT_VERSION MATCHES 5)
IF(NOT QT4_INSTALLED AND NOT QT5_INSTALLED)
IF(Qt_FIND_REQUIRED)
MESSAGE(SEND_ERROR "CMake was unable to find any Qt versions, put qmake in your path, or set QTDIR/QT_QMAKE_EXECUTABLE.")
ENDIF(Qt_FIND_REQUIRED)
ELSE(NOT QT4_INSTALLED AND NOT QT5_INSTALLED)
IF(NOT QT_FOUND)
IF(Qt_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "CMake was unable to find Qt version: ${DESIRED_QT_VERSION}, put qmake in your path or set QTDIR/QT_QMAKE_EXECUTABLE.")
ELSE(Qt_FIND_REQUIRED)
MESSAGE("CMake was unable to find Qt version: ${DESIRED_QT_VERSION}, put qmake in your path or set QTDIR/QT_QMAKE_EXECUTABLE.")
ENDIF(Qt_FIND_REQUIRED)
ENDIF(NOT QT_FOUND)
ENDIF(NOT QT4_INSTALLED AND NOT QT5_INSTALLED)
MACRO(QT_GET_MOC_FLAGS moc_flags)
IF(QT_VERSION_MAJOR MATCHES 4)
QT4_GET_MOC_FLAGS(${moc_flags})
ELSE(QT_VERSION_MAJOR MATCHES 4)
IF(QT_VERSION_MAJOR MATCHES 5)
QT5_GET_MOC_FLAGS(${moc_flags})
ENDIF(QT_VERSION_MAJOR MATCHES 5)
ENDIF(QT_VERSION_MAJOR MATCHES 4)
ENDMACRO(QT_GET_MOC_FLAGS)
MACRO(QT_CREATE_MOC_COMMAND infile outfile moc_flags moc_options)
IF(QT_VERSION_MAJOR MATCHES 4)
IF(CMAKE_VERSION VERSION_GREATER 2.8.11.20130607)
QT4_CREATE_MOC_COMMAND(${infile} ${outfile} "${moc_flags}" "${moc_options}" "")
ELSE(CMAKE_VERSION VERSION_GREATER 2.8.11.20130607)
QT4_CREATE_MOC_COMMAND(${infile} ${outfile} "${moc_flags}" "${moc_options}")
ENDIF(CMAKE_VERSION VERSION_GREATER 2.8.11.20130607)
ELSE(QT_VERSION_MAJOR MATCHES 4)
IF(QT_VERSION_MAJOR MATCHES 5)
IF(QTVERSION VERSION_GREATER 5.1.99)
QT5_CREATE_MOC_COMMAND(${infile} ${outfile} "${moc_flags}" "${moc_options}" "")
ELSE()
QT5_CREATE_MOC_COMMAND(${infile} ${outfile} "${moc_flags}" "${moc_options}")
ENDIF()
ENDIF(QT_VERSION_MAJOR MATCHES 5)
ENDIF(QT_VERSION_MAJOR MATCHES 4)
ENDMACRO(QT_CREATE_MOC_COMMAND)
MARK_AS_ADVANCED(QT_QMAKE_EXECUTABLE_FINDQT)
telepathy-qt-0.9.6~git1/cmake/modules/FindGLIB2.cmake 0000664 0001750 0001750 00000003210 12470405660 020076 0 ustar jr jr # - Try to find the GLIB2 libraries
# Once done this will define
#
# GLIB2_FOUND - system has glib2
# GLIB2_INCLUDE_DIR - the glib2 include directory
# GLIB2_LIBRARIES - glib2 library
# Copyright (c) 2008 Laurent Montel,
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
# Already in cache, be silent
set(GLIB2_FIND_QUIETLY TRUE)
endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
find_package(PkgConfig)
pkg_check_modules(PC_LibGLIB2 glib-2.0)
find_path(GLIB2_MAIN_INCLUDE_DIR
NAMES glib.h
HINTS ${PC_LibGLIB2_INCLUDEDIR}
PATH_SUFFIXES glib-2.0)
find_library(GLIB2_LIBRARY
NAMES glib-2.0
HINTS ${PC_LibGLIB2_LIBDIR}
)
set(GLIB2_LIBRARIES ${GLIB2_LIBRARY})
# search the glibconfig.h include dir under the same root where the library is found
get_filename_component(glib2LibDir "${GLIB2_LIBRARIES}" PATH)
find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h
PATH_SUFFIXES glib-2.0/include
HINTS ${PC_LibGLIB2_INCLUDEDIR} "${glib2LibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH})
set(GLIB2_INCLUDE_DIR "${GLIB2_MAIN_INCLUDE_DIR}")
# not sure if this include dir is optional or required
# for now it is optional
if(GLIB2_INTERNAL_INCLUDE_DIR)
set(GLIB2_INCLUDE_DIR ${GLIB2_INCLUDE_DIR} "${GLIB2_INTERNAL_INCLUDE_DIR}")
endif(GLIB2_INTERNAL_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR)
mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES)
telepathy-qt-0.9.6~git1/cmake/modules/TpQtMacros.cmake 0000664 0001750 0001750 00000067034 12470405660 020551 0 ustar jr jr # - Common macros for Tp-Qt
# Copyright (c) 2010, Collabora Ltd.
#
# Redistribution and use is allowed according to the terms of the BSD license.
#
# These macros/functions are not exported - they are meant for internal usage into Telepathy-Qt's build system.
#
# Preamble: How dynamic generators are handled with the CMake build system.
# Telepathy-Qt strongly relies upon lots of files generated at build time through some python programs, found
# in tools/. To avoid developers the struggle of handling those manually, a set of convenience macros have been
# created to handle them with the correct dependencies. Each of those macros takes a target name as a first argument
# and creates a target with that exact name. In a similar fashion, in the last argument you can specify a list
# of targets the generated target will depend on. This way, you can handle transparently dependencies between
# generated files, while the dirty stuff is done for you in the background.
#
# macro TPQT_EXTRACT_DEPENDS (tpqt_other tpqt_depends)
# Internal macro used to extract arguments from ARGN
#
# function TPQT_CREATE_MOC_COMMAND_TARGET_DEPS(inputfile outputfile moc_flags moc_options target_dependencies ...)
# This function behaves exactly like qt_create_moc_command, but creates a custom target for the
# moc file generation, allowing to specify a list of targets the generated moc target will depend on.
# Just like qt_create_moc_command, it is an internal macro and it's not meant to be used explicitely.
#
# function TPQT_GENERATE_MOC_I(inputfile outputfile)
# This function behaves exactly like qt_generate_moc, but it generates moc files with the -i option,
# which disables the generation of an #include directive. This macro has to be used always when building
# Tp-Qt internals due to the internal header files restrictions.
#
# function TPQT_GENERATE_MOC_I_TARGET_DEPS(inputfile outputfile target_dependencies ...)
# This function acts as an overload to QT_GENERATE_MOC_I: it does exactly the same thing, but creates a
# custom target for the moc file generation, and adds target_dependencies to it as dependencies.
#
# function TPQT_GENERATE_MOCS(sourcefile ...)
# Generates mocs from a list of header files. You usually want to use this function when building tests
# or examples. Please remember the list of the header files passed to this function MUST be added to the
# target's sources.
#
# function TPQT_CLIENT_GENERATOR(spec group pretty_include namespace [arguments] [DEPENDS dependencies ...])
# This function takes care of invoking qt-client-gen.py with the correct arguments, which generates
# headers out of specs. spec is the name of the spec headers will be generated from, group represents
# the spec's group, pretty_include is the name of the capitalized header (for example ClientGenerator),
# namespace is the C++ namespace the generated header will belong to. This function also accepts
# as an optional last argument a list of additional command line arguments which will be passed to
# qt-client-gen.py upon execution. After issuing DEPENDS in the last argument you can pass a list of targets
# the generated target will depend on.
#
# function TPQT_FUTURE_CLIENT_GENERATOR(spec namespace [arguments] [DEPENDS dependencies ...])
# Same as tpqt_client_generator, but for future interfaces
#
# function TPQT_SERVICE_GENERATOR(spec group pretty_include namespace [arguments] [DEPENDS dependencies ...])
# This function takes care of invoking qt-svc-gen.py with the correct arguments, which generates
# headers out of specs. spec is the name of the spec headers will be generated from, group represents
# the spec's group, pretty_include is the name of the capitalized header (for example ServiceGenerator),
# namespace is the C++ namespace the generated header will belong to. This function also accepts
# as an optional last argument a list of additional command line arguments which will be passed to
# qt-svc-gen.py upon execution. After issuing DEPENDS in the last argument you can pass a list of targets
# the generated target will depend on.
#
# function TPQT_GENERATE_MANAGER_FILE(MANAGER_FILE OUTPUT_FILENAME DEPEND_FILENAME)
# This function takes care of invoking manager-file.py with the correct arguments. The first argument is the
# path to the manager-file.py file which should be used, the second is the output filename of the manager,
# and the third is the path to the file which depends on the generated manager file.
#
# function TPQT_XINCLUDATOR (TARGET_NAME INPUT_FILE OUTPUT_FILE [additional_arguments ...] [DEPENDS dependencies ...])
# This function takes care of invoking xincludator.py with the correct arguments. TARGET_NAME is the name of
# the generated target (see preamble), INPUT_FILE is the input spec file, OUTPUT_FILE is the filename
# the generated file will be saved to. This function also accepts as an optional last argument a list of
# additional command line arguments which will be passed to xincludator upon execution.
# After issuing DEPENDS in the last argument you can pass a list of targets the generated target will depend on.
#
# function TPQT_CONSTANTS_GEN (TARGET_NAME SPEC_XML OUTPUT_FILE [additional_arguments ...] [DEPENDS dependencies ...])
# This function takes care of invoking qt-constants-gen.py with the correct arguments. TARGET_NAME is the name of
# the generated target (see preamble), SPEC_XML is the spec input file, OUTPUT_FILE is the filename
# the generated file will be saved to. This function also accepts as an optional last argument a list of
# additional command line arguments which will be passed to qt-constants-gen.py upon execution.
# After issuing DEPENDS in the last argument you can pass a list of targets the generated target will depend on.
#
# function TPQT_TYPES_GEN (TARGET_NAME SPEC_XML OUTFILE_DECL OUTFILE_IMPL NAMESPACE
# REAL_INCLUDE PRETTY_INCLUDE [additional_arguments ...] [DEPENDS dependencies ...])
# This function takes care of invoking qt-types-gen.py with the correct arguments. TARGET_NAME is the name of
# the generated target (see preamble), SPEC_XML is the input spec file, OUTFILE_DECL is the filename
# the header of the generated file will be saved to, OUTFILE_IMPL is the filename the implementation of the
# generated file will be saved to, NAMESPACE is the C++ namespace the generated header will belong to,
# REAL_INCLUDE is the real include file you want to use, PRETTY_INCLUDE is the name of the capitalized header
# (for example ClientGenerator).
# This function also accepts as an optional last argument a list of additional command line arguments
# which will be passed to qt-constants-gen.py upon execution.
# After issuing DEPENDS in the last argument you can pass a list of targets the generated target will depend on.
#
# macro TPQT_ADD_GENERIC_UNIT_TEST (fancyName name [libraries ...])
# This macro takes care of building and adding a generic unit test to the automatic CTest suite. The requirement
# for using this macro is to have the unit test contained in a single source file named ${name}.cpp. fancyName will
# be used as the test and target's name, and you can specify as a third and optional argument a set of additional
# libraries the target will link to.
#
# macro TPQT_ADD_DBUS_UNIT_TEST (fancyName name [libraries ...])
# This macro takes care of building and adding an unit test requiring DBus emulation to the automatic
# CTest suite. The requirement for using this macro is to have the unit test contained in a single
# source file named ${name}.cpp. fancyName will be used as the test and target's name, and you can specify as a third
# and optional argument a set of additional libraries the target will link to. Please remember that you need to
# set up the DBus environment by calling TPQT_SETUP_DBUS_TEST_ENVIRONMENT BEFORE you call this macro.
#
# macro _TPQT_ADD_CHECK_TARGETS (fancyName name command [args])
# This is an internal macro which is meant to be used by TPQT_ADD_DBUS_UNIT_TEST and TPQT_ADD_GENERIC_UNIT_TEST.
# It takes care of generating a check target for each test method available (currently normal execution, valgrind and
# callgrind). This macro accepts the same arguments as the add test macros, but accepts a command and a list of
# arguments for running the test instead of the link libraries. However, you are not meant to call this macro from
# your CMakeLists.txt files.
#
# function TPQT_SETUP_DBUS_TEST_ENVIRONMENT ()
# This function MUST be called before calling TPQT_ADD_DBUS_UNIT_TEST. It takes care of preparing the test
# environment for DBus tests and generating the needed files.
#
# macro MAKE_INSTALL_PATH_ABSOLUTE (out in)
# This macro makes the path given in the "in" variable absolute (or leaves it unchanged
# if it's absolute already) by prefixing it with TELEPATHY_QT_INSTALL_DIR,
# and returns the absolute path in the "out" variable. This macro is mainly used for
# generating *Config.cmake files.
#
#
MACRO (TPQT_EXTRACT_DEPENDS _tpqt_other _tpqt_depends)
SET(${_tpqt_other})
SET(${_tpqt_depends})
SET(_TPQT_DOING_DEPENDS FALSE)
FOREACH(_currentArg ${ARGN})
IF ("${_currentArg}" STREQUAL "DEPENDS")
SET(_TPQT_DOING_DEPENDS TRUE)
ELSE ("${_currentArg}" STREQUAL "DEPENDS")
IF(_TPQT_DOING_DEPENDS)
LIST(APPEND ${_tpqt_depends} "${_currentArg}")
ELSE(_TPQT_DOING_DEPENDS)
LIST(APPEND ${_tpqt_other} "${_currentArg}")
ENDIF(_TPQT_DOING_DEPENDS)
ENDIF ("${_currentArg}" STREQUAL "DEPENDS")
ENDFOREACH(_currentArg)
ENDMACRO (TPQT_EXTRACT_DEPENDS)
# helper function to set up a moc rule
FUNCTION (TPQT_CREATE_MOC_COMMAND_TARGET_DEPS infile outfile moc_flags moc_options)
# For Windows, create a parameters file to work around command line length limit
GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME)
IF (WIN32)
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
# just the file name. This is necessary because the moc tool on
# MinGW builds does not seem to handle spaces in the path to the
# file given with the @ syntax.
GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH)
IF(_moc_outfile_dir)
SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir})
ENDIF(_moc_outfile_dir)
SET (_moc_parameters_file ${outfile}_parameters)
SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}")
FILE (REMOVE ${_moc_parameters_file})
FOREACH(arg ${_moc_parameters})
FILE (APPEND ${_moc_parameters_file} "${arg}\n")
ENDFOREACH(arg)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters
DEPENDS ${infile}
${_moc_working_dir}
VERBATIM)
ELSE (WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile}
DEPENDS ${infile})
ENDIF (WIN32)
add_custom_target(moc-${_moc_outfile_name} DEPENDS ${outfile})
add_dependencies(moc-${_moc_outfile_name} ${ARGN})
ENDFUNCTION (TPQT_CREATE_MOC_COMMAND_TARGET_DEPS)
# add the -i option to QT_GENERATE_MOC
function(TPQT_GENERATE_MOC_I infile outfile)
qt_get_moc_flags(moc_flags)
get_filename_component(abs_infile ${infile} ABSOLUTE)
qt_create_moc_command(${abs_infile} ${outfile} "${moc_flags}" "-i")
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
endfunction(TPQT_GENERATE_MOC_I)
# same as tpqt_generate_moc_i, but lets the caller specify a list of targets which the mocs should depend on
function(TPQT_GENERATE_MOC_I_TARGET_DEPS infile outfile)
qt_get_moc_flags(moc_flags)
get_filename_component(abs_infile ${infile} ABSOLUTE)
tpqt_create_moc_command_target_deps(${abs_infile} ${outfile} "${moc_flags}" "-i" ${ARGN})
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
endfunction(TPQT_GENERATE_MOC_I_TARGET_DEPS)
# generates mocs for the passed list. The list should be added to the target's sources
function(tpqt_generate_mocs)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_gen" )
foreach(moc_src ${ARGN})
string(REPLACE ".h" ".moc.hpp" generated_file ${moc_src})
tpqt_generate_moc_i(${CMAKE_CURRENT_SOURCE_DIR}/${moc_src} ${CMAKE_CURRENT_BINARY_DIR}/_gen/${generated_file})
set_property(SOURCE ${moc_src} APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_gen/${generated_file})
endforeach(moc_src ${ARGN})
endfunction(tpqt_generate_mocs)
function(tpqt_client_generator spec group pretty_include namespace)
tpqt_extract_depends(client_generator_args client_generator_depends ${ARGN})
set(ARGS
${CMAKE_SOURCE_DIR}/tools/qt-client-gen.py
--group=${group}
--namespace=${namespace}
--typesnamespace=Tp
--headerfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}.h
--implfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}-body.hpp
--realinclude=TelepathyQt/${spec}.h
--prettyinclude=TelepathyQt/${pretty_include}
--specxml=${CMAKE_CURRENT_BINARY_DIR}/_gen/stable-spec.xml
--ifacexml=${CMAKE_CURRENT_BINARY_DIR}/_gen/spec-${spec}.xml
--extraincludes=${TYPES_INCLUDE}
--must-define=IN_TP_QT_HEADER
--visibility=TP_QT_EXPORT
${client_generator_args})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}.h ${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}-body.hpp
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${ARGS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/libqtcodegen.py
${CMAKE_SOURCE_DIR}/tools/qt-client-gen.py)
add_custom_target(generate_cli-${spec}-body DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}-body.hpp)
add_dependencies(all-generated-sources generate_cli-${spec}-body)
if (client_generator_depends)
add_dependencies(generate_cli-${spec}-body ${client_generator_depends})
endif (client_generator_depends)
tpqt_generate_moc_i_target_deps(${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}.h
${CMAKE_CURRENT_BINARY_DIR}/_gen/cli-${spec}.moc.hpp
"generate_cli-${spec}-body")
endfunction(tpqt_client_generator spec group pretty_include namespace)
function(tpqt_future_client_generator spec namespace)
tpqt_extract_depends(future_client_generator_args future_client_generator_depends ${ARGN})
set(ARGS
${CMAKE_SOURCE_DIR}/tools/qt-client-gen.py
--namespace=${namespace}
--typesnamespace=TpFuture
--headerfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}.h
--implfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}-body.hpp
--realinclude=TelepathyQt/future-internal.h
--prettyinclude=TelepathyQt/future-internal.h
--specxml=${CMAKE_CURRENT_BINARY_DIR}/_gen/future-spec.xml
--ifacexml=${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}.xml
--extraincludes=${TYPES_INCLUDE}
--extraincludes=''
--extraincludes=''
--visibility=TP_QT_NO_EXPORT
${future_client_generator_args})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}.h ${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}-body.hpp
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${ARGS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/libqtcodegen.py
${CMAKE_SOURCE_DIR}/tools/qt-client-gen.py)
add_custom_target(generate_future-${spec}-body DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}-body.hpp)
add_dependencies(all-generated-sources generate_future-${spec}-body)
if (future_client_generator_depends)
add_dependencies(generate_future-${spec}-body ${future_client_generator_depends})
endif (future_client_generator_depends)
tpqt_generate_moc_i_target_deps(${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}.h
${CMAKE_CURRENT_BINARY_DIR}/_gen/future-${spec}.moc.hpp
"generate_future-${spec}-body")
endfunction(tpqt_future_client_generator spec namespace)
function(tpqt_service_generator spec group pretty_include namespace)
tpqt_extract_depends(service_generator_args service_generator_depends ${ARGN})
string(REPLACE "svc-" "" spec ${spec})
set(ARGS
${CMAKE_SOURCE_DIR}/tools/qt-svc-gen.py
--group=${group}
--namespace=${namespace}
--typesnamespace=Tp
--headerfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.h
--implfile=${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.cpp
--realinclude=TelepathyQt/_gen/svc-${spec}.h
--mocinclude=TelepathyQt/_gen/svc-${spec}.moc.hpp
--specxml=${CMAKE_CURRENT_BINARY_DIR}/_gen/stable-spec.xml
--ifacexml=${CMAKE_CURRENT_BINARY_DIR}/_gen/spec-svc-${spec}.xml
--visibility=TP_QT_EXPORT
${service_generator_args})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.h ${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.cpp
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${ARGS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/libqtcodegen.py
${CMAKE_SOURCE_DIR}/tools/qt-svc-gen.py)
add_custom_target(generate_service-${spec}-body DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.cpp)
add_dependencies(all-generated-service-sources generate_service-${spec}-body)
if (service_generator_depends)
add_dependencies(generate_service-${spec}-body ${service_generator_depends})
endif (service_generator_depends)
tpqt_generate_moc_i_target_deps(${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.h
${CMAKE_CURRENT_BINARY_DIR}/_gen/svc-${spec}.moc.hpp
"generate_service-${spec}-body")
endfunction(tpqt_service_generator spec group pretty_include namespace)
# This function is used for generating CM in various examples
function(tpqt_generate_manager_file MANAGER_FILE OUTPUT_FILENAME DEPEND_FILENAME)
# make_directory is required, otherwise the command won't work!!
make_directory(${CMAKE_CURRENT_BINARY_DIR}/_gen)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_gen/param-spec-struct.h
${CMAKE_CURRENT_BINARY_DIR}/_gen/${OUTPUT_FILENAME}
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${CMAKE_SOURCE_DIR}/tools/manager-file.py
${MANAGER_FILE}
_gen
DEPENDS ${CMAKE_SOURCE_DIR}/tools/manager-file.py)
set_source_files_properties(${DEPEND_FILENAME}
PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_gen/param-spec-struct.h)
endfunction(tpqt_generate_manager_file MANAGER_FILE)
function(tpqt_xincludator _TARGET_NAME _INPUT_FILE _OUTPUT_FILE)
tpqt_extract_depends(xincludator_gen_args xincludator_gen_depends ${ARGN})
# Gather all .xml files in TelepathyQt and spec/ and make this target depend on those
file(GLOB depends_xml_files ${CMAKE_SOURCE_DIR}/TelepathyQt/*.xml ${CMAKE_SOURCE_DIR}/spec/*.xml)
add_custom_command(OUTPUT ${_OUTPUT_FILE}
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${CMAKE_SOURCE_DIR}/tools/xincludator.py
${_INPUT_FILE}
${xincludator_gen_args}
> ${_OUTPUT_FILE}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/xincludator.py
${_INPUT_FILE} ${depends_xml_files})
add_custom_target(${_TARGET_NAME} DEPENDS ${_OUTPUT_FILE})
if (xincludator_gen_depends)
add_dependencies(${_TARGET_NAME} ${xincludator_gen_depends})
endif (xincludator_gen_depends)
endfunction(tpqt_xincludator _TARGET_NAME _INPUT_FILE _OUTPUT_FILE)
function(tpqt_constants_gen _TARGET_NAME _SPEC_XML _OUTFILE)
tpqt_extract_depends(constants_gen_args constants_gen_depends ${ARGN})
# Gather all .xml files in TelepathyQt and spec/ and make this target depend on those
file(GLOB depends_xml_files ${CMAKE_SOURCE_DIR}/TelepathyQt/*.xml ${CMAKE_SOURCE_DIR}/spec/*.xml)
add_custom_command(OUTPUT ${_OUTFILE}
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${CMAKE_SOURCE_DIR}/tools/qt-constants-gen.py
${constants_gen_args}
--specxml=${_SPEC_XML}
> ${_OUTFILE}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/libqtcodegen.py
${CMAKE_SOURCE_DIR}/tools/qt-constants-gen.py
${_SPEC_XML} ${depends_xml_files})
add_custom_target(${_TARGET_NAME} DEPENDS ${_OUTFILE})
add_dependencies(all-generated-sources ${_TARGET_NAME})
if (constants_gen_depends)
add_dependencies(${_TARGET_NAME} ${constants_gen_depends})
endif (constants_gen_depends)
endfunction (tpqt_constants_gen _TARGET_NAME _SPEC_XML _OUTFILE)
function(tpqt_types_gen _TARGET_NAME _SPEC_XML _OUTFILE_DECL _OUTFILE_IMPL _NAMESPACE _REALINCLUDE _PRETTYINCLUDE)
tpqt_extract_depends(types_gen_args types_gen_depends ${ARGN})
# Gather all .xml files in TelepathyQt and spec/ and make this target depend on those
file(GLOB depends_xml_files ${CMAKE_SOURCE_DIR}/TelepathyQt/*.xml ${CMAKE_SOURCE_DIR}/spec/*.xml)
add_custom_command(OUTPUT ${_OUTFILE_DECL} ${_OUTFILE_IMPL}
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${CMAKE_SOURCE_DIR}/tools/qt-types-gen.py
--namespace=${_NAMESPACE}
--declfile=${_OUTFILE_DECL}
--implfile=${_OUTFILE_IMPL}
--realinclude=${_REALINCLUDE}
--prettyinclude=${_PRETTYINCLUDE}
${types_gen_args}
--specxml=${_SPEC_XML}
DEPENDS ${CMAKE_SOURCE_DIR}/tools/libqtcodegen.py
${CMAKE_SOURCE_DIR}/tools/qt-types-gen.py
${_SPEC_XML} ${depends_xml_files})
add_custom_target(${_TARGET_NAME} DEPENDS ${_OUTFILE_IMPL})
add_dependencies(all-generated-sources ${_TARGET_NAME})
if (types_gen_depends)
add_dependencies(${_TARGET_NAME} ${types_gen_depends})
endif (types_gen_depends)
endfunction(tpqt_types_gen _TARGET_NAME _SPEC_XML _OUTFILE_DECL _OUTFILE_IMPL _NAMESPACE _REALINCLUDE _PRETTYINCLUDE)
macro(tpqt_add_generic_unit_test _fancyName _name)
tpqt_generate_moc_i(${_name}.cpp ${CMAKE_CURRENT_BINARY_DIR}/_gen/${_name}.cpp.moc.hpp)
add_executable(test-${_name} ${_name}.cpp ${CMAKE_CURRENT_BINARY_DIR}/_gen/${_name}.cpp.moc.hpp)
target_link_libraries(test-${_name} ${QT_QTCORE_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} telepathy-qt${QT_VERSION_MAJOR} tp-qt-tests ${TP_QT_EXECUTABLE_LINKER_FLAGS} ${ARGN})
add_test(${_fancyName} ${SH} ${CMAKE_CURRENT_BINARY_DIR}/runGenericTest.sh ${CMAKE_CURRENT_BINARY_DIR}/test-${_name})
list(APPEND _telepathy_qt_test_cases test-${_name})
# Valgrind and Callgrind targets
_tpqt_add_check_targets(${_fancyName} ${_name} ${CMAKE_CURRENT_BINARY_DIR}/runGenericTest.sh ${CMAKE_CURRENT_BINARY_DIR}/test-${_name})
endmacro(tpqt_add_generic_unit_test _fancyName _name)
macro(tpqt_add_dbus_unit_test _fancyName _name)
tpqt_generate_moc_i(${_name}.cpp ${CMAKE_CURRENT_BINARY_DIR}/_gen/${_name}.cpp.moc.hpp)
add_executable(test-${_name} ${_name}.cpp ${CMAKE_CURRENT_BINARY_DIR}/_gen/${_name}.cpp.moc.hpp)
target_link_libraries(test-${_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} telepathy-qt${QT_VERSION_MAJOR} tp-qt-tests ${TP_QT_EXECUTABLE_LINKER_FLAGS} ${ARGN})
set(with_session_bus ${CMAKE_CURRENT_BINARY_DIR}/runDbusTest.sh)
add_test(${_fancyName} ${SH} ${with_session_bus} ${CMAKE_CURRENT_BINARY_DIR}/test-${_name})
list(APPEND _telepathy_qt_test_cases test-${_name})
# Valgrind and Callgrind targets
_tpqt_add_check_targets(${_fancyName} ${_name} ${with_session_bus} ${CMAKE_CURRENT_BINARY_DIR}/test-${_name})
endmacro(tpqt_add_dbus_unit_test _fancyName _name)
macro(_tpqt_add_check_targets _fancyName _name _runnerScript)
set_tests_properties(${_fancyName}
PROPERTIES
FAIL_REGULAR_EXPRESSION "^FAIL!")
# Standard check target
add_custom_target(check-${_fancyName} ${SH} ${_runnerScript} ${ARGN})
add_dependencies(check-${_fancyName} test-${_name})
# Lcov target
add_dependencies(lcov-check test-${_name})
# Valgrind target
add_custom_target(check-valgrind-${_fancyName})
add_dependencies(check-valgrind-${_fancyName} test-${_name})
add_custom_command(
TARGET check-valgrind-${_fancyName}
COMMAND G_SLICE=always-malloc ${SH} ${_runnerScript} /usr/bin/valgrind
--tool=memcheck
--leak-check=full
--leak-resolution=high
--child-silent-after-fork=yes
--num-callers=20
--gen-suppressions=all
--log-file=${CMAKE_CURRENT_BINARY_DIR}/test-${_fancyName}.memcheck.log
--suppressions=${CMAKE_SOURCE_DIR}/tools/tp-qt-tests.supp
--suppressions=${CMAKE_SOURCE_DIR}/tools/telepathy-glib.supp
${ARGN}
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running valgrind on test \"${_fancyName}\"")
add_dependencies(check-valgrind check-valgrind-${_fancyName})
# Callgrind target
add_custom_target(check-callgrind-${_fancyName})
add_dependencies(check-callgrind-${_fancyName} test-${_name})
add_custom_command(
TARGET check-callgrind-${_fancyName}
COMMAND ${SH} ${_runnerScript} /usr/bin/valgrind
--tool=callgrind
--dump-instr=yes
--log-file=${CMAKE_CURRENT_BINARY_DIR}/test-${_fancyName}.callgrind.log
--callgrind-out-file=${CMAKE_CURRENT_BINARY_DIR}/test-${_fancyName}.callgrind.out
${ARGN}
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
COMMENT
"Running callgrind on test \"${_fancyName}\"")
add_dependencies(check-callgrind check-callgrind-${_fancyName})
endmacro(_tpqt_add_check_targets _fancyName _name)
function(tpqt_setup_dbus_test_environment)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/runDbusTest.sh "
${test_environment}
sh ${CMAKE_SOURCE_DIR}/tools/with-session-bus.sh \\
--config-file=${CMAKE_BINARY_DIR}/tests/dbus-1/session.conf -- $@
")
endfunction(tpqt_setup_dbus_test_environment)
macro(make_install_path_absolute out in)
if (IS_ABSOLUTE "${in}")
set(${out} "${in}")
else (IS_ABSOLUTE "${in}")
set(${out} "\${TELEPATHY_QT${QT_VERSION_MAJOR}_INSTALL_DIR}/${in}")
endif (IS_ABSOLUTE "${in}")
endmacro(make_install_path_absolute out in)
telepathy-qt-0.9.6~git1/cmake/modules/FindLibXml2.cmake 0000664 0001750 0001750 00000003561 12470405660 020561 0 ustar jr jr # - Try to find LibXml2
# Once done this will define
#
# LIBXML2_FOUND - System has LibXml2
# LIBXML2_INCLUDE_DIR - The LibXml2 include directory
# LIBXML2_LIBRARIES - The libraries needed to use LibXml2
# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
# Copyright (c) 2006, Alexander Neundorf,
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES)
# in cache already
SET(LibXml2_FIND_QUIETLY TRUE)
ENDIF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES)
IF (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_LIBXML libxml-2.0)
SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
ENDIF (NOT WIN32)
FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h
HINTS
${PC_LIBXML_INCLUDEDIR}
${PC_LIBXML_INCLUDE_DIRS}
PATH_SUFFIXES libxml2
)
FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2
HINTS
${PC_LIBXML_LIBDIR}
${PC_LIBXML_LIBRARY_DIRS}
)
FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint)
# for backwards compat. with KDE 4.0.x:
SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
IF( NOT LIBXML2_XMLLINT_EXECUTABLE )
MESSAGE(STATUS "xmllint program not found. Install it if you want validate generated doc file.")
ENDIF(NOT LIBXML2_XMLLINT_EXECUTABLE )
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
telepathy-qt-0.9.6~git1/HACKING 0000664 0001750 0001750 00000011364 12470405660 013744 0 ustar jr jr Contents:
• Version control
• Coding style...
› ...for C++ code
› ...for C and Python code
• Submitting patches
===============================================================================
Version control
===============================================================================
The current development version of telepathy-qt is available from the
'master' branch in the git repository:
(for committers)
(cgit)
Stable branches are available from branches with names like
'telepathy-qt-0.2' in the same repository.
===============================================================================
Coding style
===============================================================================
For C++ code:
-------------
TelepathyQt uses the standard Qt coding style for the Qt/C++ code, as also
followed by eg. KDELibs. The coding style is described in more detail in the
KDE TechBase at ; in
short, it amounts to:
* 4 spaces for indentation (no tabs, anywhere)
* javaCase for variables and functions (incl. members), FullCamelCase for types
* No abbreviations, except for 100% standard ones like regex, refcount, etc.
* Type &var and Type *var, not Type& var and Type* var for pointers and refs
* Use only one empty line to separate both groups of related statements AND
function & class bodies
* Use a space after each keyword but none after opening parens (if (true))
* No spaces between the function name and the parens for the parameter list
* Surround binary operators with spaces, but don't put spaces between a unary
operator and their operand
* For function bodies, put the opening curly brace on its own line. For
everything else, put the opening curly brace in the same line as the
statement (if, for, etc.) associated with it.
* Use curly braces even for single-line bodies of conditional statements and
loops
* Prefer static_cast, const_cast etc over C-style casts
* Wrap long lines to 100 characters at most
* Use foreach, emit instead of Q_FOREACH/Q_EMIT
* Don't write long (> ~5 lines) inline methods unless they are needed because of
eg. template
* Don't use references to QObjects
* Destroy transient objects such as method call watchers as soon as possible
rather than accumulating them to long-lived parent objects
* Documentation should be in the source file instead of the header file
* Public xxxInterface methods' definitions should be added to the end of the
public methods declaration.
* Always add friend struct Private declaration on classes that have Private
structure.
* Always add Q_DISABLE_COPY(xxx) to classes that cannot be copied.
* Q_DISABLE_COPY(xxx) declaration must be placed on the top of the class
definition, before the public keyword.
* Methods should be ordered as follows:
public
public Q_SLOTS
Q_SIGNALS
protected
protected Q_SLOTS
private Q_SLOTS
private
* friend class xxx definitions must be placed right below the private keyword.
* All exported classes should use TP_QT_EXPORT macro as following:
class TP_QT_EXPORT xxx { ... };
* Every issue in APIs which can (or will) only be fixed later should be marked
with a doxygen \todo and have a corresponding fd.o bug filed and mentioned in
the \todo annotation
For C and Python code:
----------------------
Parts of the regression tests — namely, those parts in tests/lib/glib/ — are
taken from telepathy-glib, and are written in C; the majority of the code
generation tools — in tools/ — are written in Python. Please follow
for these.
===============================================================================
Submitting patches
===============================================================================
Patches should be made as (preferably) git branches or (last resort) -uNr diffs
against upstream git master, as found at:
git://anongit.freedesktop.org/telepathy/telepathy-qt
ssh://git.freedesktop.org/git/telepathy/telepathy-qt (for committers)
http://cgit.freedesktop.org/telepathy/telepathy-qt/ (cgit)
Patches can be announced at the freedesktop.org bugzilla, using the product
"Telepathy" and component "tp-qt":
https://bugs.freedesktop.org/enter_bug.cgi?product=Telepathy&component=tp-qt
If submitting a Git branch, please set the URL field of the bug to point to
your Git branch. Regardless of whether you are referring to a Git branch or
attaching patches, please specify the "patch" keyword on the bug.
For details on the code review procedure, see:
http://telepathy.freedesktop.org/wiki/Review%20Procedure
telepathy-qt-0.9.6~git1/doxygen.css 0000664 0001750 0001750 00000013170 12470405660 015141 0 ustar jr jr body, table, div, p, dl {
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
font-size: 12px;
}
/* @group Heading Levels */
h1 {
text-align: center;
font-size: 150%;
}
h2 {
font-size: 110%;
font-weight: bold;
}
h3 {
font-size: 100%;
}
h3.version {
font-size: 100%;
text-align: center;
}
/* @end */
caption {
font-weight: bold;
}
div.title{
font-size: 150%;
text-align: center;
margin: 2px;
padding: 2px;
}
div.qindex, div.navtab{
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
}
div.qindex, div.navpath {
width: 100%;
line-height: 140%;
}
div.navtab {
margin-right: 15px;
}
/* @group Link Styling */
a {
color: #153788;
font-weight: normal;
text-decoration: none;
}
.contents a:visited {
color: #1b77c5;
}
a:hover {
text-decoration: underline;
}
a.qindex {
font-weight: bold;
}
a.qindexHL {
font-weight: bold;
background-color: #6666cc;
color: #ffffff;
border: 1px double #9295C2;
}
.contents a.qindexHL:visited {
color: #ffffff;
}
a.el {
}
a.elRef {
}
a.code {
}
a.codeRef {
}
/* @end */
dl.el {
margin-left: -1cm;
}
.fragment {
font-family: monospace, fixed;
font-size: 100%;
}
pre.fragment {
border: 1px solid #CCCCCC;
background-color: #f5f5f5;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
}
div.ah {
background-color: black;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
margin-top: 3px
}
div.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: bold;
}
div.groupText {
margin-left: 16px;
font-style: italic;
}
body {
background: white;
color: black;
margin-right: 20px;
margin-left: 20px;
}
td.indexkey {
background-color: #e8eef2;
font-weight: bold;
border: 1px solid #CCCCCC;
margin: 2px 0px 2px 0;
padding: 2px 10px;
}
td.indexvalue {
background-color: #e8eef2;
border: 1px solid #CCCCCC;
padding: 2px 10px;
margin: 2px 0px;
}
tr.memlist {
background-color: #f0f0f0;
}
p.formulaDsp {
text-align: center;
}
img.formulaDsp {
}
img.formulaInl {
vertical-align: middle;
}
/* @group Code Colorization */
span.keyword {
color: #008000
}
span.keywordtype {
color: #604020
}
span.keywordflow {
color: #e08000
}
span.comment {
color: #800000
}
span.preprocessor {
color: #806020
}
span.stringliteral {
color: #002080
}
span.charliteral {
color: #008080
}
span.vhdldigit {
color: #ff00ff
}
span.vhdlchar {
color: #000000
}
span.vhdlkeyword {
color: #700070
}
span.vhdllogic {
color: #ff0000
}
/* @end */
.search {
color: #003399;
font-weight: bold;
}
form.search {
margin-bottom: 0px;
margin-top: 0px;
}
input.search {
font-size: 75%;
color: #000080;
font-weight: normal;
background-color: #e8eef2;
}
td.tiny {
font-size: 75%;
}
.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #84b0c7;
}
th.dirtab {
background: #e8eef2;
font-weight: bold;
}
hr {
height: 0;
border: none;
border-top: 1px solid #666;
}
/* @group Member Descriptions */
.mdescLeft, .mdescRight,
.memItemLeft, .memItemRight,
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
background-color: #FAFAFA;
border: none;
margin: 4px;
padding: 1px 0 0 8px;
}
.mdescLeft, .mdescRight {
padding: 0px 8px 4px 8px;
color: #555;
}
.memItemLeft, .memItemRight, .memTemplParams {
border-top: 1px solid #ccc;
}
.memTemplParams {
color: #606060;
}
/* @end */
/* @group Member Details */
/* Styles for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #606060;
font-weight: normal;
margin-left: 3px;
}
.memnav {
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
.memitem {
padding: 0;
}
.memname {
white-space: nowrap;
font-weight: bold;
}
.memproto {
padding: 0;
background-color: #d5e1e8;
font-weight: bold;
border: 1px solid #84b0c7;
}
.memdoc {
padding: 2px 5px;
border-top-width: 0;
}
.paramkey {
text-align: right;
}
.paramtype {
white-space: nowrap;
}
.paramname {
color: #602020;
white-space: nowrap;
}
.paramname em {
font-style: normal;
}
/* @end */
/* @group Directory (tree) */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin: 0.5em;
}
/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
}
.directory h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
/*
The following two styles can be used to replace the root node title
with an image of your choice. Simply uncomment the next two styles,
specify the name of your image and be sure to set 'height' to the
proper pixel height of your image.
*/
/*
.directory h3.swap {
height: 61px;
background-repeat: no-repeat;
background-image: url("yourimage.gif");
}
.directory h3.swap span {
display: none;
}
*/
.directory > h3 {
margin-top: 0;
}
.directory p {
margin: 0px;
white-space: nowrap;
}
.directory div {
display: none;
margin: 0px;
}
.directory img {
vertical-align: -30%;
}
/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}
.directory-alt h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
.directory-alt > h3 {
margin-top: 0;
}
.directory-alt p {
margin: 0px;
white-space: nowrap;
}
.directory-alt div {
display: none;
margin: 0px;
}
.directory-alt img {
vertical-align: -30%;
}
/* @end */
address {
font-style: normal;
color: #333;
}
div.rationale:before {
content: "Rationale:";
display: block;
font-weight: bold;
font-size: 0.85em;
}
div.rationale {
font-style: italic;
border-left: 0.25em solid #808080;
padding-left: 0.5em;
}
div.rationale p {
font-size: 0.85em;
}
telepathy-qt-0.9.6~git1/tests/ 0000775 0001750 0001750 00000000000 12470405660 014112 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/ 0000775 0001750 0001750 00000000000 12470405660 014660 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/test.cpp 0000664 0001750 0001750 00000005752 12470405660 016354 0 ustar jr jr #include "tests/lib/test.h"
#include
#include
#include
#include
#include
#include
#include
#include
using Tp::PendingOperation;
using Tp::PendingVoid;
using Tp::Client::DBus::PeerInterface;
Test::Test(QObject *parent)
: QObject(parent), mLoop(new QEventLoop(this))
{
QTimer::singleShot(10 * 60 * 1000, this, SLOT(onWatchdog()));
}
Test::~Test()
{
delete mLoop;
}
void Test::initTestCaseImpl()
{
Tp::registerTypes();
Tp::enableDebug(true);
Tp::enableWarnings(true);
QVERIFY(QDBusConnection::sessionBus().isConnected());
}
void Test::initImpl()
{
}
void Test::cleanupImpl()
{
}
void Test::cleanupTestCaseImpl()
{
// To allow for cleanup code to run (e.g. PendingOperation cleanup after they finish)
mLoop->processEvents();
}
void Test::expectSuccessfulCall(PendingOperation *op)
{
if (op->isError()) {
qWarning().nospace() << op->errorName()
<< ": " << op->errorMessage();
mLoop->exit(1);
return;
}
mLoop->exit(0);
}
void Test::expectSuccessfulCall(QDBusPendingCallWatcher *watcher)
{
if (watcher->isError()) {
qWarning().nospace() << watcher->error().name()
<< ": " << watcher->error().message();
mLoop->exit(1);
return;
}
mLoop->exit(0);
}
void Test::expectFailure(PendingOperation *op)
{
if (!op->isError()) {
qWarning() << "expectFailure(): should have been an error, but wasn't";
mLastError = QString();
mLastErrorMessage = QString();
mLoop->exit(1);
return;
}
mLastError = op->errorName();
mLastErrorMessage = op->errorMessage();
mLoop->exit(0);
}
void Test::expectSuccessfulProperty(PendingOperation *op)
{
if (op->isError()) {
qWarning().nospace() << op->errorName()
<< ": " << op->errorMessage();
mPropertyValue = QVariant();
mLoop->exit(1001);
} else {
Tp::PendingVariant *pv = qobject_cast(op);
mPropertyValue = pv->result();
mLoop->exit(1000);
}
}
void Test::processDBusQueue(Tp::DBusProxy *proxy)
{
// Call method Ping on the D-Bus Peer interface
PeerInterface peer(proxy);
PendingVoid *call = new PendingVoid(peer.Ping(), Tp::SharedPtr());
// Wait for the reply to the Ping call
while (!call->isFinished()) {
mLoop->processEvents();
}
QVERIFY(call->isFinished());
QVERIFY(call->isValid());
// Do one more processEvents so the PendingVoid is always freed
mLoop->processEvents();
}
void Test::onWatchdog()
{
// We can't use QFAIL because the test would then go to cleanup() and/or cleanupTestCase(),
// which would often hang too - so let's just use abort
qWarning() << "Test took over 10 minutes to finish, it's probably hung up - aborting";
std::abort();
}
#include "_gen/test.h.moc.hpp"
telepathy-qt-0.9.6~git1/tests/lib/CMakeLists.txt 0000664 0001750 0001750 00000001631 12470405660 017421 0 ustar jr jr include_directories(
${CMAKE_CURRENT_BINARY_DIR})
set(tp_qt_tests_SRCS
test.cpp
test-thread-helper.cpp
)
set(tp_qt_tests_MOC_SRCS
test.h
test-thread-helper.h
)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_gen")
foreach(moc_src ${tp_qt_tests_MOC_SRCS})
set(generated_file _gen/${moc_src})
string(REPLACE ".h" ".h.moc.hpp" generated_file ${generated_file})
tpqt_generate_moc_i(${CMAKE_CURRENT_SOURCE_DIR}/${moc_src}
${CMAKE_CURRENT_BINARY_DIR}/${generated_file})
list(APPEND tp_qt_tests_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${generated_file})
endforeach(moc_src ${tp_qt_tests_MOC_SRCS})
add_library(tp-qt-tests ${tp_qt_tests_SRCS})
target_link_libraries(tp-qt-tests ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} telepathy-qt${QT_VERSION_MAJOR})
if(ENABLE_TP_GLIB_TESTS)
add_subdirectory(glib)
add_subdirectory(glib-helpers)
endif(ENABLE_TP_GLIB_TESTS)
telepathy-qt-0.9.6~git1/tests/lib/python/ 0000775 0001750 0001750 00000000000 12470405660 016201 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/python/account-manager.py 0000775 0001750 0001750 00000037243 12470405660 021633 0 ustar jr jr #!/usr/bin/python
#
# A small implementation of a Telepathy AccountManager.
import sys
import re
import dbus
from dbus.bus import NAME_FLAG_DO_NOT_QUEUE, REQUEST_NAME_REPLY_EXISTS
from dbus.mainloop.glib import DBusGMainLoop
from dbus.service import Object, method, signal
from gobject import MainLoop
TP = 'org.freedesktop.Telepathy'
AM_IFACE = TP + '.AccountManager'
AM_BUS_NAME = AM_IFACE
AM_OBJECT_PATH = '/' + AM_IFACE.replace('.', '/')
ACCOUNT_IFACE = TP + '.Account'
ACCOUNT_IFACE_AVATAR_IFACE = ACCOUNT_IFACE + '.Interface.Avatar'
ACCOUNT_OBJECT_PATH_BASE = '/' + ACCOUNT_IFACE.replace('.', '/') + '/'
Connection_Status_Connected = dbus.UInt32(0)
Connection_Status_Connecting = dbus.UInt32(1)
Connection_Status_Disconnected = dbus.UInt32(2)
Connection_Status_Reason_None_Specified = dbus.UInt32(0)
Connection_Status_Reason_Requested = dbus.UInt32(1)
Connection_Status_Reason_Network_Error = dbus.UInt32(2)
Connection_Presence_Type_Offline = dbus.UInt32(1)
Connection_Presence_Type_Available = dbus.UInt32(2)
VALID_CONNECTION_MANAGER_NAME = re.compile(r'^[A-Za-z0-9][_A-Za-z0-9]+$')
VALID_PROTOCOL_NAME = re.compile(r'^[A-Za-z0-9][-A-Za-z0-9]+$')
TELEPATHY_ERROR = "org.freedesktop.Telepathy.Error"
TELEPATHY_ERROR_DISCONNECTED = TELEPATHY_ERROR + ".Disconnected"
TELEPATHY_ERROR_CANCELLED = TELEPATHY_ERROR + ".Cancelled"
TELEPATHY_ERROR_NETWORK_ERROR = TELEPATHY_ERROR + ".NetworkError"
class AccountManager(Object):
def __init__(self, bus=None):
#: map from object path to Account
self._valid_accounts = {}
#: map from object path to Account
self._invalid_accounts = {}
if bus is None:
bus = dbus.SessionBus()
ret = bus.request_name(AM_BUS_NAME, NAME_FLAG_DO_NOT_QUEUE)
if ret == REQUEST_NAME_REPLY_EXISTS:
raise dbus.NameExistsException(AM_BUS_NAME)
Object.__init__(self, bus, AM_OBJECT_PATH)
def _am_props(self):
return dbus.Dictionary({
'Interfaces': dbus.Array([], signature='s'),
'ValidAccounts': dbus.Array(self._valid_accounts.keys(),
signature='o'),
'InvalidAccounts': dbus.Array(self._invalid_accounts.keys(),
signature='o'),
'SupportedAccountProperties': dbus.Array([ACCOUNT_IFACE + '.Enabled'], signature='s'),
}, signature='sv')
@method(dbus.PROPERTIES_IFACE,
in_signature='s',
out_signature='a{sv}')
def GetAll(self, iface):
if iface == AM_IFACE:
return self._am_props()
else:
raise ValueError('No such interface')
@method(dbus.PROPERTIES_IFACE,
in_signature='ss',
out_signature='v')
def Get(self, iface, prop):
if iface == AM_IFACE:
props = self._am_props()
else:
raise ValueError('No such interface')
if prop in props:
return props[prop]
else:
raise ValueError('No such property')
@method(dbus.PROPERTIES_IFACE,
in_signature='ssv')
def Set(self, iface, prop, value):
raise NotImplementedError('No mutable properties')
@signal(AM_IFACE, signature='ob')
def AccountValidityChanged(self, path, valid):
if valid:
assert path in self._invalid_accounts
assert path not in self._valid_accounts
self._valid_accounts[path] = self._invalid_accounts.pop(path)
else:
assert path in self._valid_accounts
assert path not in self._invalid_accounts
self._invalid_accounts[path] = self._valid_accounts.pop(path)
print "Emitting AccountValidityChanged(%s, %s)" % (path, valid)
@signal(AM_IFACE, signature='o')
def AccountRemoved(self, path):
assert path in self._valid_accounts or path in self._invalid_accounts
self._valid_accounts.pop(path, None)
self._invalid_accounts.pop(path, None)
print "Emitting AccountRemoved(%s)" % path
@method(AM_IFACE, in_signature='sssa{sv}a{sv}', out_signature='o')
def CreateAccount(self, cm, protocol, display_name, parameters,
properties):
if not VALID_CONNECTION_MANAGER_NAME.match(cm):
raise ValueError('Invalid CM name')
if not VALID_PROTOCOL_NAME.match(protocol):
raise ValueError('Invalid protocol name')
if properties:
raise ValueError('This AM does not support setting properties at'
'account creation')
base = ACCOUNT_OBJECT_PATH_BASE + cm + '/' + protocol.replace('-', '_')
# FIXME: This is a stupid way to generate the paths - we should
# incorporate the display name somehow. However, it's spec-compliant
i = 0
while 1:
path = '%s/Account%d' % (base, i)
if (path not in self._valid_accounts and
path not in self._invalid_accounts):
account = Account(self, path,
'%s (account %d)' % (display_name, i), parameters)
# put it in the wrong set and move it to the right one -
# that's probably the simplest implementation
if account._is_valid():
self._invalid_accounts[path] = account
self.AccountValidityChanged(path, True)
assert path not in self._invalid_accounts
assert path in self._valid_accounts
else:
self._valid_accounts[path] = account
self.AccountValidityChanged(path, False)
assert path not in self._valid_accounts
assert path in self._invalid_accounts
return path
i += 1
raise AssertionError('Not reached')
class Account(Object):
def __init__(self, am, path, display_name, parameters):
Object.__init__(self, am.connection, path)
self._am = am
self._connection = dbus.ObjectPath('/')
self._connection_status = Connection_Status_Disconnected
self._connection_status_reason = Connection_Status_Reason_None_Specified
self._connection_error = u''
self._connection_error_details = dbus.Dictionary({}, signature='sv')
self._service = u''
self._display_name = display_name
self._icon = u'bob.png'
self._enabled = True
self._nickname = u'Bob'
self._parameters = parameters
self._has_been_online = False
self._connect_automatically = False
self._normalized_name = u'bob'
self._automatic_presence = dbus.Struct(
(Connection_Presence_Type_Available, 'available', ''),
signature='uss')
self._current_presence = dbus.Struct(
(Connection_Presence_Type_Offline, 'offline', ''),
signature='uss')
self._requested_presence = dbus.Struct(
(Connection_Presence_Type_Offline, 'offline', ''),
signature='uss')
self._avatar = dbus.Struct(
(dbus.ByteArray(''), 'image/png'),
signature='ays')
self._interfaces = [ACCOUNT_IFACE_AVATAR_IFACE,]
def _is_valid(self):
return True
@method(ACCOUNT_IFACE, in_signature='a{sv}as', out_signature='as')
def UpdateParameters(self, set_, unset):
print ("%s: entering UpdateParameters(\n %r,\n %r \n)"
% (self.__dbus_object_path__, set_, unset))
for (key, value) in set_.iteritems():
self._parameters[key] = value
for key in unset:
self._parameters.pop(key, None)
print ("%s: UpdateParameters(...) -> success"
% self.__dbus_object_path__)
self.AccountPropertyChanged({'Parameters': self._parameters})
return []
@signal(ACCOUNT_IFACE, signature='a{sv}')
def AccountPropertyChanged(self, delta):
print ("%s: emitting AccountPropertyChanged(\n %r \n)"
% (self.__dbus_object_path__, delta))
@signal(ACCOUNT_IFACE_AVATAR_IFACE, signature='')
def AvatarChanged(self):
print ("%s: emitting AvatarChanged"
% (self.__dbus_object_path__))
@method(ACCOUNT_IFACE, in_signature='', out_signature='')
def Remove(self):
print "%s: entering Remove()" % self.__dbus_object_path__
self.Removed()
self.remove_from_connection()
print "%s: Remove() -> success" % self.__dbus_object_path__
@signal(ACCOUNT_IFACE, signature='')
def Removed(self):
self._am.AccountRemoved(self.__dbus_object_path__)
print "%s: Emitting Removed()" % self.__dbus_object_path__
def _account_props(self):
return dbus.Dictionary({
'Interfaces': dbus.Array(self._interfaces, signature='s'),
'Service': self._service,
'DisplayName': self._display_name,
'Icon': self._icon,
'Valid': self._is_valid(),
'Enabled': self._enabled,
'Nickname': self._nickname,
'Parameters': self._parameters,
'AutomaticPresence': self._automatic_presence,
'CurrentPresence': self._current_presence,
'RequestedPresence': self._requested_presence,
'HasBeenOnline': self._has_been_online,
'ConnectAutomatically': self._connect_automatically,
'Connection': self._connection,
'ConnectionStatus': self._connection_status,
'ConnectionStatusReason': self._connection_status_reason,
'ConnectionError': self._connection_error,
'ConnectionErrorDetails': self._connection_error_details,
'NormalizedName': self._normalized_name,
}, signature='sv')
def _account_avatar_props(self):
return dbus.Dictionary({
'Avatar': self._avatar
}, signature='sv')
@method(dbus.PROPERTIES_IFACE,
in_signature='s',
out_signature='a{sv}')
def GetAll(self, iface):
if iface == ACCOUNT_IFACE:
return self._account_props()
elif iface == ACCOUNT_IFACE_AVATAR_IFACE:
return self._account_avatar_props()
else:
raise ValueError('No such interface')
@method(dbus.PROPERTIES_IFACE,
in_signature='ss',
out_signature='v')
def Get(self, iface, prop):
if iface == ACCOUNT_IFACE:
props = self._account_props()
elif iface == ACCOUNT_IFACE_AVATAR_IFACE:
props = self._account_avatar_props()
else:
raise ValueError('No such interface')
if prop in props:
return props[prop]
else:
raise ValueError('No such property')
@method(dbus.PROPERTIES_IFACE,
in_signature='ssv', byte_arrays=True)
def Set(self, iface, prop, value):
if iface == ACCOUNT_IFACE:
props = {}
if prop == 'Service':
self._service = unicode(value)
elif prop == 'DisplayName':
self._display_name = unicode(value)
elif prop == 'Icon':
self._icon = unicode(value)
elif prop == 'Enabled':
self._enabled = bool(value)
elif prop == 'Nickname':
self._nickname = unicode(value)
elif prop == 'AutomaticPresence':
self._automatic_presence = dbus.Struct(
(dbus.UInt32(value[0]), unicode(value[1]),
unicode(value[2])),
signature='uss')
elif prop == 'RequestedPresence':
self._requested_presence = dbus.Struct(
(dbus.UInt32(value[0]), unicode(value[1]),
unicode(value[2])),
signature='uss')
# pretend to put the account online, if the presence != offline
if value[0] != Connection_Presence_Type_Offline:
# simulate that we are connecting/changing presence
props["ChangingPresence"] = True
if self._connection_status == Connection_Status_Disconnected:
self._connection_status = Connection_Status_Connecting
props["ConnectionStatus"] = self._connection_status
props[prop] = self._account_props()[prop]
self.AccountPropertyChanged(props)
props["ChangingPresence"] = False
if "(deny)" in self._requested_presence[2]:
self._connection_status = Connection_Status_Disconnected
self._connection_status_reason = Connection_Status_Reason_Network_Error
self._connection_error = TELEPATHY_ERROR_NETWORK_ERROR
self._connection_error_details = dbus.Dictionary(
{'debug-message': u'You asked for it'},
signature='sv')
self._current_presence = dbus.Struct(
(Connection_Presence_Type_Offline, 'offline', ''),
signature='uss')
else:
self._connection_status = Connection_Status_Connected
self._connection_status_reason = Connection_Status_Reason_None_Specified
self._connection_error = u''
self._connection_error_details = dbus.Dictionary({}, signature='sv')
self._current_presence = self._requested_presence
if self._has_been_online == False:
self._has_been_online = True
props["HasBeenOnline"] = self._has_been_online
else:
self._connection_status = Connection_Status_Disconnected
self._connection_status_reason = Connection_Status_Reason_Requested
self._connection_error = TELEPATHY_ERROR_CANCELLED
self._connection_error_details = dbus.Dictionary(
{'debug-message': u'You asked for it'},
signature='sv')
self._current_presence = dbus.Struct(
(Connection_Presence_Type_Offline, 'offline', ''),
signature='uss')
props["ConnectionStatus"] = self._connection_status
props["ConnectionStatusReason"] = self._connection_status_reason
props["ConnectionError"] = self._connection_error
props["ConnectionErrorDetails"] = self._connection_error_details
props["CurrentPresence"] = self._current_presence
elif prop == 'ConnectAutomatically':
self._connect_automatically = bool(value)
elif prop == 'Connection':
self._connection = dbus.ObjectPath(value)
else:
raise ValueError('Read-only or nonexistent property')
props[prop] = self._account_props()[prop]
self.AccountPropertyChanged(props)
elif iface == ACCOUNT_IFACE_AVATAR_IFACE:
if prop == 'Avatar':
self._avatar = dbus.Struct(
(dbus.ByteArray(value[0]), unicode(value[1])),
signature='ays')
self.AvatarChanged()
else:
raise ValueError('Nonexistent property')
else:
raise ValueError('No such interface')
if __name__ == '__main__':
DBusGMainLoop(set_as_default=True)
try:
am = AccountManager()
except dbus.NameExistsException:
print >> sys.stderr, 'AccountManager already running'
sys.exit(1)
print "AccountManager running..."
mainloop = MainLoop()
mainloop.run()
telepathy-qt-0.9.6~git1/tests/lib/glib/ 0000775 0001750 0001750 00000000000 12470405660 015575 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/glib/simple-account-manager.c 0000664 0001750 0001750 00000012646 12470405660 022305 0 ustar jr jr /*
* simple-account-manager.c - a simple account manager service.
*
* Copyright (C) 2007-2009 Collabora Ltd.
* Copyright (C) 2007-2008 Nokia Corporation
*
* 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.
*/
#include "simple-account-manager.h"
#include
#include
#include
#include
static void account_manager_iface_init (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccountManager,
tp_tests_simple_account_manager,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_MANAGER,
account_manager_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init)
)
/* TP_IFACE_ACCOUNT_MANAGER is implied */
static const char *ACCOUNT_MANAGER_INTERFACES[] = { NULL };
static gchar *VALID_ACCOUNTS[] = {
"/org/freedesktop/Telepathy/Account/fakecm/fakeproto/validaccount",
NULL };
static gchar *INVALID_ACCOUNTS[] = {
"/org/freedesktop/Telepathy/Account/fakecm/fakeproto/invalidaccount",
NULL };
enum
{
PROP_0,
PROP_INTERFACES,
PROP_VALID_ACCOUNTS,
PROP_INVALID_ACCOUNTS,
};
struct _TpTestsSimpleAccountManagerPrivate
{
int dummy;
};
static void
tp_tests_simple_account_manager_create_account (TpSvcAccountManager *self,
const gchar *in_Connection_Manager,
const gchar *in_Protocol,
const gchar *in_Display_Name,
GHashTable *in_Parameters,
GHashTable *in_Properties,
DBusGMethodInvocation *context)
{
const gchar *out_Account = "/some/fake/account/i/think";
tp_svc_account_manager_return_from_create_account (context, out_Account);
}
static void
account_manager_iface_init (gpointer klass,
gpointer unused G_GNUC_UNUSED)
{
#define IMPLEMENT(x) tp_svc_account_manager_implement_##x (\
klass, tp_tests_simple_account_manager_##x)
IMPLEMENT (create_account);
#undef IMPLEMENT
}
static void
tp_tests_simple_account_manager_init (TpTestsSimpleAccountManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, TpTestsSimpleAccountManagerPrivate);
}
static void
tp_tests_simple_account_manager_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *spec)
{
GPtrArray *accounts;
guint i = 0;
switch (property_id) {
case PROP_INTERFACES:
g_value_set_boxed (value, ACCOUNT_MANAGER_INTERFACES);
break;
case PROP_VALID_ACCOUNTS:
accounts = g_ptr_array_new ();
for (i=0; VALID_ACCOUNTS[i] != NULL; i++)
g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i]));
g_value_take_boxed (value, accounts);
break;
case PROP_INVALID_ACCOUNTS:
accounts = g_ptr_array_new ();
for (i=0; INVALID_ACCOUNTS[i] != NULL; i++)
g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i]));
g_value_take_boxed (value, accounts);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
break;
}
}
/**
* This class currently only provides the minimum for
* tp_account_manager_prepare to succeed. This turns out to be only a working
* Properties.GetAll(). If we wanted later to check the case where
* tp_account_prepare succeeds, we would need to implement an account object
* too.
*/
static void
tp_tests_simple_account_manager_class_init (
TpTestsSimpleAccountManagerClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl am_props[] = {
{ "Interfaces", "interfaces", NULL },
{ "ValidAccounts", "valid-accounts", NULL },
{ "InvalidAccounts", "invalid-accounts", NULL },
/*
{ "SupportedAccountProperties", "supported-account-properties", NULL },
*/
{ NULL }
};
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_ACCOUNT_MANAGER,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
am_props
},
{ NULL },
};
g_type_class_add_private (klass, sizeof (TpTestsSimpleAccountManagerPrivate));
object_class->get_property = tp_tests_simple_account_manager_get_property;
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
"In this case we only implement AccountManager, so none.",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
param_spec = g_param_spec_boxed ("valid-accounts", "Valid accounts",
"The accounts which are valid on this account. This may be a lie.",
TP_ARRAY_TYPE_OBJECT_PATH_LIST,
G_PARAM_READABLE);
g_object_class_install_property (object_class, PROP_VALID_ACCOUNTS, param_spec);
param_spec = g_param_spec_boxed ("invalid-accounts", "Invalid accounts",
"The accounts which are invalid on this account. This may be a lie.",
TP_ARRAY_TYPE_OBJECT_PATH_LIST,
G_PARAM_READABLE);
g_object_class_install_property (object_class, PROP_INVALID_ACCOUNTS, param_spec);
klass->dbus_props_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsSimpleAccountManagerClass, dbus_props_class));
}
telepathy-qt-0.9.6~git1/tests/lib/glib/simple-client.h 0000664 0001750 0001750 00000003566 12470405660 020525 0 ustar jr jr /*
* simple-client.h - header for a simple client
*
* Copyright © 2010 Collabora Ltd.
*
* 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.
*/
#ifndef __TP_TESTS_SIMPLE_CLIENT_H__
#define __TP_TESTS_SIMPLE_CLIENT_H__
#include
#include
G_BEGIN_DECLS
typedef struct _TpTestsSimpleClient TpTestsSimpleClient;
typedef struct _TpTestsSimpleClientClass TpTestsSimpleClientClass;
struct _TpTestsSimpleClientClass {
TpBaseClientClass parent_class;
};
struct _TpTestsSimpleClient {
TpBaseClient parent;
TpObserveChannelsContext *observe_ctx;
TpAddDispatchOperationContext *add_dispatch_ctx;
TpHandleChannelsContext *handle_channels_ctx;
};
GType tp_tests_simple_client_get_type (void);
/* TYPE MACROS */
#define TP_TESTS_TYPE_SIMPLE_CLIENT \
(tp_tests_simple_client_get_type ())
#define TP_TESTS_SIMPLE_CLIENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CLIENT, \
TpTestsSimpleClient))
#define TP_TESTS_SIMPLE_CLIENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CLIENT, \
TpTestsSimpleClientClass))
#define SIMPLE_IS_CLIENT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CLIENT))
#define SIMPLE_IS_CLIENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CLIENT))
#define TP_TESTS_SIMPLE_CLIENT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CLIENT, \
TpTestsSimpleClientClass))
TpTestsSimpleClient * tp_tests_simple_client_new (TpDBusDaemon *dbus_daemon,
const gchar *name,
gboolean uniquify_name);
G_END_DECLS
#endif /* #ifndef __TP_TESTS_SIMPLE_CONN_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/stream-tube-chan.c 0000664 0001750 0001750 00000052654 12470405660 021114 0 ustar jr jr /*
* stream-tube-chan.c - Simple stream tube channel
*
* Copyright (C) 2010 Collabora Ltd.
*
* 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.
*/
#include "stream-tube-chan.h"
#include
#include
#include
#include
#include
#include
#include
enum
{
PROP_SERVICE = 1,
PROP_SUPPORTED_SOCKET_TYPES,
PROP_PARAMETERS,
PROP_STATE,
};
enum
{
SIG_INCOMING_CONNECTION,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0, };
struct _TpTestsStreamTubeChannelPrivate {
TpTubeChannelState state;
GHashTable *supported_socket_types;
/* Accepting side */
GSocketService *service;
GValue *access_control_param;
/* Offering side */
TpSocketAddressType address_type;
GValue *address;
gchar *unix_address;
guint connection_id;
TpSocketAccessControl access_control;
GHashTable *parameters;
gboolean close_on_accept;
};
static void
destroy_socket_control_list (gpointer data)
{
GArray *tab = data;
g_array_free (tab, TRUE);
}
static void
create_supported_socket_types (TpTestsStreamTubeChannel *self)
{
TpSocketAccessControl access_control;
GArray *unix_tab;
g_assert (self->priv->supported_socket_types == NULL);
self->priv->supported_socket_types = g_hash_table_new_full (NULL, NULL,
NULL, destroy_socket_control_list);
/* Socket_Address_Type_Unix */
unix_tab = g_array_sized_new (FALSE, FALSE, sizeof (TpSocketAccessControl),
1);
access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
g_array_append_val (unix_tab, access_control);
g_hash_table_insert (self->priv->supported_socket_types,
GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX), unix_tab);
}
static void
tp_tests_stream_tube_channel_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
switch (property_id)
{
case PROP_SERVICE:
g_value_set_string (value, "test-service");
break;
case PROP_SUPPORTED_SOCKET_TYPES:
g_value_set_boxed (value,
self->priv->supported_socket_types);
break;
case PROP_PARAMETERS:
g_value_set_boxed (value, self->priv->parameters);
break;
case PROP_STATE:
g_value_set_uint (value, self->priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
tp_tests_stream_tube_channel_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
switch (property_id)
{
case PROP_SUPPORTED_SOCKET_TYPES:
self->priv->supported_socket_types = g_value_dup_boxed (value);
break;
case PROP_PARAMETERS:
if (self->priv->parameters != NULL)
g_hash_table_destroy (self->priv->parameters);
self->priv->parameters = g_value_dup_boxed (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void stream_tube_iface_init (gpointer iface, gpointer data);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TpTestsStreamTubeChannel,
tp_tests_stream_tube_channel,
TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAM_TUBE,
stream_tube_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
NULL);
)
/* type definition stuff */
static const char * tp_tests_stream_tube_channel_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_TUBE,
NULL
};
static void
tp_tests_stream_tube_channel_init (TpTestsStreamTubeChannel *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
TP_TESTS_TYPE_STREAM_TUBE_CHANNEL, TpTestsStreamTubeChannelPrivate);
}
static GObject *
constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
GObject *object =
G_OBJECT_CLASS (tp_tests_stream_tube_channel_parent_class)->constructor (
type, n_props, props);
TpTestsStreamTubeChannel *self = TP_TESTS_STREAM_TUBE_CHANNEL (object);
if (tp_base_channel_is_requested (TP_BASE_CHANNEL (self)))
{
self->priv->state = TP_TUBE_CHANNEL_STATE_NOT_OFFERED;
self->priv->parameters = tp_asv_new (NULL, NULL);
}
else
{
self->priv->state = TP_TUBE_CHANNEL_STATE_LOCAL_PENDING;
self->priv->parameters = tp_asv_new ("badger", G_TYPE_UINT, 42,
NULL);
}
if (self->priv->supported_socket_types == NULL)
create_supported_socket_types (self);
tp_base_channel_register (TP_BASE_CHANNEL (self));
return object;
}
static void
dispose (GObject *object)
{
TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
if (self->priv->service != NULL)
{
g_socket_service_stop (self->priv->service);
tp_clear_object (&self->priv->service);
}
tp_clear_pointer (&self->priv->address, tp_g_value_slice_free);
tp_clear_pointer (&self->priv->supported_socket_types, g_hash_table_unref);
tp_clear_pointer (&self->priv->access_control_param, tp_g_value_slice_free);
if (self->priv->unix_address != NULL)
g_unlink (self->priv->unix_address);
tp_clear_pointer (&self->priv->unix_address, g_free);
((GObjectClass *) tp_tests_stream_tube_channel_parent_class)->dispose (
object);
}
static void
channel_close (TpBaseChannel *channel)
{
tp_base_channel_destroyed (channel);
}
static void
fill_immutable_properties (TpBaseChannel *chan,
GHashTable *properties)
{
TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
tp_tests_stream_tube_channel_parent_class);
klass->fill_immutable_properties (chan, properties);
tp_dbus_properties_mixin_fill_properties_hash (
G_OBJECT (chan), properties,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "Service",
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "SupportedSocketTypes",
NULL);
if (!tp_base_channel_is_requested (chan))
{
/* Parameters is immutable only for incoming tubes */
tp_dbus_properties_mixin_fill_properties_hash (
G_OBJECT (chan), properties,
TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
NULL);
}
}
static void
tp_tests_stream_tube_channel_class_init (TpTestsStreamTubeChannelClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl stream_tube_props[] = {
{ "Service", "service", NULL, },
{ "SupportedSocketTypes", "supported-socket-types", NULL },
{ NULL }
};
static TpDBusPropertiesMixinPropImpl tube_props[] = {
{ "Parameters", "parameters", NULL, },
{ "State", "state", NULL, },
{ NULL }
};
object_class->constructor = constructor;
object_class->get_property = tp_tests_stream_tube_channel_get_property;
object_class->set_property = tp_tests_stream_tube_channel_set_property;
object_class->dispose = dispose;
base_class->channel_type = TP_IFACE_CHANNEL_TYPE_STREAM_TUBE;
base_class->interfaces = tp_tests_stream_tube_channel_interfaces;
base_class->close = channel_close;
base_class->fill_immutable_properties = fill_immutable_properties;
/* base_class->target_handle_type is defined in subclasses */
param_spec = g_param_spec_string ("service", "service name",
"the service associated with this tube object.",
"",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SERVICE, param_spec);
param_spec = g_param_spec_boxed (
"supported-socket-types", "Supported socket types",
"GHashTable containing supported socket types.",
TP_HASH_TYPE_SUPPORTED_SOCKET_MAP,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SUPPORTED_SOCKET_TYPES,
param_spec);
param_spec = g_param_spec_boxed (
"parameters", "Parameters",
"parameters of the tube",
TP_HASH_TYPE_STRING_VARIANT_MAP,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_PARAMETERS,
param_spec);
param_spec = g_param_spec_uint (
"state", "TpTubeState",
"state of the tube",
0, NUM_TP_TUBE_CHANNEL_STATES - 1, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_STATE,
param_spec);
signals[SIG_INCOMING_CONNECTION] = g_signal_new ("incoming-connection",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1, G_TYPE_IO_STREAM);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_TYPE_STREAM_TUBE,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
stream_tube_props);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_INTERFACE_TUBE,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
tube_props);
g_type_class_add_private (object_class,
sizeof (TpTestsStreamTubeChannelPrivate));
}
static void
change_state (TpTestsStreamTubeChannel *self,
TpTubeChannelState state)
{
self->priv->state = state;
tp_svc_channel_interface_tube_emit_tube_channel_state_changed (self, state);
}
/* Return the address of the socket which has been shared over the tube */
GSocketAddress *
tp_tests_stream_tube_channel_get_server_address (TpTestsStreamTubeChannel *self)
{
return tp_g_socket_address_from_variant (self->priv->address_type,
self->priv->address, NULL);
}
static gboolean
check_address_type (TpTestsStreamTubeChannel *self,
TpSocketAddressType address_type,
TpSocketAccessControl access_control)
{
GArray *arr;
guint i;
arr = g_hash_table_lookup (self->priv->supported_socket_types,
GUINT_TO_POINTER (address_type));
if (arr == NULL)
return FALSE;
for (i = 0; i < arr->len; i++)
{
if (g_array_index (arr, TpSocketAccessControl, i) == access_control)
return TRUE;
}
return FALSE;
}
static void
stream_tube_offer (TpSvcChannelTypeStreamTube *iface,
guint address_type,
const GValue *address,
guint access_control,
GHashTable *parameters,
DBusGMethodInvocation *context)
{
TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) iface;
GError *error = NULL;
if (self->priv->state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED)
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Tube is not in the not offered state");
goto fail;
}
if (!check_address_type (self, address_type, access_control))
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Address type not supported with this access control");
goto fail;
}
self->priv->address_type = address_type;
self->priv->address = tp_g_value_slice_dup (address);
self->priv->access_control = access_control;
g_object_set (self, "parameters", parameters, NULL);
change_state (self, TP_TUBE_CHANNEL_STATE_REMOTE_PENDING);
tp_svc_channel_type_stream_tube_return_from_offer (context);
return;
fail:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static void
service_incoming_cb (GSocketService *service,
GSocketConnection *connection,
GObject *source_object,
gpointer user_data)
{
TpTestsStreamTubeChannel *self = user_data;
GError *error = NULL;
if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS)
{
GCredentials *creds;
guchar byte;
/* FIXME: we should an async version of this API (bgo #629503) */
creds = tp_unix_connection_receive_credentials_with_byte (
connection, &byte, NULL, &error);
g_assert_no_error (error);
g_assert_cmpuint (byte, ==,
g_value_get_uchar (self->priv->access_control_param));
g_object_unref (creds);
}
else if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_PORT)
{
GSocketAddress *remote_addr;
gchar *host, *remote_host;
guint port, remote_port;
dbus_g_type_struct_get (self->priv->access_control_param,
0, &host,
1, &port,
G_MAXUINT);
remote_addr = g_socket_connection_get_remote_address (connection, &error);
g_assert_no_error (error);
remote_host = g_inet_address_to_string (
g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (remote_addr)));
remote_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (remote_addr));
g_assert_cmpuint (remote_port, ==, port);
g_assert_cmpstr (remote_host, ==, host);
g_free (host);
g_free (remote_host);
g_object_unref (remote_addr);
}
tp_svc_channel_type_stream_tube_emit_new_local_connection (self,
self->priv->connection_id);
self->priv->connection_id++;
g_signal_emit (self, signals[SIG_INCOMING_CONNECTION], 0, connection);
}
static GValue *
create_local_socket (TpTestsStreamTubeChannel *self,
TpSocketAddressType address_type,
TpSocketAccessControl access_control,
GError **error)
{
gboolean success;
GSocketAddress *address, *effective_address;
GValue *address_gvalue;
switch (access_control)
{
case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
case TP_SOCKET_ACCESS_CONTROL_PORT:
break;
default:
g_assert_not_reached ();
}
switch (address_type)
{
case TP_SOCKET_ADDRESS_TYPE_UNIX:
{
address = g_unix_socket_address_new (tmpnam (NULL));
break;
}
case TP_SOCKET_ADDRESS_TYPE_IPV4:
case TP_SOCKET_ADDRESS_TYPE_IPV6:
{
GInetAddress *localhost;
localhost = g_inet_address_new_loopback (
address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
G_SOCKET_FAMILY_IPV4 : G_SOCKET_FAMILY_IPV6);
address = g_inet_socket_address_new (localhost, 0);
g_object_unref (localhost);
break;
}
default:
g_assert_not_reached ();
}
self->priv->service = g_socket_service_new ();
success = g_socket_listener_add_address (
G_SOCKET_LISTENER (self->priv->service),
address, G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
NULL, &effective_address, NULL);
g_assert (success);
tp_g_signal_connect_object (self->priv->service, "incoming",
G_CALLBACK (service_incoming_cb), self, 0);
switch (address_type)
{
case TP_SOCKET_ADDRESS_TYPE_UNIX:
self->priv->unix_address = g_strdup (g_unix_socket_address_get_path (
G_UNIX_SOCKET_ADDRESS (effective_address)));
address_gvalue = tp_g_value_slice_new_bytes (
g_unix_socket_address_get_path_len (
G_UNIX_SOCKET_ADDRESS (effective_address)),
g_unix_socket_address_get_path (
G_UNIX_SOCKET_ADDRESS (effective_address)));
break;
case TP_SOCKET_ADDRESS_TYPE_IPV4:
case TP_SOCKET_ADDRESS_TYPE_IPV6:
address_gvalue = tp_g_value_slice_new_take_boxed (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
dbus_g_type_specialized_construct (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
dbus_g_type_struct_set (address_gvalue,
0, address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
"127.0.0.1" : "::1",
1, g_inet_socket_address_get_port (
G_INET_SOCKET_ADDRESS (effective_address)),
G_MAXUINT);
break;
default:
g_assert_not_reached ();
}
g_object_unref (address);
g_object_unref (effective_address);
return address_gvalue;
}
static void
stream_tube_accept (TpSvcChannelTypeStreamTube *iface,
TpSocketAddressType address_type,
TpSocketAccessControl access_control,
const GValue *access_control_param,
DBusGMethodInvocation *context)
{
TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) iface;
GError *error = NULL;
GValue *address;
if (self->priv->state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING)
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Tube is not in the local pending state");
goto fail;
}
if (!check_address_type (self, address_type, access_control))
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Address type not supported with this access control");
goto fail;
}
if (self->priv->close_on_accept)
{
tp_base_channel_close (TP_BASE_CHANNEL (self));
return;
}
address = create_local_socket (self, address_type, access_control, &error);
self->priv->access_control = access_control;
self->priv->access_control_param = tp_g_value_slice_dup (
access_control_param);
change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
tp_svc_channel_type_stream_tube_return_from_accept (context, address);
tp_g_value_slice_free (address);
return;
fail:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static void
stream_tube_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelTypeStreamTubeClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_type_stream_tube_implement_##x (klass, stream_tube_##x)
IMPLEMENT(offer);
IMPLEMENT(accept);
#undef IMPLEMENT
}
/* Called to emulate a peer connecting to an offered tube */
void
tp_tests_stream_tube_channel_peer_connected (TpTestsStreamTubeChannel *self,
GIOStream *stream,
TpHandle handle)
{
GValue *connection_param;
if (self->priv->state == TP_TUBE_CHANNEL_STATE_REMOTE_PENDING)
change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
g_assert (self->priv->state == TP_TUBE_CHANNEL_STATE_OPEN);
switch (self->priv->access_control)
{
case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
connection_param = tp_g_value_slice_new_static_string ("dummy");
break;
case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
{
GError *error = NULL;
guchar byte = g_random_int_range (0, G_MAXUINT8);
/* FIXME: we should an async version of this API (bgo #629503) */
tp_unix_connection_send_credentials_with_byte (
G_SOCKET_CONNECTION (stream), byte, NULL, &error);
g_assert_no_error (error);
connection_param = tp_g_value_slice_new_byte (byte);
}
break;
case TP_SOCKET_ACCESS_CONTROL_PORT:
{
GSocketAddress *addr;
GError *error = NULL;
addr = g_socket_connection_get_local_address (
G_SOCKET_CONNECTION (stream), &error);
g_assert_no_error (error);
connection_param = tp_g_value_slice_new_take_boxed (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
dbus_g_type_specialized_construct (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
dbus_g_type_struct_set (connection_param,
0, "badger",
1, g_inet_socket_address_get_port (
G_INET_SOCKET_ADDRESS (addr)),
G_MAXUINT);
g_object_unref (addr);
}
break;
default:
g_assert_not_reached ();
}
tp_svc_channel_type_stream_tube_emit_new_remote_connection (self, handle,
connection_param, self->priv->connection_id);
self->priv->connection_id++;
tp_g_value_slice_free (connection_param);
}
/* Called to emulate a peer connecting to an offered tube */
void
tp_tests_stream_tube_channel_peer_connected_no_stream (TpTestsStreamTubeChannel *self,
const GValue *connection_param,
TpHandle handle)
{
if (self->priv->state == TP_TUBE_CHANNEL_STATE_REMOTE_PENDING)
change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
g_assert (self->priv->state == TP_TUBE_CHANNEL_STATE_OPEN);
tp_svc_channel_type_stream_tube_emit_new_remote_connection (self, handle,
connection_param, self->priv->connection_id);
self->priv->connection_id++;
}
void
tp_tests_stream_tube_channel_last_connection_disconnected (
TpTestsStreamTubeChannel *self,
const gchar *error)
{
tp_svc_channel_type_stream_tube_emit_connection_closed (self,
self->priv->connection_id - 1, error, "kaboum");
}
void
tp_tests_stream_tube_channel_set_close_on_accept (
TpTestsStreamTubeChannel *self,
gboolean close_on_accept)
{
self->priv->close_on_accept = close_on_accept;
}
/* Contact Stream Tube */
G_DEFINE_TYPE (TpTestsContactStreamTubeChannel,
tp_tests_contact_stream_tube_channel,
TP_TESTS_TYPE_STREAM_TUBE_CHANNEL)
static void
tp_tests_contact_stream_tube_channel_init (
TpTestsContactStreamTubeChannel *self)
{
}
static void
tp_tests_contact_stream_tube_channel_class_init (
TpTestsContactStreamTubeChannelClass *klass)
{
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
}
/* Room Stream Tube */
G_DEFINE_TYPE (TpTestsRoomStreamTubeChannel,
tp_tests_room_stream_tube_channel,
TP_TESTS_TYPE_STREAM_TUBE_CHANNEL)
static void
tp_tests_room_stream_tube_channel_init (
TpTestsRoomStreamTubeChannel *self)
{
}
static void
tp_tests_room_stream_tube_channel_class_init (
TpTestsRoomStreamTubeChannelClass *klass)
{
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
base_class->target_handle_type = TP_HANDLE_TYPE_ROOM;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/dbus-tube-chan.c 0000664 0001750 0001750 00000052132 12470405660 020545 0 ustar jr jr /*
* dbus-tube-chan.c - Simple dbus tube channel
*
* Copyright (C) 2010 Collabora Ltd.
*
* 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.
*/
#include "dbus-tube-chan.h"
#include
#include
#include
#include
#include
#include
#include
enum
{
PROP_SERVICE_NAME = 1,
PROP_DBUS_NAMES,
PROP_SUPPORTED_ACCESS_CONTROLS,
PROP_PARAMETERS,
PROP_STATE,
PROP_DBUS_ADDRESS
};
struct _TpTestsDBusTubeChannelPrivate {
TpTubeChannelState state;
TpSocketAccessControl access_control;
/* our unique D-Bus name on the virtual tube bus (NULL for 1-1 D-Bus tubes)*/
gchar *dbus_local_name;
/* the address that we are listening for D-Bus connections on */
gchar *dbus_srv_addr;
/* the path of the UNIX socket used by the D-Bus server */
gchar *socket_path;
/* the server that's listening on dbus_srv_addr */
DBusServer *dbus_srv;
/* the connection to dbus_srv from a local client, or NULL */
DBusConnection *dbus_conn;
/* the queue of D-Bus messages to be delivered to a local client when it
* will connect */
GSList *dbus_msg_queue;
/* current size of the queue in bytes. The maximum is MAX_QUEUE_SIZE */
unsigned long dbus_msg_queue_size;
/* mapping of contact handle -> D-Bus name (empty for 1-1 D-Bus tubes) */
GHashTable *dbus_names;
GArray *supported_access_controls;
GHashTable *parameters;
gboolean close_on_accept;
};
static void
tp_tests_dbus_tube_channel_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) object;
switch (property_id)
{
case PROP_SERVICE_NAME:
g_value_set_string (value, "com.test.Test");
break;
case PROP_DBUS_NAMES:
g_value_set_boxed (value, self->priv->dbus_names);
break;
case PROP_SUPPORTED_ACCESS_CONTROLS:
g_value_set_boxed (value, self->priv->supported_access_controls);
break;
case PROP_PARAMETERS:
g_value_set_boxed (value, self->priv->parameters);
break;
case PROP_DBUS_ADDRESS:
g_value_set_string (value, self->priv->dbus_srv_addr);
break;
case PROP_STATE:
g_value_set_uint (value, self->priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
tp_tests_dbus_tube_channel_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) object;
switch (property_id)
{
case PROP_SUPPORTED_ACCESS_CONTROLS:
if (self->priv->supported_access_controls != NULL)
g_array_free (self->priv->supported_access_controls, FALSE);
self->priv->supported_access_controls = g_value_dup_boxed (value);
break;
case PROP_PARAMETERS:
if (self->priv->parameters != NULL)
g_hash_table_destroy (self->priv->parameters);
self->priv->parameters = g_value_dup_boxed (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void dbus_tube_iface_init (gpointer iface, gpointer data);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TpTestsDBusTubeChannel,
tp_tests_dbus_tube_channel,
TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE,
dbus_tube_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
NULL);
)
/* type definition stuff */
static const char * tp_tests_dbus_tube_channel_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_TUBE,
NULL
};
static void
tp_tests_dbus_tube_channel_init (TpTestsDBusTubeChannel *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, TpTestsDBusTubeChannelPrivate);
self->priv->dbus_names = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static GObject *
constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
GObject *object =
G_OBJECT_CLASS (tp_tests_dbus_tube_channel_parent_class)->constructor (
type, n_props, props);
TpTestsDBusTubeChannel *self = TP_TESTS_DBUS_TUBE_CHANNEL (object);
if (tp_base_channel_is_requested (TP_BASE_CHANNEL (self)))
{
self->priv->state = TP_TUBE_CHANNEL_STATE_NOT_OFFERED;
self->priv->parameters = tp_asv_new (NULL, NULL);
}
else
{
self->priv->state = TP_TUBE_CHANNEL_STATE_LOCAL_PENDING;
self->priv->parameters = tp_asv_new ("badger", G_TYPE_UINT, 42,
NULL);
}
if (self->priv->supported_access_controls == NULL)
{
GArray *acontrols;
TpSocketAccessControl a;
acontrols = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
a = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
acontrols = g_array_append_val (acontrols, a);
self->priv->supported_access_controls = acontrols;
}
tp_base_channel_register (TP_BASE_CHANNEL (self));
return object;
}
static void
dispose (GObject *object)
{
TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) object;
tp_clear_pointer (&self->priv->dbus_names, g_hash_table_unref);
if (self->priv->supported_access_controls != NULL)
g_array_free (self->priv->supported_access_controls, TRUE);
if (self->priv->parameters != NULL)
g_hash_table_destroy (self->priv->parameters);
if (self->priv->dbus_srv != NULL)
dbus_server_unref (self->priv->dbus_srv);
if (self->priv->dbus_conn != NULL)
dbus_connection_unref (self->priv->dbus_conn);
if (self->priv->dbus_srv_addr != NULL)
g_free (self->priv->dbus_srv_addr);
if (self->priv->socket_path != NULL)
g_free (self->priv->socket_path);
((GObjectClass *) tp_tests_dbus_tube_channel_parent_class)->dispose (
object);
}
static void
channel_close (TpBaseChannel *channel)
{
tp_base_channel_destroyed (channel);
}
static void
fill_immutable_properties (TpBaseChannel *chan,
GHashTable *properties)
{
TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
tp_tests_dbus_tube_channel_parent_class);
klass->fill_immutable_properties (chan, properties);
tp_dbus_properties_mixin_fill_properties_hash (
G_OBJECT (chan), properties,
TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName",
TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls",
NULL);
if (!tp_base_channel_is_requested (chan))
{
/* Parameters is immutable only for incoming tubes */
tp_dbus_properties_mixin_fill_properties_hash (
G_OBJECT (chan), properties,
TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
NULL);
}
}
static void
tp_tests_dbus_tube_channel_class_init (TpTestsDBusTubeChannelClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = {
{ "ServiceName", "service-name", NULL, },
{ "DBusNames", "dbus-names", NULL, },
{ "SupportedAccessControls", "supported-access-controls", NULL, },
{ NULL }
};
static TpDBusPropertiesMixinPropImpl tube_props[] = {
{ "Parameters", "parameters", NULL, },
{ "State", "state", NULL, },
{ NULL }
};
object_class->constructor = constructor;
object_class->get_property = tp_tests_dbus_tube_channel_get_property;
object_class->set_property = tp_tests_dbus_tube_channel_set_property;
object_class->dispose = dispose;
base_class->channel_type = TP_IFACE_CHANNEL_TYPE_DBUS_TUBE;
base_class->interfaces = tp_tests_dbus_tube_channel_interfaces;
base_class->close = channel_close;
base_class->fill_immutable_properties = fill_immutable_properties;
/* base_class->target_handle_type is defined in subclasses */
param_spec = g_param_spec_string ("service-name", "Service Name",
"the service name associated with this tube object.",
"",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SERVICE_NAME, param_spec);
param_spec = g_param_spec_boxed ("dbus-names", "DBus Names",
"DBusTube.DBusNames",
TP_HASH_TYPE_DBUS_TUBE_PARTICIPANTS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec);
param_spec = g_param_spec_boxed ("supported-access-controls",
"Supported access-controls",
"GArray containing supported access controls.",
DBUS_TYPE_G_UINT_ARRAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class,
PROP_SUPPORTED_ACCESS_CONTROLS, param_spec);
param_spec = g_param_spec_string (
"dbus-address",
"D-Bus address",
"The D-Bus address on which this tube will listen for connections",
"",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DBUS_ADDRESS,
param_spec);
param_spec = g_param_spec_boxed (
"parameters", "Parameters",
"parameters of the tube",
TP_HASH_TYPE_STRING_VARIANT_MAP,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_PARAMETERS,
param_spec);
param_spec = g_param_spec_uint (
"state", "TpTubeState",
"state of the tube",
0, NUM_TP_TUBE_CHANNEL_STATES - 1, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_STATE,
param_spec);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
dbus_tube_props);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_INTERFACE_TUBE,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
tube_props);
g_type_class_add_private (object_class,
sizeof (TpTestsDBusTubeChannelPrivate));
}
static gboolean
check_access_control (TpTestsDBusTubeChannel *self,
TpSocketAccessControl access_control)
{
guint i;
for (i = 0; i < self->priv->supported_access_controls->len; i++)
{
if (g_array_index (self->priv->supported_access_controls, TpSocketAccessControl, i) == access_control)
return TRUE;
}
return FALSE;
}
static void
change_state (TpTestsDBusTubeChannel *self,
TpTubeChannelState state)
{
self->priv->state = state;
tp_svc_channel_interface_tube_emit_tube_channel_state_changed (self, state);
}
/*
* Characters used are permissible both in filenames and in D-Bus names. (See
* D-Bus specification for restrictions.)
*/
static void
generate_ascii_string (guint len,
gchar *buf)
{
const gchar *chars =
"0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"_-";
guint i;
for (i = 0; i < len; i++)
buf[i] = chars[g_random_int_range (0, 64)];
}
static DBusHandlerResult
filter_cb (DBusConnection *conn,
DBusMessage *msg,
void *user_data)
{
TpTestsDBusTubeChannel *self = TP_TESTS_DBUS_TUBE_CHANNEL (user_data);
TpTestsDBusTubeChannelPrivate *priv = self->priv;
gchar *marshalled = NULL;
gint len;
if (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_SIGNAL &&
!tp_strdiff (dbus_message_get_interface (msg),
"org.freedesktop.DBus.Local") &&
!tp_strdiff (dbus_message_get_member (msg), "Disconnected"))
{
/* connection was disconnected */
g_debug ("connection was disconnected");
dbus_connection_close (priv->dbus_conn);
tp_clear_pointer (&priv->dbus_conn, dbus_connection_unref);
goto out;
}
if (priv->dbus_local_name != NULL)
{
if (!dbus_message_set_sender (msg, priv->dbus_local_name))
g_debug ("dbus_message_set_sender failed");
}
if (!dbus_message_marshal (msg, &marshalled, &len))
goto out;
out:
if (marshalled != NULL)
g_free (marshalled);
return DBUS_HANDLER_RESULT_HANDLED;
}
static dbus_bool_t
allow_all_connections (DBusConnection *conn,
unsigned long uid,
void *data)
{
return TRUE;
}
static void
new_connection_cb (DBusServer *server,
DBusConnection *conn,
void *data)
{
TpTestsDBusTubeChannel *self = TP_TESTS_DBUS_TUBE_CHANNEL (data);
TpTestsDBusTubeChannelPrivate *priv = self->priv;
guint32 serial;
GSList *i;
if (priv->dbus_conn != NULL)
/* we already have a connection; drop this new one */
/* return without reffing conn means it will be dropped */
return;
dbus_connection_ref (conn);
dbus_connection_setup_with_g_main (conn, NULL);
dbus_connection_add_filter (conn, filter_cb, self, NULL);
priv->dbus_conn = conn;
if (priv->access_control == TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
{
/* By default libdbus use Credentials access control. If user wants
* to use the Localhost access control, we need to bypass this check. */
dbus_connection_set_unix_user_function (conn, allow_all_connections,
NULL, NULL);
}
/* We may have received messages to deliver before the local connection is
* established. Theses messages are kept in the dbus_msg_queue list and are
* delivered as soon as we get the connection. */
g_debug ("%u messages in the queue (%lu bytes)",
g_slist_length (priv->dbus_msg_queue), priv->dbus_msg_queue_size);
priv->dbus_msg_queue = g_slist_reverse (priv->dbus_msg_queue);
for (i = priv->dbus_msg_queue; i != NULL; i = g_slist_delete_link (i, i))
{
DBusMessage *msg = i->data;
g_debug ("delivering queued message from '%s' to '%s' on the "
"new connection",
dbus_message_get_sender (msg),
dbus_message_get_destination (msg));
dbus_connection_send (priv->dbus_conn, msg, &serial);
dbus_message_unref (msg);
}
priv->dbus_msg_queue = NULL;
priv->dbus_msg_queue_size = 0;
}
/* There is two step to enable receiving a D-Bus connection from the local
* application:
* - listen on the socket
* - add the socket in the mainloop
*
* We need to know the socket path to return from the AcceptDBusTube D-Bus
* call but the socket in the mainloop must be added only when we are ready
* to receive connections, that is when the bytestream is fully open with the
* remote contact.
*
* See also Bug 13891:
* https://bugs.freedesktop.org/show_bug.cgi?id=13891
* */
static gboolean
create_dbus_server (TpTestsDBusTubeChannel *self,
GError **err)
{
#define SERVER_LISTEN_MAX_TRIES 5
TpTestsDBusTubeChannelPrivate *priv = self->priv;
guint i;
if (priv->dbus_srv != NULL)
return TRUE;
for (i = 0; i < SERVER_LISTEN_MAX_TRIES; i++)
{
gchar suffix[8];
DBusError error;
g_free (priv->dbus_srv_addr);
g_free (priv->socket_path);
generate_ascii_string (8, suffix);
priv->socket_path = g_strdup_printf ("%s/dbus-tpqt4-test-%.8s",
g_get_tmp_dir (), suffix);
priv->dbus_srv_addr = g_strdup_printf ("unix:path=%s",
priv->socket_path);
dbus_error_init (&error);
priv->dbus_srv = dbus_server_listen (priv->dbus_srv_addr, &error);
if (priv->dbus_srv != NULL)
break;
g_debug ("dbus_server_listen failed (try %u): %s: %s", i, error.name,
error.message);
dbus_error_free (&error);
}
if (priv->dbus_srv == NULL)
{
g_debug ("all attempts failed. Close the tube");
g_free (priv->dbus_srv_addr);
priv->dbus_srv_addr = NULL;
g_free (priv->socket_path);
priv->socket_path = NULL;
g_set_error (err, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
"Can't create D-Bus server");
return FALSE;
}
g_debug ("listening on %s", priv->dbus_srv_addr);
dbus_server_set_new_connection_function (priv->dbus_srv, new_connection_cb,
self, NULL);
return TRUE;
}
static void
dbus_tube_offer (TpSvcChannelTypeDBusTube *iface,
GHashTable *parameters,
guint access_control,
DBusGMethodInvocation *context)
{
TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) iface;
GError *error = NULL;
if (self->priv->state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED)
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Tube is not in the not offered state");
goto fail;
}
if (!check_access_control (self, access_control))
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Address type not supported with this access control");
goto fail;
}
self->priv->access_control = access_control;
if (!create_dbus_server (self, &error))
goto fail;
g_object_set (self, "parameters", parameters, NULL);
change_state (self, TP_TUBE_CHANNEL_STATE_REMOTE_PENDING);
tp_svc_channel_type_dbus_tube_return_from_offer (context, self->priv->dbus_srv_addr);
return;
fail:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static void
dbus_tube_accept (TpSvcChannelTypeDBusTube *iface,
guint access_control,
DBusGMethodInvocation *context)
{
TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) iface;
GError *error = NULL;
if (self->priv->state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING)
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Tube is not in the local pending state");
goto fail;
}
if (!check_access_control (self, access_control))
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Address type not supported with this access control");
goto fail;
}
if (self->priv->close_on_accept)
{
tp_base_channel_close (TP_BASE_CHANNEL (self));
return;
}
if (!create_dbus_server (self, &error))
goto fail;
change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
tp_svc_channel_type_dbus_tube_return_from_accept (context, self->priv->dbus_srv_addr);
return;
fail:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static void
dbus_tube_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelTypeDBusTubeClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_type_dbus_tube_implement_##x (klass, dbus_tube_##x)
IMPLEMENT(offer);
IMPLEMENT(accept);
#undef IMPLEMENT
}
/* Called to emulate a peer connecting to an offered tube */
void
tp_tests_dbus_tube_channel_peer_connected_no_stream (TpTestsDBusTubeChannel *self,
gchar *bus_name,
TpHandle handle)
{
GHashTable *added;
GArray *removed;
if (self->priv->state == TP_TUBE_CHANNEL_STATE_REMOTE_PENDING)
change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
g_assert (self->priv->state == TP_TUBE_CHANNEL_STATE_OPEN);
added = g_hash_table_new (g_direct_hash, g_direct_equal);
removed = g_array_new (FALSE, FALSE, sizeof (TpHandle));
g_hash_table_insert (added, GUINT_TO_POINTER (handle), bus_name);
// Add to the global hash table as well
g_hash_table_insert (self->priv->dbus_names, GUINT_TO_POINTER (handle), bus_name);
tp_svc_channel_type_dbus_tube_emit_dbus_names_changed (self, added,
removed);
g_hash_table_destroy (added);
g_array_free (removed, TRUE);
}
/* Called to emulate a peer connecting to an offered tube */
void
tp_tests_dbus_tube_channel_peer_disconnected (TpTestsDBusTubeChannel *self,
TpHandle handle)
{
GHashTable *added;
GArray *removed;
g_assert (self->priv->state == TP_TUBE_CHANNEL_STATE_OPEN);
added = g_hash_table_new (g_direct_hash, g_direct_equal);
removed = g_array_new (FALSE, FALSE, sizeof (TpHandle));
g_array_append_val (removed, handle);
// Remove from the global hash table as well
g_hash_table_remove (self->priv->dbus_names, GUINT_TO_POINTER (handle));
tp_svc_channel_type_dbus_tube_emit_dbus_names_changed (self, added,
removed);
g_hash_table_destroy (added);
g_array_free (removed, TRUE);
}
void
tp_tests_dbus_tube_channel_set_close_on_accept (
TpTestsDBusTubeChannel *self,
gboolean close_on_accept)
{
self->priv->close_on_accept = close_on_accept;
}
/* Contact DBus Tube */
G_DEFINE_TYPE (TpTestsContactDBusTubeChannel,
tp_tests_contact_dbus_tube_channel,
TP_TESTS_TYPE_DBUS_TUBE_CHANNEL)
static void
tp_tests_contact_dbus_tube_channel_init (
TpTestsContactDBusTubeChannel *self)
{
}
static void
tp_tests_contact_dbus_tube_channel_class_init (
TpTestsContactDBusTubeChannelClass *klass)
{
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
}
/* Room DBus Tube */
G_DEFINE_TYPE (TpTestsRoomDBusTubeChannel,
tp_tests_room_dbus_tube_channel,
TP_TESTS_TYPE_DBUS_TUBE_CHANNEL)
static void
tp_tests_room_dbus_tube_channel_init (
TpTestsRoomDBusTubeChannel *self)
{
}
static void
tp_tests_room_dbus_tube_channel_class_init (
TpTestsRoomDBusTubeChannelClass *klass)
{
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
base_class->target_handle_type = TP_HANDLE_TYPE_ROOM;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/contacts-conn.c 0000664 0001750 0001750 00000127270 12470405660 020523 0 ustar jr jr /*
* contacts-conn.c - connection with contact info
*
* Copyright (C) 2007-2008 Collabora Ltd.
* Copyright (C) 2007-2008 Nokia Corporation
*
* 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.
*/
#include "contacts-conn.h"
#include
#include
#include
#include
#include
#include
#include
#include "debug.h"
static void init_aliasing (gpointer, gpointer);
static void init_avatars (gpointer, gpointer);
static void init_location (gpointer, gpointer);
static void init_contact_caps (gpointer, gpointer);
static void init_contact_info (gpointer, gpointer);
static void init_client_types (gpointer, gpointer);
static void conn_avatars_properties_getter (GObject *object, GQuark interface,
GQuark name, GValue *value, gpointer getter_data);
G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection,
tp_tests_contacts_connection,
TP_TESTS_TYPE_SIMPLE_CONNECTION,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING,
init_aliasing);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_AVATARS,
init_avatars);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE,
tp_presence_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
tp_presence_mixin_simple_presence_iface_init)
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_LOCATION,
init_location)
G_IMPLEMENT_INTERFACE (
TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
init_contact_caps)
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO,
init_contact_info)
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES,
init_client_types);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
tp_contacts_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST,
tp_base_contact_list_mixin_list_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS,
tp_base_contact_list_mixin_groups_iface_init);
);
/* type definition stuff */
static const char *mime_types[] = { "image/png", NULL };
static TpDBusPropertiesMixinPropImpl conn_avatars_properties[] = {
{ "MinimumAvatarWidth", GUINT_TO_POINTER (1), NULL },
{ "MinimumAvatarHeight", GUINT_TO_POINTER (2), NULL },
{ "RecommendedAvatarWidth", GUINT_TO_POINTER (3), NULL },
{ "RecommendedAvatarHeight", GUINT_TO_POINTER (4), NULL },
{ "MaximumAvatarWidth", GUINT_TO_POINTER (5), NULL },
{ "MaximumAvatarHeight", GUINT_TO_POINTER (6), NULL },
{ "MaximumAvatarBytes", GUINT_TO_POINTER (7), NULL },
/* special-cased - it's the only one with a non-guint value */
{ "SupportedAvatarMIMETypes", NULL, NULL },
{ NULL }
};
enum
{
N_SIGNALS
};
struct _TpTestsContactsConnectionPrivate
{
/* TpHandle => gchar * */
GHashTable *aliases;
/* TpHandle => AvatarData */
GHashTable *avatars;
/* TpHandle => ContactsConnectionPresenceStatusIndex */
GHashTable *presence_statuses;
/* TpHandle => gchar * */
GHashTable *presence_messages;
/* TpHandle => GHashTable * */
GHashTable *locations;
/* TpHandle => GPtrArray * */
GHashTable *capabilities;
/* TpHandle => GPtrArray * */
GHashTable *contact_info;
GPtrArray *default_contact_info;
/* TpHandle => gchar ** */
GHashTable *client_types;
TestContactListManager *list_manager;
};
typedef struct
{
GArray *data;
gchar *mime_type;
gchar *token;
} AvatarData;
static AvatarData *
avatar_data_new (GArray *data,
const gchar *mime_type,
const gchar *token)
{
AvatarData *a;
a = g_slice_new (AvatarData);
a->data = data ? g_array_ref (data) : NULL;
a->mime_type = g_strdup (mime_type);
a->token = g_strdup (token);
return a;
}
static void
avatar_data_free (gpointer data)
{
AvatarData *a = data;
if (a != NULL)
{
if (a->data != NULL)
g_array_unref (a->data);
g_free (a->mime_type);
g_free (a->token);
g_slice_free (AvatarData, a);
}
}
static void
free_rcc_list (GPtrArray *rccs)
{
g_boxed_free (TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, rccs);
}
static void
tp_tests_contacts_connection_init (TpTestsContactsConnection *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_CONTACTS_CONNECTION,
TpTestsContactsConnectionPrivate);
self->priv->aliases = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_free);
self->priv->avatars = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, avatar_data_free);
self->priv->presence_statuses = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, NULL);
self->priv->presence_messages = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, g_free);
self->priv->locations = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) g_hash_table_unref);
self->priv->capabilities = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify) free_rcc_list);
self->priv->contact_info = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify) g_ptr_array_unref);
self->priv->default_contact_info = (GPtrArray *) dbus_g_type_specialized_construct (
TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST);
self->priv->client_types = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify) g_strfreev);
}
static void
finalize (GObject *object)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
tp_contacts_mixin_finalize (object);
g_hash_table_destroy (self->priv->aliases);
g_hash_table_destroy (self->priv->avatars);
g_hash_table_destroy (self->priv->presence_statuses);
g_hash_table_destroy (self->priv->presence_messages);
g_hash_table_destroy (self->priv->locations);
g_hash_table_destroy (self->priv->capabilities);
g_hash_table_destroy (self->priv->contact_info);
g_hash_table_destroy (self->priv->client_types);
if (self->priv->default_contact_info != NULL)
g_ptr_array_unref (self->priv->default_contact_info);
G_OBJECT_CLASS (tp_tests_contacts_connection_parent_class)->finalize (object);
}
static void
aliasing_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
TpBaseConnection *base = TP_BASE_CONNECTION (object);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
const gchar *alias = g_hash_table_lookup (self->priv->aliases,
GUINT_TO_POINTER (handle));
if (alias == NULL)
{
alias = tp_handle_inspect (contact_repo, handle);
}
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_ALIASING "/alias",
tp_g_value_slice_new_string (alias));
}
}
static void
avatars_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
AvatarData *a = g_hash_table_lookup (self->priv->avatars,
GUINT_TO_POINTER (handle));
if (a != NULL && a->token != NULL)
{
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_AVATARS "/token",
tp_g_value_slice_new_string (a->token));
}
}
}
static void
location_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
GHashTable *location = g_hash_table_lookup (self->priv->locations,
GUINT_TO_POINTER (handle));
if (location != NULL)
{
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_LOCATION "/location",
tp_g_value_slice_new_boxed (TP_HASH_TYPE_LOCATION, location));
}
}
}
static void
contact_caps_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
GPtrArray *caps = g_hash_table_lookup (self->priv->capabilities,
GUINT_TO_POINTER (handle));
if (caps != NULL)
{
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES "/capabilities",
tp_g_value_slice_new_boxed (
TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, caps));
}
}
}
static void
contact_info_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
GPtrArray *info = g_hash_table_lookup (self->priv->contact_info,
GUINT_TO_POINTER (handle));
if (info != NULL)
{
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO "/info",
tp_g_value_slice_new_boxed (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST,
info));
}
}
}
static TpDBusPropertiesMixinPropImpl conn_contact_info_properties[] = {
{ "ContactInfoFlags", GUINT_TO_POINTER (TP_CONTACT_INFO_FLAG_PUSH |
TP_CONTACT_INFO_FLAG_CAN_SET), NULL },
{ "SupportedFields", NULL, NULL },
{ NULL }
};
static void
conn_contact_info_properties_getter (GObject *object,
GQuark interface,
GQuark name,
GValue *value,
gpointer getter_data)
{
GQuark q_supported_fields = g_quark_from_static_string ("SupportedFields");
static GPtrArray *supported_fields = NULL;
if (name == q_supported_fields)
{
if (supported_fields == NULL)
{
supported_fields = g_ptr_array_new ();
g_ptr_array_add (supported_fields, tp_value_array_build (4,
G_TYPE_STRING, "n",
G_TYPE_STRV, NULL,
G_TYPE_UINT, 0,
G_TYPE_UINT, 0,
G_TYPE_INVALID));
}
g_value_set_boxed (value, supported_fields);
}
else
{
g_value_set_uint (value, GPOINTER_TO_UINT (getter_data));
}
}
static void
client_types_fill_contact_attributes (
GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
guint i;
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
gchar **types = g_hash_table_lookup (self->priv->client_types,
GUINT_TO_POINTER (handle));
if (types != NULL)
{
tp_contacts_mixin_set_contact_attribute (attributes, handle,
TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES "/client-types",
tp_g_value_slice_new_boxed (G_TYPE_STRV, types));
}
}
}
static void
constructed (GObject *object)
{
TpBaseConnection *base = TP_BASE_CONNECTION (object);
void (*parent_impl) (GObject *) =
G_OBJECT_CLASS (tp_tests_contacts_connection_parent_class)->constructed;
if (parent_impl != NULL)
parent_impl (object);
tp_contacts_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactsConnection, contacts_mixin));
tp_base_connection_register_with_contacts_mixin (base);
tp_base_contact_list_mixin_register_with_contacts_mixin (base);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
aliasing_fill_contact_attributes);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
avatars_fill_contact_attributes);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
location_fill_contact_attributes);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
contact_caps_fill_contact_attributes);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
contact_info_fill_contact_attributes);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES,
client_types_fill_contact_attributes);
tp_presence_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactsConnection, presence_mixin));
tp_presence_mixin_simple_presence_register_with_contacts_mixin (object);
}
static const TpPresenceStatusOptionalArgumentSpec can_have_message[] = {
{ "message", "s", NULL, NULL },
{ NULL }
};
/* Must match TpTestsContactsConnectionPresenceStatusIndex in the .h */
static const TpPresenceStatusSpec my_statuses[] = {
{ "available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE,
can_have_message },
{ "busy", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE, can_have_message },
{ "away", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE, can_have_message },
{ "offline", TP_CONNECTION_PRESENCE_TYPE_OFFLINE, FALSE, NULL },
{ "unknown", TP_CONNECTION_PRESENCE_TYPE_UNKNOWN, FALSE, NULL },
{ "error", TP_CONNECTION_PRESENCE_TYPE_ERROR, FALSE, NULL },
{ NULL }
};
static gboolean
my_status_available (GObject *object,
guint index)
{
TpBaseConnection *base = TP_BASE_CONNECTION (object);
if (base->status != TP_CONNECTION_STATUS_CONNECTED)
return FALSE;
return TRUE;
}
static GHashTable *
my_get_contact_statuses (GObject *object,
const GArray *contacts,
GError **error)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) tp_presence_status_free);
guint i;
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
gpointer key = GUINT_TO_POINTER (handle);
TpTestsContactsConnectionPresenceStatusIndex index;
const gchar *presence_message;
GHashTable *parameters;
index = GPOINTER_TO_UINT (g_hash_table_lookup (
self->priv->presence_statuses, key));
presence_message = g_hash_table_lookup (
self->priv->presence_messages, key);
parameters = g_hash_table_new_full (g_str_hash,
g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);
if (presence_message != NULL)
g_hash_table_insert (parameters, "message",
tp_g_value_slice_new_string (presence_message));
g_hash_table_insert (result, key,
tp_presence_status_new (index, parameters));
g_hash_table_destroy (parameters);
}
return result;
}
static gboolean
my_set_own_status (GObject *object,
const TpPresenceStatus *status,
GError **error)
{
TpBaseConnection *base_conn = TP_BASE_CONNECTION (object);
TpTestsContactsConnectionPresenceStatusIndex index = status->index;
const gchar *message = "";
if (status->optional_arguments != NULL)
{
message = g_hash_table_lookup (status->optional_arguments, "message");
if (message == NULL)
message = "";
}
tp_tests_contacts_connection_change_presences (TP_TESTS_CONTACTS_CONNECTION (object),
1, &(base_conn->self_handle), &index, &message);
return TRUE;
}
static guint
my_get_maximum_status_message_length_cb (GObject *obj)
{
return 512;
}
static GPtrArray *
create_channel_managers (TpBaseConnection *conn)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (conn);
GPtrArray *ret = g_ptr_array_sized_new (1);
self->priv->list_manager = g_object_new (TEST_TYPE_CONTACT_LIST_MANAGER,
"connection", conn, NULL);
g_ptr_array_add (ret, self->priv->list_manager);
return ret;
}
static void
tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
{
TpBaseConnectionClass *base_class =
(TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
TpPresenceMixinClass *mixin_class;
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
NULL };
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CONNECTION_INTERFACE_AVATARS,
conn_avatars_properties_getter,
NULL,
conn_avatars_properties,
},
{ TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
conn_contact_info_properties_getter,
NULL,
conn_contact_info_properties,
},
{ NULL }
};
object_class->constructed = constructed;
object_class->finalize = finalize;
g_type_class_add_private (klass, sizeof (TpTestsContactsConnectionPrivate));
base_class->interfaces_always_present = interfaces_always_present;
base_class->create_channel_managers = create_channel_managers;
tp_contacts_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsContactsConnectionClass, contacts_mixin));
tp_presence_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsContactsConnectionClass, presence_mixin),
my_status_available, my_get_contact_statuses,
my_set_own_status, my_statuses);
mixin_class = TP_PRESENCE_MIXIN_CLASS(klass);
mixin_class->get_maximum_status_message_length =
my_get_maximum_status_message_length_cb;
tp_presence_mixin_simple_presence_init_dbus_properties (object_class);
klass->properties_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsContactsConnectionClass, properties_class));
tp_base_contact_list_mixin_class_init (base_class);
}
TestContactListManager *
tp_tests_contacts_connection_get_contact_list_manager (
TpTestsContactsConnection *self)
{
return self->priv->list_manager;
}
void
tp_tests_contacts_connection_change_aliases (TpTestsContactsConnection *self,
guint n,
const TpHandle *handles,
const gchar * const *aliases)
{
GPtrArray *structs = g_ptr_array_sized_new (n);
guint i;
for (i = 0; i < n; i++)
{
GValueArray *pair = g_value_array_new (2);
DEBUG ("contact#%u -> %s", handles[i], aliases[i]);
g_hash_table_insert (self->priv->aliases,
GUINT_TO_POINTER (handles[i]), g_strdup (aliases[i]));
g_value_array_append (pair, NULL);
g_value_init (pair->values + 0, G_TYPE_UINT);
g_value_set_uint (pair->values + 0, handles[i]);
g_value_array_append (pair, NULL);
g_value_init (pair->values + 1, G_TYPE_STRING);
g_value_set_string (pair->values + 1, aliases[i]);
g_ptr_array_add (structs, pair);
}
tp_svc_connection_interface_aliasing_emit_aliases_changed (self,
structs);
g_ptr_array_foreach (structs, (GFunc) g_value_array_free, NULL);
g_ptr_array_free (structs, TRUE);
}
void
tp_tests_contacts_connection_change_presences (
TpTestsContactsConnection *self,
guint n,
const TpHandle *handles,
const TpTestsContactsConnectionPresenceStatusIndex *indexes,
const gchar * const *messages)
{
GHashTable *presences = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) tp_presence_status_free);
guint i;
for (i = 0; i < n; i++)
{
GHashTable *parameters;
gpointer key = GUINT_TO_POINTER (handles[i]);
DEBUG ("contact#%u -> %s \"%s\"", handles[i],
my_statuses[indexes[i]].name, messages[i]);
g_hash_table_insert (self->priv->presence_statuses, key,
GUINT_TO_POINTER (indexes[i]));
g_hash_table_insert (self->priv->presence_messages, key,
g_strdup (messages[i]));
parameters = g_hash_table_new_full (g_str_hash,
g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);
if (messages[i] != NULL && messages[i][0] != '\0')
g_hash_table_insert (parameters, "message",
tp_g_value_slice_new_string (messages[i]));
g_hash_table_insert (presences, key, tp_presence_status_new (indexes[i],
parameters));
g_hash_table_destroy (parameters);
}
tp_presence_mixin_emit_presence_update ((GObject *) self,
presences);
g_hash_table_destroy (presences);
}
void
tp_tests_contacts_connection_change_avatar_tokens (TpTestsContactsConnection *self,
guint n,
const TpHandle *handles,
const gchar * const *tokens)
{
guint i;
for (i = 0; i < n; i++)
{
DEBUG ("contact#%u -> %s", handles[i], tokens[i]);
g_hash_table_insert (self->priv->avatars,
GUINT_TO_POINTER (handles[i]), avatar_data_new (NULL, NULL, tokens[i]));
tp_svc_connection_interface_avatars_emit_avatar_updated (self,
handles[i], tokens[i]);
}
}
void
tp_tests_contacts_connection_change_avatar_data (
TpTestsContactsConnection *self,
TpHandle handle,
GArray *data,
const gchar *mime_type,
const gchar *token,
gboolean emit_avatar_updated)
{
g_hash_table_insert (self->priv->avatars,
GUINT_TO_POINTER (handle), avatar_data_new (data, mime_type, token));
if (emit_avatar_updated)
{
tp_svc_connection_interface_avatars_emit_avatar_updated (self,
handle, token);
}
}
void
tp_tests_contacts_connection_change_locations (TpTestsContactsConnection *self,
guint n,
const TpHandle *handles,
GHashTable **locations)
{
guint i;
for (i = 0; i < n; i++)
{
DEBUG ("contact#%u ->", handles[i]);
tp_asv_dump (locations[i]);
g_hash_table_insert (self->priv->locations,
GUINT_TO_POINTER (handles[i]), g_hash_table_ref (locations[i]));
tp_svc_connection_interface_location_emit_location_updated (self,
handles[i], locations[i]);
}
}
void
tp_tests_contacts_connection_change_capabilities (
TpTestsContactsConnection *self,
GHashTable *capabilities)
{
GHashTableIter iter;
gpointer handle, caps;
g_hash_table_iter_init (&iter, capabilities);
while (g_hash_table_iter_next (&iter, &handle, &caps))
{
g_hash_table_insert (self->priv->capabilities,
handle,
g_boxed_copy (TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST,
caps));
}
tp_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
self, capabilities);
}
void
tp_tests_contacts_connection_change_contact_info (
TpTestsContactsConnection *self,
TpHandle handle,
GPtrArray *info)
{
g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (handle),
g_ptr_array_ref (info));
tp_svc_connection_interface_contact_info_emit_contact_info_changed (self,
handle, info);
}
void
tp_tests_contacts_connection_set_default_contact_info (
TpTestsContactsConnection *self,
GPtrArray *info)
{
if (self->priv->default_contact_info != NULL)
g_ptr_array_unref (self->priv->default_contact_info);
self->priv->default_contact_info = g_ptr_array_ref (info);
}
void
tp_tests_contacts_connection_change_client_types(
TpTestsContactsConnection *self,
TpHandle handle,
gchar **client_types)
{
g_hash_table_insert (self->priv->client_types, GUINT_TO_POINTER (handle),
client_types);
tp_svc_connection_interface_client_types_emit_client_types_updated (self,
handle, (const gchar **) client_types);
}
static void
my_get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
DBusGMethodInvocation *context)
{
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context,
0);
}
static void
my_get_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (aliasing);
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GHashTable *result;
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
const gchar *alias = g_hash_table_lookup (self->priv->aliases,
GUINT_TO_POINTER (handle));
if (alias == NULL)
g_hash_table_insert (result, GUINT_TO_POINTER (handle),
(gchar *) tp_handle_inspect (contact_repo, handle));
else
g_hash_table_insert (result, GUINT_TO_POINTER (handle),
(gchar *) alias);
}
tp_svc_connection_interface_aliasing_return_from_get_aliases (context,
result);
g_hash_table_destroy (result);
}
static void
my_request_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (aliasing);
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GPtrArray *result;
gchar **strings;
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_ptr_array_sized_new (contacts->len + 1);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
const gchar *alias = g_hash_table_lookup (self->priv->aliases,
GUINT_TO_POINTER (handle));
if (alias == NULL)
g_ptr_array_add (result,
(gchar *) tp_handle_inspect (contact_repo, handle));
else
g_ptr_array_add (result, (gchar *) alias);
}
g_ptr_array_add (result, NULL);
strings = (gchar **) g_ptr_array_free (result, FALSE);
tp_svc_connection_interface_aliasing_return_from_request_aliases (context,
(const gchar **) strings);
g_free (strings);
}
static void
init_aliasing (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceAliasingClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_aliasing_implement_##x (\
klass, my_##x)
IMPLEMENT(get_alias_flags);
IMPLEMENT(request_aliases);
IMPLEMENT(get_aliases);
/* IMPLEMENT(set_aliases); */
#undef IMPLEMENT
}
static void
my_get_avatar_tokens (TpSvcConnectionInterfaceAvatars *avatars,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
GHashTable *result;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
AvatarData *a = g_hash_table_lookup (self->priv->avatars,
GUINT_TO_POINTER (handle));
if (a == NULL || a->token == NULL)
{
/* we're expected to do a round-trip to the server to find out
* their token, so we have to give some sort of result. Assume
* no avatar, here */
a = avatar_data_new (NULL, NULL, "");
g_hash_table_insert (self->priv->avatars,
GUINT_TO_POINTER (handle), a);
tp_svc_connection_interface_avatars_emit_avatar_updated (self,
handle, a->token);
}
g_hash_table_insert (result, GUINT_TO_POINTER (handle),
a->token);
}
tp_svc_connection_interface_avatars_return_from_get_known_avatar_tokens (
context, result);
g_hash_table_destroy (result);
}
static void
my_get_known_avatar_tokens (TpSvcConnectionInterfaceAvatars *avatars,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
GHashTable *result;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
AvatarData *a = g_hash_table_lookup (self->priv->avatars,
GUINT_TO_POINTER (handle));
const gchar *token = a ? a->token : NULL;
g_hash_table_insert (result, GUINT_TO_POINTER (handle),
(gchar *) (token != NULL ? token : ""));
}
tp_svc_connection_interface_avatars_return_from_get_known_avatar_tokens (
context, result);
g_hash_table_destroy (result);
}
static void
my_request_avatars (TpSvcConnectionInterfaceAvatars *avatars,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
AvatarData *a = g_hash_table_lookup (self->priv->avatars,
GUINT_TO_POINTER (handle));
if (a != NULL)
tp_svc_connection_interface_avatars_emit_avatar_retrieved (self, handle,
a->token, a->data, a->mime_type);
}
tp_svc_connection_interface_avatars_return_from_request_avatars (context);
}
static void
conn_avatars_properties_getter (GObject *object,
GQuark interface,
GQuark name,
GValue *value,
gpointer getter_data)
{
GQuark q_mime_types = g_quark_from_static_string (
"SupportedAvatarMIMETypes");
if (name == q_mime_types)
{
g_value_set_static_boxed (value, mime_types);
}
else
{
g_value_set_uint (value, GPOINTER_TO_UINT (getter_data));
}
}
static void
init_avatars (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceAvatarsClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_avatars_implement_##x (\
klass, my_##x)
/* IMPLEMENT(get_avatar_requirements); */
IMPLEMENT(get_avatar_tokens);
IMPLEMENT(get_known_avatar_tokens);
/* IMPLEMENT(request_avatar); */
IMPLEMENT(request_avatars);
/* IMPLEMENT(set_avatar); */
/* IMPLEMENT(clear_avatar); */
#undef IMPLEMENT
}
static void
my_get_locations (TpSvcConnectionInterfaceLocation *avatars,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
GHashTable *result;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
GHashTable *location = g_hash_table_lookup (self->priv->locations,
GUINT_TO_POINTER (handle));
if (location != NULL)
{
g_hash_table_insert (result, GUINT_TO_POINTER (handle), location);
}
}
tp_svc_connection_interface_location_return_from_get_locations (
context, result);
g_hash_table_destroy (result);
}
static void
init_location (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceLocationClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_location_implement_##x (\
klass, my_##x)
IMPLEMENT(get_locations);
#undef IMPLEMENT
}
static void
my_get_contact_capabilities (TpSvcConnectionInterfaceContactCapabilities *obj,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
TpBaseConnection *base = TP_BASE_CONNECTION (obj);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
GHashTable *result;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, TpHandle, i);
GPtrArray *arr = g_hash_table_lookup (self->priv->capabilities,
GUINT_TO_POINTER (handle));
if (arr != NULL)
{
g_hash_table_insert (result, GUINT_TO_POINTER (handle), arr);
}
}
tp_svc_connection_interface_contact_capabilities_return_from_get_contact_capabilities (
context, result);
g_hash_table_destroy (result);
}
static void
init_contact_caps (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceContactCapabilitiesClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_contact_capabilities_implement_##x (\
klass, my_##x)
IMPLEMENT(get_contact_capabilities);
#undef IMPLEMENT
}
static GPtrArray *
lookup_contact_info (TpTestsContactsConnection *self,
TpHandle handle)
{
GPtrArray *ret = g_hash_table_lookup (self->priv->contact_info,
GUINT_TO_POINTER (handle));
if (ret == NULL && self->priv->default_contact_info != NULL)
{
ret = self->priv->default_contact_info;
g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (handle),
g_ptr_array_ref (ret));
}
if (ret == NULL)
return g_ptr_array_new ();
return g_ptr_array_ref (ret);
}
static void
my_refresh_contact_info (TpSvcConnectionInterfaceContactInfo *obj,
const GArray *contacts,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
TpBaseConnection *base = TP_BASE_CONNECTION (obj);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
self->refresh_contact_info_called++;
for (i = 0; i < contacts->len; i++)
{
TpHandle handle = g_array_index (contacts, guint, i);
// actually update the info (if not using the default info) so there is an actual change
g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (handle),
g_ptr_array_ref (self->priv->default_contact_info));
tp_svc_connection_interface_contact_info_emit_contact_info_changed (self,
handle, self->priv->default_contact_info);
}
tp_svc_connection_interface_contact_info_return_from_refresh_contact_info (
context);
}
static void
my_request_contact_info (TpSvcConnectionInterfaceContactInfo *obj,
guint handle,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
TpBaseConnection *base = TP_BASE_CONNECTION (obj);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
GPtrArray *ret;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handle_is_valid (contact_repo, handle, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
ret = lookup_contact_info (self, handle);
tp_svc_connection_interface_contact_info_return_from_request_contact_info (
context, ret);
g_ptr_array_unref (ret);
}
static void
my_set_contact_info (TpSvcConnectionInterfaceContactInfo *obj,
const GPtrArray *info,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
TpBaseConnection *base = TP_BASE_CONNECTION (obj);
GPtrArray *copy;
guint i;
TpHandle self_handle;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
/* Deep copy info */
copy = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free);
for (i = 0; i < info->len; i++)
g_ptr_array_add (copy, g_value_array_copy (g_ptr_array_index (info, i)));
self_handle = tp_base_connection_get_self_handle (base);
g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (self_handle),
copy);
tp_svc_connection_interface_contact_info_return_from_set_contact_info (
context);
}
static void
init_contact_info (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceContactInfoClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_contact_info_implement_##x (\
klass, my_##x)
IMPLEMENT (refresh_contact_info);
IMPLEMENT (request_contact_info);
IMPLEMENT (set_contact_info);
#undef IMPLEMENT
}
static void
my_request_client_types (TpSvcConnectionInterfaceClientTypes *obj,
guint handle,
DBusGMethodInvocation *context)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
TpBaseConnection *base = TP_BASE_CONNECTION (obj);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GError *error = NULL;
gchar **types;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handle_is_valid (contact_repo, handle, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
types = g_hash_table_lookup(self->priv->client_types, GUINT_TO_POINTER (handle));
tp_svc_connection_interface_client_types_return_from_request_client_types (
context, (const gchar **) types);
}
static void
init_client_types (gpointer g_iface,
gpointer iface_data)
{
TpSvcConnectionInterfaceClientTypesClass *klass = g_iface;
#define IMPLEMENT(x) tp_svc_connection_interface_client_types_implement_##x (\
klass, my_##x)
/* IMPLEMENT (get_client_types); */
IMPLEMENT (request_client_types);
#undef IMPLEMENT
}
/* =============== Legacy version (no Contacts interface) ================= */
G_DEFINE_TYPE (TpTestsLegacyContactsConnection,
tp_tests_legacy_contacts_connection, TP_TESTS_TYPE_CONTACTS_CONNECTION);
enum
{
LEGACY_PROP_HAS_IMMORTAL_HANDLES = 1
};
static void
legacy_contacts_connection_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
switch (property_id)
{
case LEGACY_PROP_HAS_IMMORTAL_HANDLES:
/* Pretend we don't. */
g_value_set_boolean (value, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
tp_tests_legacy_contacts_connection_init (TpTestsLegacyContactsConnection *self)
{
}
static void
tp_tests_legacy_contacts_connection_class_init (
TpTestsLegacyContactsConnectionClass *klass)
{
/* Leave Contacts out of the interfaces we say are present, so clients
* won't use it */
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
NULL };
TpBaseConnectionClass *base_class =
(TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->get_property = legacy_contacts_connection_get_property;
base_class->interfaces_always_present = interfaces_always_present;
g_object_class_override_property (object_class,
LEGACY_PROP_HAS_IMMORTAL_HANDLES, "has-immortal-handles");
}
/* =============== No Requests and no ContactCapabilities ================= */
G_DEFINE_TYPE (TpTestsNoRequestsConnection, tp_tests_no_requests_connection,
TP_TESTS_TYPE_CONTACTS_CONNECTION);
static void
tp_tests_no_requests_connection_init (TpTestsNoRequestsConnection *self)
{
}
static void
tp_tests_no_requests_connection_class_init (
TpTestsNoRequestsConnectionClass *klass)
{
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
NULL };
TpBaseConnectionClass *base_class =
(TpBaseConnectionClass *) klass;
base_class->interfaces_always_present = interfaces_always_present;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/params-cm.c 0000664 0001750 0001750 00000014543 12470405660 017630 0 ustar jr jr /*
* params-cm.h - source for TpTestsParamConnectionManager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "params-cm.h"
#include
#include
#include
G_DEFINE_TYPE (TpTestsParamConnectionManager,
tp_tests_param_connection_manager,
TP_TYPE_BASE_CONNECTION_MANAGER)
struct _TpTestsParamConnectionManagerPrivate
{
int dummy;
};
static void
tp_tests_param_connection_manager_init (
TpTestsParamConnectionManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_PARAM_CONNECTION_MANAGER,
TpTestsParamConnectionManagerPrivate);
}
enum {
TP_TESTS_PARAM_STRING,
TP_TESTS_PARAM_INT16,
TP_TESTS_PARAM_INT32,
TP_TESTS_PARAM_UINT16,
TP_TESTS_PARAM_UINT32,
TP_TESTS_PARAM_INT64,
TP_TESTS_PARAM_UINT64,
TP_TESTS_PARAM_BOOLEAN,
TP_TESTS_PARAM_DOUBLE,
TP_TESTS_PARAM_ARRAY_STRINGS,
TP_TESTS_PARAM_ARRAY_BYTES,
TP_TESTS_PARAM_OBJECT_PATH,
TP_TESTS_PARAM_LC_STRING,
TP_TESTS_PARAM_UC_STRING,
NUM_PARAM
};
static gboolean
filter_string_ascii_case (const TpCMParamSpec *param_spec,
GValue *value,
GError **error)
{
const gchar *s = g_value_get_string (value);
guint i;
for (i = 0; s[i] != '\0'; i++)
{
int c = s[i]; /* just to avoid -Wtype-limits */
if (c < 0 || c > 127) /* char might be signed or unsigned */
{
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"%s must be ASCII", param_spec->name);
return FALSE;
}
}
if (GINT_TO_POINTER (param_spec->filter_data))
g_value_take_string (value, g_ascii_strup (s, -1));
else
g_value_take_string (value, g_ascii_strdown (s, -1));
return TRUE;
}
static TpCMParamSpec param_example_params[] = {
{ "a-string", "s", G_TYPE_STRING,
TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT, "the default string",
G_STRUCT_OFFSET (TpTestsCMParams, a_string), NULL, NULL, NULL },
{ "a-int16", "n", G_TYPE_INT,
TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT, GINT_TO_POINTER (42),
G_STRUCT_OFFSET (TpTestsCMParams, a_int16), NULL, NULL, NULL },
{ "a-int32", "i", G_TYPE_INT,
TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT, GINT_TO_POINTER (42),
G_STRUCT_OFFSET (TpTestsCMParams, a_int32), NULL, NULL, NULL },
{ "a-uint16", "q", G_TYPE_UINT, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_uint16), NULL, NULL, NULL },
{ "a-uint32", "u", G_TYPE_UINT, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_uint32), NULL, NULL, NULL },
{ "a-int64", "x", G_TYPE_INT64, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_int64), NULL, NULL, NULL },
{ "a-uint64", "t", G_TYPE_UINT64, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_uint64), NULL, NULL, NULL },
{ "a-boolean", "b", G_TYPE_BOOLEAN, TP_CONN_MGR_PARAM_FLAG_REQUIRED, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_boolean), NULL, NULL, NULL },
{ "a-double", "d", G_TYPE_DOUBLE, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_double), NULL, NULL, NULL },
{ "a-array-of-strings", "as", 0, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_array_of_strings), NULL, NULL, NULL },
{ "a-array-of-bytes", "ay", 0, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_array_of_bytes), NULL, NULL, NULL },
{ "a-object-path", "o", 0, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, a_object_path), NULL, NULL, NULL },
/* demo of a filter */
{ "lc-string", "s", G_TYPE_STRING, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, lc_string),
filter_string_ascii_case, GINT_TO_POINTER (FALSE), NULL },
{ "uc-string", "s", G_TYPE_STRING, 0, NULL,
G_STRUCT_OFFSET (TpTestsCMParams, uc_string),
filter_string_ascii_case, GINT_TO_POINTER (TRUE), NULL },
{ NULL }
};
static TpTestsCMParams *params = NULL;
static gpointer
alloc_params (void)
{
params = g_slice_new0 (TpTestsCMParams);
return params;
}
static void
free_params (gpointer p)
{
/* CM user is responsible to free params so he can check their values */
params = (TpTestsCMParams *) p;
params->would_have_been_freed = TRUE;
}
static const TpCMProtocolSpec example_protocols[] = {
{ "example", param_example_params,
alloc_params, free_params },
{ NULL, NULL }
};
static TpBaseConnection *
new_connection (TpBaseConnectionManager *self,
const gchar *proto,
TpIntSet *params_present,
gpointer parsed_params,
GError **error)
{
g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
"No connection for you");
return NULL;
}
static void
tp_tests_param_connection_manager_class_init (
TpTestsParamConnectionManagerClass *klass)
{
TpBaseConnectionManagerClass *base_class =
(TpBaseConnectionManagerClass *) klass;
g_type_class_add_private (klass,
sizeof (TpTestsParamConnectionManagerPrivate));
param_example_params[TP_TESTS_PARAM_ARRAY_STRINGS].gtype = G_TYPE_STRV;
param_example_params[TP_TESTS_PARAM_ARRAY_BYTES].gtype =
DBUS_TYPE_G_UCHAR_ARRAY;
param_example_params[TP_TESTS_PARAM_OBJECT_PATH].gtype =
DBUS_TYPE_G_OBJECT_PATH;
base_class->new_connection = new_connection;
base_class->cm_dbus_name = "params_cm";
base_class->protocol_params = example_protocols;
}
TpTestsCMParams *
tp_tests_param_connection_manager_steal_params_last_conn (void)
{
TpTestsCMParams *p = params;
params = NULL;
return p;
}
void
tp_tests_param_connection_manager_free_params (TpTestsCMParams *p)
{
g_free (p->a_string);
g_strfreev (p->a_array_of_strings);
if (p->a_array_of_bytes != NULL)
g_array_free (p->a_array_of_bytes, TRUE);
g_free (p->a_object_path);
g_slice_free (TpTestsCMParams, p);
}
telepathy-qt-0.9.6~git1/tests/lib/glib/simple-channel-dispatch-operation.c 0000664 0001750 0001750 00000022240 12470405660 024433 0 ustar jr jr /*
* simple-channel-dispatch-operation.c - a simple channel dispatch operation
* service.
*
* Copyright © 2010 Collabora Ltd.
*
* 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.
*/
#include "simple-channel-dispatch-operation.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
static void channel_dispatch_operation_iface_init (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleChannelDispatchOperation,
tp_tests_simple_channel_dispatch_operation,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_DISPATCH_OPERATION,
channel_dispatch_operation_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init)
)
/* TP_IFACE_CHANNEL_DISPATCH_OPERATION is implied */
static const char *CHANNEL_DISPATCH_OPERATION_INTERFACES[] = { NULL };
static const gchar *CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS[] = {
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
enum
{
PROP_0,
PROP_INTERFACES,
PROP_CONNECTION,
PROP_ACCOUNT,
PROP_CHANNELS,
PROP_POSSIBLE_HANDLERS,
};
struct _SimpleChannelDispatchOperationPrivate
{
gchar *conn_path;
gchar *account_path;
/* Array of TpChannel */
GPtrArray *channels;
};
static void
tp_tests_simple_channel_dispatch_operation_handle_with (
TpSvcChannelDispatchOperation *iface,
const gchar *handler,
DBusGMethodInvocation *context)
{
if (!tp_strdiff (handler, "FAIL"))
{
GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Nope" };
dbus_g_method_return_error (context, &error);
return;
}
dbus_g_method_return (context);
}
static void
tp_tests_simple_channel_dispatch_operation_claim (
TpSvcChannelDispatchOperation *iface,
DBusGMethodInvocation *context)
{
dbus_g_method_return (context);
}
static void
tp_tests_simple_channel_dispatch_operation_handle_with_time (
TpSvcChannelDispatchOperation *iface,
const gchar *handler,
gint64 user_action_timestamp,
DBusGMethodInvocation *context)
{
dbus_g_method_return (context);
}
static void
channel_dispatch_operation_iface_init (gpointer klass,
gpointer unused G_GNUC_UNUSED)
{
#define IMPLEMENT(x) tp_svc_channel_dispatch_operation_implement_##x (\
klass, tp_tests_simple_channel_dispatch_operation_##x)
IMPLEMENT(handle_with);
IMPLEMENT(claim);
IMPLEMENT(handle_with_time);
#undef IMPLEMENT
}
static void
tp_tests_simple_channel_dispatch_operation_init (TpTestsSimpleChannelDispatchOperation *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION,
TpTestsSimpleChannelDispatchOperationPrivate);
self->priv->channels = g_ptr_array_new_with_free_func (
(GDestroyNotify) g_object_unref);
}
static void
tp_tests_simple_channel_dispatch_operation_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *spec)
{
TpTestsSimpleChannelDispatchOperation *self =
TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION (object);
switch (property_id) {
case PROP_INTERFACES:
g_value_set_boxed (value, CHANNEL_DISPATCH_OPERATION_INTERFACES);
break;
case PROP_ACCOUNT:
g_value_set_boxed (value, self->priv->account_path);
break;
case PROP_CONNECTION:
g_value_set_boxed (value, self->priv->conn_path);
break;
case PROP_CHANNELS:
{
GPtrArray *arr = g_ptr_array_new ();
guint i;
for (i = 0; i < self->priv->channels->len; i++)
{
TpChannel *channel = g_ptr_array_index (self->priv->channels, i);
GValue props_value = G_VALUE_INIT;
GVariant *props_variant;
/* Yay, double conversion! But this is for tests corner case */
props_variant = tp_channel_dup_immutable_properties (channel);
dbus_g_value_parse_g_variant (props_variant, &props_value);
g_ptr_array_add (arr,
tp_value_array_build (2,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
TP_HASH_TYPE_STRING_VARIANT_MAP,
g_value_get_boxed (&props_value),
G_TYPE_INVALID));
g_variant_unref (props_variant);
g_value_unset (&props_value);
}
g_value_take_boxed (value, arr);
}
break;
case PROP_POSSIBLE_HANDLERS:
g_value_set_boxed (value, CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
break;
}
}
static void
tp_tests_simple_channel_dispatch_operation_finalize (GObject *object)
{
TpTestsSimpleChannelDispatchOperation *self =
TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION (object);
void (*finalize) (GObject *) =
G_OBJECT_CLASS (tp_tests_simple_channel_dispatch_operation_parent_class)->finalize;
g_free (self->priv->conn_path);
g_free (self->priv->account_path);
g_ptr_array_free (self->priv->channels, TRUE);
if (finalize != NULL)
finalize (object);
}
/**
* This class currently only provides the minimum for
* tp_channel_dispatch_operation_prepare to succeed. This turns out to be only a working
* Properties.GetAll().
*/
static void
tp_tests_simple_channel_dispatch_operation_class_init (TpTestsSimpleChannelDispatchOperationClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl a_props[] = {
{ "Interfaces", "interfaces", NULL },
{ "Connection", "connection", NULL },
{ "Account", "account", NULL },
{ "Channels", "channels", NULL },
{ "PossibleHandlers", "possible-handlers", NULL },
{ NULL }
};
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CHANNEL_DISPATCH_OPERATION,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
a_props
},
{ NULL },
};
g_type_class_add_private (klass, sizeof (TpTestsSimpleChannelDispatchOperationPrivate));
object_class->get_property = tp_tests_simple_channel_dispatch_operation_get_property;
object_class->finalize = tp_tests_simple_channel_dispatch_operation_finalize;
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
"In this case we only implement ChannelDispatchOperation, so none.",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
param_spec = g_param_spec_boxed ("connection", "connection path",
"Connection path",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_boxed ("account", "account path",
"Account path",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
param_spec = g_param_spec_boxed ("channels", "channel paths",
"Channel paths",
TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CHANNELS, param_spec);
param_spec = g_param_spec_boxed ("possible-handlers", "possible handlers",
"possible handles",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_POSSIBLE_HANDLERS,
param_spec);
klass->dbus_props_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsSimpleChannelDispatchOperationClass, dbus_props_class));
}
void
tp_tests_simple_channel_dispatch_operation_set_conn_path (
TpTestsSimpleChannelDispatchOperation *self,
const gchar *conn_path)
{
self->priv->conn_path = g_strdup (conn_path);
}
void
tp_tests_simple_channel_dispatch_operation_add_channel (
TpTestsSimpleChannelDispatchOperation *self,
TpChannel *chan)
{
g_ptr_array_add (self->priv->channels, g_object_ref (chan));
}
void
tp_tests_simple_channel_dispatch_operation_lost_channel (
TpTestsSimpleChannelDispatchOperation *self,
TpChannel *chan)
{
const gchar *path = tp_proxy_get_object_path (chan);
g_ptr_array_remove (self->priv->channels, chan);
tp_svc_channel_dispatch_operation_emit_channel_lost (self, path,
TP_ERROR_STR_NOT_AVAILABLE, "Badger");
if (self->priv->channels->len == 0)
{
/* We removed the last channel; fire Finished */
tp_svc_channel_dispatch_operation_emit_finished (self);
}
}
void
tp_tests_simple_channel_dispatch_operation_set_account_path (
TpTestsSimpleChannelDispatchOperation *self,
const gchar *account_path)
{
self->priv->account_path = g_strdup (account_path);
}
telepathy-qt-0.9.6~git1/tests/lib/glib/textchan-group.c 0000664 0001750 0001750 00000032151 12470405660 020713 0 ustar jr jr /*
* a stub anonymous MUC
*
* Copyright (C) 2008 Collabora Ltd.
* Copyright (C) 2008 Nokia Corporation
*
* 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.
*/
//TODO This either needs to be ported away from TpTextMixin,
//or we need to use another test CM instead of this one on the tests where it is used.
//tp-glib has not ported it because it is used in TpTextMixin tests.
#define _TP_IGNORE_DEPRECATIONS
#include "textchan-group.h"
#include
#include
#include
#include
#include
#include
#include
static void text_iface_init (gpointer iface, gpointer data);
static void channel_iface_init (gpointer iface, gpointer data);
G_DEFINE_TYPE_WITH_CODE (TpTestsTextChannelGroup,
tp_tests_text_channel_group,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TEXT, text_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
tp_group_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init))
static const char *text_channel_group_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_GROUP,
NULL
};
/* type definition stuff */
enum
{
PROP_OBJECT_PATH = 1,
PROP_CHANNEL_TYPE,
PROP_HANDLE_TYPE,
PROP_HANDLE,
PROP_TARGET_ID,
PROP_CONNECTION,
PROP_INTERFACES,
PROP_REQUESTED,
PROP_INITIATOR_HANDLE,
PROP_INITIATOR_ID,
PROP_DETAILED,
PROP_PROPERTIES,
N_PROPS
};
struct _TpTestsTextChannelGroupPrivate
{
gchar *object_path;
gboolean detailed;
gboolean properties;
gboolean closed;
gboolean disposed;
};
static gboolean
add_member (GObject *obj,
TpHandle handle,
const gchar *message,
GError **error)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (obj);
TpIntSet *add = tp_intset_new ();
tp_intset_add (add, handle);
tp_group_mixin_change_members (obj, message, add, NULL, NULL, NULL,
self->conn->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
tp_intset_destroy (add);
return TRUE;
}
static void
tp_tests_text_channel_group_init (TpTestsTextChannelGroup *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_TEXT_CHANNEL_GROUP, TpTestsTextChannelGroupPrivate);
}
static GObject *
constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
GObject *object =
G_OBJECT_CLASS (tp_tests_text_channel_group_parent_class)->constructor (type,
n_props, props);
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
(self->conn, TP_HANDLE_TYPE_CONTACT);
TpChannelGroupFlags flags = 0;
tp_dbus_daemon_register_object (
tp_base_connection_get_dbus_daemon (self->conn),
self->priv->object_path, self);
tp_text_mixin_init (object, G_STRUCT_OFFSET (TpTestsTextChannelGroup, text),
contact_repo);
tp_text_mixin_set_message_types (object,
TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE,
G_MAXUINT);
if (self->priv->detailed)
flags |= TP_CHANNEL_GROUP_FLAG_MEMBERS_CHANGED_DETAILED;
if (self->priv->properties)
flags |= TP_CHANNEL_GROUP_FLAG_PROPERTIES;
tp_group_mixin_init (object, G_STRUCT_OFFSET (TpTestsTextChannelGroup, group),
contact_repo, self->conn->self_handle);
tp_group_mixin_change_flags (object, flags, 0);
return object;
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
g_value_set_string (value, self->priv->object_path);
break;
case PROP_CHANNEL_TYPE:
g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_TEXT);
break;
case PROP_HANDLE_TYPE:
g_value_set_uint (value, TP_HANDLE_TYPE_NONE);
break;
case PROP_HANDLE:
g_value_set_uint (value, 0);
break;
case PROP_TARGET_ID:
g_value_set_static_string (value, "");
break;
case PROP_REQUESTED:
g_value_set_boolean (value, TRUE);
break;
case PROP_INITIATOR_HANDLE:
g_value_set_uint (value, self->conn->self_handle);
break;
case PROP_INITIATOR_ID:
{
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
self->conn, TP_HANDLE_TYPE_CONTACT);
g_value_set_string (value,
tp_handle_inspect (contact_repo, self->conn->self_handle));
}
break;
case PROP_INTERFACES:
g_value_set_boxed (value, text_channel_group_interfaces);
break;
case PROP_CONNECTION:
g_value_set_object (value, self->conn);
break;
case PROP_DETAILED:
g_value_set_boolean (value, self->priv->detailed);
break;
case PROP_PROPERTIES:
g_value_set_boolean (value, self->priv->properties);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
g_free (self->priv->object_path);
self->priv->object_path = g_value_dup_string (value);
break;
case PROP_HANDLE:
case PROP_HANDLE_TYPE:
case PROP_CHANNEL_TYPE:
/* these properties are writable in the interface, but not actually
* meaningfully changable on this channel, so we do nothing */
break;
case PROP_CONNECTION:
self->conn = g_value_get_object (value);
break;
case PROP_DETAILED:
self->priv->detailed = g_value_get_boolean (value);
break;
case PROP_PROPERTIES:
self->priv->properties = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
dispose (GObject *object)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
if (self->priv->disposed)
return;
self->priv->disposed = TRUE;
if (!self->priv->closed)
{
tp_svc_channel_emit_closed (self);
}
((GObjectClass *) tp_tests_text_channel_group_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
g_free (self->priv->object_path);
tp_text_mixin_finalize (object);
tp_group_mixin_finalize (object);
((GObjectClass *) tp_tests_text_channel_group_parent_class)->finalize (object);
}
static void
tp_tests_text_channel_group_class_init (TpTestsTextChannelGroupClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl channel_props[] = {
{ "TargetHandleType", "handle-type", NULL },
{ "TargetHandle", "handle", NULL },
{ "ChannelType", "channel-type", NULL },
{ "Interfaces", "interfaces", NULL },
{ "TargetID", "target-id", NULL },
{ "Requested", "requested", NULL },
{ "InitiatorHandle", "initiator-handle", NULL },
{ "InitiatorID", "initiator-id", NULL },
{ NULL }
};
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CHANNEL,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
channel_props,
},
{ NULL }
};
g_type_class_add_private (klass, sizeof (TpTestsTextChannelGroupPrivate));
object_class->constructor = constructor;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
g_object_class_override_property (object_class, PROP_OBJECT_PATH,
"object-path");
g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
"channel-type");
g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
"handle-type");
g_object_class_override_property (object_class, PROP_HANDLE, "handle");
param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
"Connection object that owns this channel",
TP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
"Additional Channel.Interface.* interfaces",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
param_spec = g_param_spec_string ("target-id", "Peer's ID",
"Always the empty string on this channel",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle",
"The contact who initiated the channel",
0, G_MAXUINT32, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE,
param_spec);
param_spec = g_param_spec_string ("initiator-id", "Initiator's ID",
"The string obtained by inspecting the initiator-handle",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_ID,
param_spec);
param_spec = g_param_spec_boolean ("requested", "Requested?",
"True if this channel was requested by the local user",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
param_spec = g_param_spec_boolean ("detailed",
"Has the Members_Changed_Detailed flag?",
"True if the Members_Changed_Detailed group flag should be set",
TRUE,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DETAILED, param_spec);
param_spec = g_param_spec_boolean ("properties",
"Has the Properties flag?",
"True if the Properties group flag should be set",
TRUE,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_PROPERTIES, param_spec);
tp_text_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsTextChannelGroupClass, text_class));
tp_group_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsTextChannelGroupClass, group_class), add_member,
NULL);
klass->dbus_properties_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsTextChannelGroupClass, dbus_properties_class));
tp_group_mixin_init_dbus_properties (object_class);
}
static void
channel_close (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (iface);
if (!self->priv->closed)
{
self->priv->closed = TRUE;
tp_svc_channel_emit_closed (self);
}
tp_svc_channel_return_from_close (context);
}
static void
channel_get_channel_type (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_channel_type (context,
TP_IFACE_CHANNEL_TYPE_TEXT);
}
static void
channel_get_handle (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0);
}
static void
channel_get_interfaces (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_interfaces (context,
text_channel_group_interfaces);
}
static void
channel_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_implement_##x (klass, channel_##x)
IMPLEMENT (close);
IMPLEMENT (get_channel_type);
IMPLEMENT (get_handle);
IMPLEMENT (get_interfaces);
#undef IMPLEMENT
}
static void
text_send (TpSvcChannelTypeText *iface,
guint type,
const gchar *text,
DBusGMethodInvocation *context)
{
/* silently swallow the message */
tp_svc_channel_type_text_return_from_send (context);
}
static void
text_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelTypeTextClass *klass = iface;
tp_text_mixin_iface_init (iface, data);
#define IMPLEMENT(x) tp_svc_channel_type_text_implement_##x (klass, text_##x)
IMPLEMENT (send);
#undef IMPLEMENT
}
telepathy-qt-0.9.6~git1/tests/lib/glib/simple-conn.h 0000664 0001750 0001750 00000005027 12470405660 020176 0 ustar jr jr /*
* simple-conn.h - header for a simple connection
*
* Copyright (C) 2007-2008 Collabora Ltd.
* Copyright (C) 2007-2008 Nokia Corporation
*
* 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.
*/
#ifndef __TP_TESTS_SIMPLE_CONN_H__
#define __TP_TESTS_SIMPLE_CONN_H__
#include
#include
G_BEGIN_DECLS
typedef struct _TpTestsSimpleConnection TpTestsSimpleConnection;
typedef struct _TpTestsSimpleConnectionClass TpTestsSimpleConnectionClass;
typedef struct _TpTestsSimpleConnectionPrivate TpTestsSimpleConnectionPrivate;
struct _TpTestsSimpleConnectionClass {
TpBaseConnectionClass parent_class;
};
struct _TpTestsSimpleConnection {
TpBaseConnection parent;
TpTestsSimpleConnectionPrivate *priv;
};
GType tp_tests_simple_connection_get_type (void);
/* TYPE MACROS */
#define TP_TESTS_TYPE_SIMPLE_CONNECTION \
(tp_tests_simple_connection_get_type ())
#define TP_TESTS_SIMPLE_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION, \
TpTestsSimpleConnection))
#define TP_TESTS_SIMPLE_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CONNECTION, \
TpTestsSimpleConnectionClass))
#define TP_TESTS_SIMPLE_IS_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION))
#define TP_TESTS_SIMPLE_IS_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CONNECTION))
#define TP_TESTS_SIMPLE_CONNECTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION, \
TpTestsSimpleConnectionClass))
TpTestsSimpleConnection * tp_tests_simple_connection_new (const gchar *account,
const gchar *protocol);
/* Cause "network events", for debugging/testing */
void tp_tests_simple_connection_inject_disconnect (
TpTestsSimpleConnection *self);
void tp_tests_simple_connection_set_identifier (TpTestsSimpleConnection *self,
const gchar *identifier);
gchar * tp_tests_simple_connection_ensure_text_chan (
TpTestsSimpleConnection *self,
const gchar *target_id,
GHashTable **props);
void tp_tests_simple_connection_set_get_self_handle_error (
TpTestsSimpleConnection *self,
GQuark domain,
gint code,
const gchar *message);
G_END_DECLS
#endif /* #ifndef __TP_TESTS_SIMPLE_CONN_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/dbus-tube-chan.h 0000664 0001750 0001750 00000012021 12470405660 020543 0 ustar jr jr /*
* dbus-tube-chan.h - Simple dbus tube channel
*
* Copyright (C) 2010 Collabora Ltd.
*
* 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.
*/
#ifndef __TP_DBUS_TUBE_CHAN_H__
#define __TP_DBUS_TUBE_CHAN_H__
#include
#include
#include
#include
G_BEGIN_DECLS
/* Base Class */
typedef struct _TpTestsDBusTubeChannel TpTestsDBusTubeChannel;
typedef struct _TpTestsDBusTubeChannelClass TpTestsDBusTubeChannelClass;
typedef struct _TpTestsDBusTubeChannelPrivate TpTestsDBusTubeChannelPrivate;
GType tp_tests_dbus_tube_channel_get_type (void);
#define TP_TESTS_TYPE_DBUS_TUBE_CHANNEL \
(tp_tests_dbus_tube_channel_get_type ())
#define TP_TESTS_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
TpTestsDBusTubeChannel))
#define TP_TESTS_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
TpTestsDBusTubeChannelClass))
#define TP_TESTS_IS_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL))
#define TP_TESTS_IS_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL))
#define TP_TESTS_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
TpTestsDBusTubeChannelClass))
struct _TpTestsDBusTubeChannelClass {
TpBaseChannelClass parent_class;
TpTextMixinClass text_class;
TpDBusPropertiesMixinClass dbus_properties_class;
};
struct _TpTestsDBusTubeChannel {
TpBaseChannel parent;
TpTextMixin text;
TpTestsDBusTubeChannelPrivate *priv;
};
/* Contact DBus Tube */
typedef struct _TpTestsContactDBusTubeChannel TpTestsContactDBusTubeChannel;
typedef struct _TpTestsContactDBusTubeChannelClass TpTestsContactDBusTubeChannelClass;
GType tp_tests_contact_dbus_tube_channel_get_type (void);
void tp_tests_dbus_tube_channel_set_close_on_accept (
TpTestsDBusTubeChannel *self,
gboolean close_on_accept);
void tp_tests_dbus_tube_channel_peer_connected_no_stream (
TpTestsDBusTubeChannel *self,
gchar *bus_name,
TpHandle handle);
void tp_tests_dbus_tube_channel_peer_disconnected (
TpTestsDBusTubeChannel *self,
TpHandle handle);
#define TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL \
(tp_tests_contact_dbus_tube_channel_get_type ())
#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
TpTestsContactDBusTubeChannel))
#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
TpTestsContactDBusTubeChannelClass))
#define TP_TESTS_IS_CONTACT_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL))
#define TP_TESTS_IS_CONTACT_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL))
#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
TpTestsContactDBusTubeChannelClass))
struct _TpTestsContactDBusTubeChannelClass {
TpTestsDBusTubeChannelClass parent_class;
};
struct _TpTestsContactDBusTubeChannel {
TpTestsDBusTubeChannel parent;
};
/* Room DBus Tube */
typedef struct _TpTestsRoomDBusTubeChannel TpTestsRoomDBusTubeChannel;
typedef struct _TpTestsRoomDBusTubeChannelClass TpTestsRoomDBusTubeChannelClass;
GType tp_tests_room_dbus_tube_channel_get_type (void);
#define TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL \
(tp_tests_room_dbus_tube_channel_get_type ())
#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
TpTestsRoomDBusTubeChannel))
#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
TpTestsRoomDBusTubeChannelClass))
#define TP_TESTS_IS_ROOM_DBUS_TUBE_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL))
#define TP_TESTS_IS_ROOM_DBUS_TUBE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL))
#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
TpTestsRoomDBusTubeChannelClass))
struct _TpTestsRoomDBusTubeChannelClass {
TpTestsDBusTubeChannelClass parent_class;
};
struct _TpTestsRoomDBusTubeChannel {
TpTestsDBusTubeChannel parent;
};
G_END_DECLS
#endif /* #ifndef __TP_DBUS_TUBE_CHAN_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/contact-list-manager.h 0000664 0001750 0001750 00000005171 12470405660 021766 0 ustar jr jr /*
* Example channel manager for contact lists
*
* Copyright © 2007-2010 Collabora Ltd.
* Copyright © 2007-2010 Nokia Corporation
*
* 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.
*/
#ifndef __TEST_CONTACT_LIST_MANAGER_H__
#define __TEST_CONTACT_LIST_MANAGER_H__
#include
G_BEGIN_DECLS
#define TEST_TYPE_CONTACT_LIST_MANAGER \
(test_contact_list_manager_get_type ())
#define TEST_CONTACT_LIST_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_CONTACT_LIST_MANAGER, \
TestContactListManager))
#define TEST_CONTACT_LIST_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_CONTACT_LIST_MANAGER, \
TestContactListManagerClass))
#define TEST_IS_CONTACT_LIST_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), TEST_TYPE_CONTACT_LIST_MANAGER))
#define TEST_IS_CONTACT_LIST_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_CONTACT_LIST_MANAGER))
#define TEST_CONTACT_LIST_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_CONTACT_LIST_MANAGER, \
TestContactListManagerClass))
typedef struct _TestContactListManager TestContactListManager;
typedef struct _TestContactListManagerClass TestContactListManagerClass;
typedef struct _TestContactListManagerPrivate TestContactListManagerPrivate;
struct _TestContactListManagerClass {
TpBaseContactListClass parent_class;
};
struct _TestContactListManager {
TpBaseContactList parent;
TestContactListManagerPrivate *priv;
};
GType test_contact_list_manager_get_type (void);
void test_contact_list_manager_add_to_group (TestContactListManager *self,
const gchar *group_name, TpHandle member);
void test_contact_list_manager_remove_from_group (TestContactListManager *self,
const gchar *group_name, TpHandle member);
void test_contact_list_manager_request_subscription (TestContactListManager *self,
guint n_members, TpHandle *members, const gchar *message);
void test_contact_list_manager_unsubscribe (TestContactListManager *self,
guint n_members, TpHandle *members);
void test_contact_list_manager_authorize_publication (TestContactListManager *self,
guint n_members, TpHandle *members);
void test_contact_list_manager_unpublish (TestContactListManager *self,
guint n_members, TpHandle *members);
void test_contact_list_manager_remove (TestContactListManager *self,
guint n_members, TpHandle *members);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/simple-manager.h 0000664 0001750 0001750 00000004400 12470405660 020645 0 ustar jr jr /*
* simple-manager.h - header for a simple connection manager
* Copyright (C) 2007-2008 Collabora Ltd.
* Copyright (C) 2007-2008 Nokia Corporation
*
* 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.
*/
#ifndef __TP_TESTS_SIMPLE_CONNECTION_MANAGER_H__
#define __TP_TESTS_SIMPLE_CONNECTION_MANAGER_H__
#include
#include
G_BEGIN_DECLS
typedef struct _TpTestsSimpleConnectionManager TpTestsSimpleConnectionManager;
typedef struct _TpTestsSimpleConnectionManagerPrivate TpTestsSimpleConnectionManagerPrivate;
typedef struct _TpTestsSimpleConnectionManagerClass TpTestsSimpleConnectionManagerClass;
typedef struct _TpTestsSimpleConnectionManagerClassPrivate
TpTestsSimpleConnectionManagerClassPrivate;
struct _TpTestsSimpleConnectionManagerClass {
TpBaseConnectionManagerClass parent_class;
TpTestsSimpleConnectionManagerClassPrivate *priv;
};
struct _TpTestsSimpleConnectionManager {
TpBaseConnectionManager parent;
TpTestsSimpleConnectionManagerPrivate *priv;
};
GType tp_tests_simple_connection_manager_get_type (void);
/* TYPE MACROS */
#define TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER \
(tp_tests_simple_connection_manager_get_type ())
#define TP_TESTS_SIMPLE_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER, \
simpleConnectionManager))
#define TP_TESTS_SIMPLE_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER, \
TpTestsSimpleConnectionManagerClass))
#define TP_TESTS_SIMPLE_IS_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER))
#define TP_TESTS_SIMPLE_IS_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER))
#define TP_TESTS_SIMPLE_CONNECTION_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CONNECTION_MANAGER, \
TpTestsSimpleConnectionManagerClass))
G_END_DECLS
#endif /* #ifndef __TP_TESTS_SIMPLE_CONNECTION_MANAGER_H__*/
telepathy-qt-0.9.6~git1/tests/lib/glib/CMakeLists.txt 0000664 0001750 0001750 00000004021 12470405660 020332 0 ustar jr jr include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${TELEPATHY_GLIB_INCLUDE_DIR}
${GLIB2_INCLUDE_DIR}
${GOBJECT_INCLUDE_DIR}
${GIO_INCLUDE_DIR}
${GIOUNIX_INCLUDE_DIR}
${DBUS_INCLUDE_DIR}
${DBUS_ARCH_INCLUDE_DIR})
if(ENABLE_TP_GLIB_TESTS)
add_subdirectory(call)
add_subdirectory(callable)
add_subdirectory(contactlist)
add_subdirectory(contactlist2)
add_subdirectory(echo)
add_subdirectory(echo2)
add_subdirectory(future)
set(tp_glib_tests_SRCS
bug16307-conn.c
bug16307-conn.h
captcha-chan.c
captcha-chan.h
contacts-conn.c
contacts-conn.h
contacts-noroster-conn.c
contacts-noroster-conn.h
contact-list-manager.h
contact-list-manager.c
contact-search-chan.c
contact-search-chan.h
debug.h
params-cm.c
params-cm.h
simple-account.c
simple-account.h
simple-account-manager.c
simple-account-manager.h
simple-channel-dispatch-operation.c
simple-channel-dispatch-operation.h
simple-client.c
simple-client.h
simple-conn.c
simple-conn.h
simple-manager.c
simple-manager.h
textchan-group.c
textchan-group.h
textchan-null.c
textchan-null.h
util.c
util.h)
if(ENABLE_TP_GLIB_GIO_TESTS)
list(APPEND tp_glib_tests_SRCS dbus-tube-chan.c dbus-tube-chan.h
stream-tube-chan.c stream-tube-chan.h)
endif(ENABLE_TP_GLIB_GIO_TESTS)
add_library(tp-glib-tests SHARED ${tp_glib_tests_SRCS})
target_link_libraries(tp-glib-tests
${TELEPATHY_GLIB_LIBRARIES}
${GLIB2_LIBRARIES}
${GOBJECT_LIBRARIES}
${GIO_LIBRARIES}
${DBUS_GLIB_LIBRARIES}
${DBUS_LIBRARIES}
example-cm-call
example-cm-callable
example-cm-contactlist
example-cm-echo
example-cm-echo2
tp-glib-tests-future-extensions)
endif(ENABLE_TP_GLIB_TESTS)
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/ 0000775 0001750 0001750 00000000000 12470405660 020206 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/connection-manager.h 0000664 0001750 0001750 00000004546 12470405660 024137 0 ustar jr jr /*
* manager.h - header for an example connection manager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER_H__
#define __EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER_H__
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleContactListConnectionManager
ExampleContactListConnectionManager;
typedef struct _ExampleContactListConnectionManagerClass
ExampleContactListConnectionManagerClass;
typedef struct _ExampleContactListConnectionManagerPrivate
ExampleContactListConnectionManagerPrivate;
struct _ExampleContactListConnectionManagerClass {
TpBaseConnectionManagerClass parent_class;
};
struct _ExampleContactListConnectionManager {
TpBaseConnectionManager parent;
ExampleContactListConnectionManagerPrivate *priv;
};
GType example_contact_list_connection_manager_get_type (void);
#define EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER \
(example_contact_list_connection_manager_get_type ())
#define EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER, \
ExampleContactListConnectionManager))
#define EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER, \
ExampleContactListConnectionManagerClass))
#define EXAMPLE_IS_CONTACT_LIST_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), \
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER))
#define EXAMPLE_IS_CONTACT_LIST_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), \
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER))
#define EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER, \
ExampleContactListConnectionManagerClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/example_contact_list.manager 0000664 0001750 0001750 00000002071 12470405660 025743 0 ustar jr jr [ConnectionManager]
Interfaces=
[Protocol example]
Interfaces=
ConnectionInterfaces=org.freedesktop.Telepathy.Connection.Interface.Requests;org.freedesktop.Telepathy.Connection.Interface.Contacts;org.freedesktop.Telepathy.Connection.Interface.Presence;org.freedesktop.Telepathy.Connection.Interface.SimplePresence;
param-account=s required register
param-simulation-delay=u
default-simulation-delay=1000
RequestableChannelClasses=contactlist;contactgroup;
VCardField=x-telepathy-example
EnglishName=Example with a contact list
Icon=face-smile
[contactlist]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.ContactList
org.freedesktop.Telepathy.Channel.TargetHandleType u=3
allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;
[contactgroup]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.ContactList
org.freedesktop.Telepathy.Channel.TargetHandleType u=4
allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/contact-list.h 0000664 0001750 0001750 00000005031 12470405660 022762 0 ustar jr jr /*
* Example channel manager for contact lists
*
* Copyright © 2007-2010 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_CONTACT_LIST_H__
#define __EXAMPLE_CONTACT_LIST_H__
#include
#include
#include
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleContactList ExampleContactList;
typedef struct _ExampleContactListClass ExampleContactListClass;
typedef struct _ExampleContactListPrivate ExampleContactListPrivate;
struct _ExampleContactListClass {
TpBaseContactListClass parent_class;
};
struct _ExampleContactList {
TpBaseContactList parent;
ExampleContactListPrivate *priv;
};
GType example_contact_list_get_type (void);
#define EXAMPLE_TYPE_CONTACT_LIST \
(example_contact_list_get_type ())
#define EXAMPLE_CONTACT_LIST(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_CONTACT_LIST, \
ExampleContactList))
#define EXAMPLE_CONTACT_LIST_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_CONTACT_LIST, \
ExampleContactListClass))
#define EXAMPLE_IS_CONTACT_LIST(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_CONTACT_LIST))
#define EXAMPLE_IS_CONTACT_LIST_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_CONTACT_LIST))
#define EXAMPLE_CONTACT_LIST_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CONTACT_LIST, \
ExampleContactListClass))
/* this enum must be kept in sync with the array _statuses in
* contact-list.c */
typedef enum {
EXAMPLE_CONTACT_LIST_PRESENCE_OFFLINE = 0,
EXAMPLE_CONTACT_LIST_PRESENCE_UNKNOWN,
EXAMPLE_CONTACT_LIST_PRESENCE_ERROR,
EXAMPLE_CONTACT_LIST_PRESENCE_AWAY,
EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE
} ExampleContactListPresence;
const TpPresenceStatusSpec *example_contact_list_presence_statuses (
void);
ExampleContactListPresence example_contact_list_get_presence (
ExampleContactList *self, TpHandle contact);
const gchar *example_contact_list_get_alias (
ExampleContactList *self, TpHandle contact);
void example_contact_list_set_alias (
ExampleContactList *self, TpHandle contact, const gchar *alias);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/conn.h 0000664 0001750 0001750 00000004634 12470405660 021323 0 ustar jr jr /*
* conn.h - header for an example connection
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_CONTACT_LIST_CONN_H__
#define __EXAMPLE_CONTACT_LIST_CONN_H__
#include
#include
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleContactListConnection ExampleContactListConnection;
typedef struct _ExampleContactListConnectionClass
ExampleContactListConnectionClass;
typedef struct _ExampleContactListConnectionPrivate
ExampleContactListConnectionPrivate;
struct _ExampleContactListConnectionClass {
TpBaseConnectionClass parent_class;
TpPresenceMixinClass presence_mixin;
TpContactsMixinClass contacts_mixin;
};
struct _ExampleContactListConnection {
TpBaseConnection parent;
TpPresenceMixin presence_mixin;
TpContactsMixin contacts_mixin;
ExampleContactListConnectionPrivate *priv;
};
GType example_contact_list_connection_get_type (void);
#define EXAMPLE_TYPE_CONTACT_LIST_CONNECTION \
(example_contact_list_connection_get_type ())
#define EXAMPLE_CONTACT_LIST_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_CONTACT_LIST_CONNECTION, \
ExampleContactListConnection))
#define EXAMPLE_CONTACT_LIST_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_CONTACT_LIST_CONNECTION, \
ExampleContactListConnectionClass))
#define EXAMPLE_IS_CONTACT_LIST_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_CONTACT_LIST_CONNECTION))
#define EXAMPLE_IS_CONTACT_LIST_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_CONTACT_LIST_CONNECTION))
#define EXAMPLE_CONTACT_LIST_CONNECTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CONTACT_LIST_CONNECTION, \
ExampleContactListConnectionClass))
gchar *example_contact_list_normalize_contact (TpHandleRepoIface *repo,
const gchar *id, gpointer context, GError **error);
const gchar * const * example_contact_list_connection_get_possible_interfaces (
void);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/CMakeLists.txt 0000664 0001750 0001750 00000000637 12470405660 022754 0 ustar jr jr if(ENABLE_TP_GLIB_TESTS)
set(example_cm_contactlist2_SRCS
conn.c
conn.h
connection-manager.c
connection-manager.h
contact-list.c
contact-list.h
protocol.c
protocol.h)
add_library(example-cm-contactlist2 STATIC ${example_cm_contactlist2_SRCS})
target_link_libraries(example-cm-contactlist2 ${TPGLIB_LIBRARIES})
endif(ENABLE_TP_GLIB_TESTS)
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/contact-list.c 0000664 0001750 0001750 00000150554 12470405660 022770 0 ustar jr jr /*
* Example implementation of TpBaseContactList.
*
* Copyright © 2007-2010 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#include "contact-list.h"
#include
#include
#include
#include
/* this array must be kept in sync with the enum
* ExampleContactListPresence in contact-list.h */
static const TpPresenceStatusSpec _statuses[] = {
{ "offline", TP_CONNECTION_PRESENCE_TYPE_OFFLINE, FALSE, NULL },
{ "unknown", TP_CONNECTION_PRESENCE_TYPE_UNKNOWN, FALSE, NULL },
{ "error", TP_CONNECTION_PRESENCE_TYPE_ERROR, FALSE, NULL },
{ "away", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE, NULL },
{ "available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE, NULL },
{ NULL }
};
const TpPresenceStatusSpec *
example_contact_list_presence_statuses (void)
{
return _statuses;
}
typedef struct {
gchar *alias;
guint subscribe:1;
guint publish:1;
guint pre_approved:1;
guint subscribe_requested:1;
guint subscribe_rejected:1;
/* string borrowed from priv->all_tags => the same pointer */
GHashTable *tags;
} ExampleContactDetails;
static ExampleContactDetails *
example_contact_details_new (void)
{
return g_slice_new0 (ExampleContactDetails);
}
static void
example_contact_details_destroy (gpointer p)
{
ExampleContactDetails *d = p;
tp_clear_pointer (&d->tags, g_hash_table_unref);
g_free (d->alias);
g_slice_free (ExampleContactDetails, d);
}
static void mutable_contact_list_iface_init (TpMutableContactListInterface *);
static void blockable_contact_list_iface_init (
TpBlockableContactListInterface *);
static void contact_group_list_iface_init (TpContactGroupListInterface *);
static void mutable_contact_group_list_iface_init (
TpMutableContactGroupListInterface *);
G_DEFINE_TYPE_WITH_CODE (ExampleContactList,
example_contact_list,
TP_TYPE_BASE_CONTACT_LIST,
G_IMPLEMENT_INTERFACE (TP_TYPE_BLOCKABLE_CONTACT_LIST,
blockable_contact_list_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_CONTACT_GROUP_LIST,
contact_group_list_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_MUTABLE_CONTACT_GROUP_LIST,
mutable_contact_group_list_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_MUTABLE_CONTACT_LIST,
mutable_contact_list_iface_init))
enum
{
ALIAS_UPDATED,
PRESENCE_UPDATED,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
enum
{
PROP_SIMULATION_DELAY = 1,
N_PROPS
};
struct _ExampleContactListPrivate
{
TpBaseConnection *conn;
guint simulation_delay;
TpHandleRepoIface *contact_repo;
/* g_strdup (group name) => the same pointer */
GHashTable *all_tags;
/* All contacts on our (fake) protocol-level contact list,
* plus all contacts in publish_requests or cancelled_publish_requests */
TpHandleSet *contacts;
/* All contacts on our (fake) protocol-level contact list
* GUINT_TO_POINTER (handle borrowed from contacts)
* => ExampleContactDetails */
GHashTable *contact_details;
/* Contacts with an outstanding request for presence publication
* (may or may not be in contact_details)
* handle borrowed from contacts => g_strdup (message) */
GHashTable *publish_requests;
/* Contacts who have requested presence but then cancelled their request
* (may or may not be in contact_details) */
TpHandleSet *cancelled_publish_requests;
TpHandleSet *blocked_contacts;
gulong status_changed_id;
};
static void
example_contact_list_init (ExampleContactList *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CONTACT_LIST, ExampleContactListPrivate);
self->priv->contact_details = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, example_contact_details_destroy);
self->priv->publish_requests = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, g_free);
self->priv->all_tags = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
/* initialized properly in constructed() */
self->priv->contact_repo = NULL;
self->priv->contacts = NULL;
self->priv->blocked_contacts = NULL;
self->priv->cancelled_publish_requests = NULL;
}
static void
example_contact_list_close_all (ExampleContactList *self)
{
tp_clear_pointer (&self->priv->contacts, tp_handle_set_destroy);
tp_clear_pointer (&self->priv->blocked_contacts, tp_handle_set_destroy);
tp_clear_pointer (&self->priv->cancelled_publish_requests,
tp_handle_set_destroy);
tp_clear_pointer (&self->priv->publish_requests, g_hash_table_unref);
tp_clear_pointer (&self->priv->contact_details, g_hash_table_unref);
/* this must come after freeing contact_details, because the strings are
* borrowed */
tp_clear_pointer (&self->priv->all_tags, g_hash_table_unref);
if (self->priv->status_changed_id != 0)
{
g_signal_handler_disconnect (self->priv->conn,
self->priv->status_changed_id);
self->priv->status_changed_id = 0;
}
}
static void
dispose (GObject *object)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (object);
example_contact_list_close_all (self);
((GObjectClass *) example_contact_list_parent_class)->dispose (
object);
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (object);
switch (property_id)
{
case PROP_SIMULATION_DELAY:
g_value_set_uint (value, self->priv->simulation_delay);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (object);
switch (property_id)
{
case PROP_SIMULATION_DELAY:
self->priv->simulation_delay = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static ExampleContactDetails *
lookup_contact (ExampleContactList *self,
TpHandle contact)
{
return g_hash_table_lookup (self->priv->contact_details,
GUINT_TO_POINTER (contact));
}
static ExampleContactDetails *
ensure_contact (ExampleContactList *self,
TpHandle contact,
gboolean *created)
{
ExampleContactDetails *ret = lookup_contact (self, contact);
if (ret == NULL)
{
tp_handle_set_add (self->priv->contacts, contact);
ret = example_contact_details_new ();
ret->alias = g_strdup (tp_handle_inspect (self->priv->contact_repo,
contact));
g_hash_table_insert (self->priv->contact_details,
GUINT_TO_POINTER (contact), ret);
/* if we already had a publish request from them, then adding them to
* the protocol-level contact list doesn't alter the Telepathy contact
* list */
if (created != NULL)
{
*created = (g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (contact)) == NULL);
}
}
else if (created != NULL)
{
*created = FALSE;
}
return ret;
}
static gchar *
ensure_tag (ExampleContactList *self,
const gchar *s,
gboolean emit_signal)
{
gchar *r = g_hash_table_lookup (self->priv->all_tags, s);
if (r == NULL)
{
g_message ("creating group %s", s);
r = g_strdup (s);
g_hash_table_insert (self->priv->all_tags, r, r);
if (emit_signal)
tp_base_contact_list_groups_created ((TpBaseContactList *) self,
&s, 1);
}
return r;
}
static void
example_contact_list_set_contact_groups_async (TpBaseContactList *contact_list,
TpHandle contact,
const gchar * const *names,
gsize n,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
gboolean created;
gsize i;
ExampleContactDetails *d;
GPtrArray *old_names, *new_names;
GHashTableIter iter;
gpointer k;
for (i = 0; i < n; i++)
ensure_tag (self, names[i], FALSE);
tp_base_contact_list_groups_created (contact_list, names, n);
d = ensure_contact (self, contact, &created);
if (created)
tp_base_contact_list_one_contact_changed (contact_list, contact);
if (d->tags == NULL)
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
old_names = g_ptr_array_sized_new (g_hash_table_size (d->tags));
new_names = g_ptr_array_sized_new (n);
for (i = 0; i < n; i++)
{
if (g_hash_table_lookup (d->tags, names[i]) == NULL)
{
gchar *tag = g_hash_table_lookup (self->priv->all_tags, names[i]);
g_assert (tag != NULL); /* already ensured to exist, above */
g_hash_table_insert (d->tags, tag, tag);
g_ptr_array_add (new_names, tag);
}
}
g_hash_table_iter_init (&iter, d->tags);
while (g_hash_table_iter_next (&iter, &k, NULL))
{
for (i = 0; i < n; i++)
{
if (!tp_strdiff (names[i], k))
goto next_hash_element;
}
/* not found in @names, so remove it */
g_ptr_array_add (old_names, k);
g_hash_table_iter_remove (&iter);
next_hash_element:
continue;
}
tp_base_contact_list_one_contact_groups_changed (contact_list, contact,
(const gchar * const *) new_names->pdata, new_names->len,
(const gchar * const *) old_names->pdata, old_names->len);
g_ptr_array_unref (old_names);
g_ptr_array_unref (new_names);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_set_contact_groups_async);
}
static gboolean
receive_contact_lists (gpointer p)
{
TpBaseContactList *contact_list = p;
ExampleContactList *self = p;
TpHandle handle;
gchar *cambridge, *montreal, *francophones;
ExampleContactDetails *d;
GHashTableIter iter;
gpointer handle_p;
if (self->priv->all_tags == NULL)
{
/* connection already disconnected, so don't process the
* "data from the server" */
return FALSE;
}
/* In a real CM we'd have received a contact list from the server at this
* point. But this isn't a real CM, so we have to make one up... */
g_message ("Receiving roster from server");
cambridge = ensure_tag (self, "Cambridge", FALSE);
montreal = ensure_tag (self, "Montreal", FALSE);
francophones = ensure_tag (self, "Francophones", FALSE);
/* Add various people who are already subscribing and publishing */
handle = tp_handle_ensure (self->priv->contact_repo, "sjoerd@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Sjoerd");
d->subscribe = TRUE;
d->publish = TRUE;
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (d->tags, cambridge, cambridge);
handle = tp_handle_ensure (self->priv->contact_repo, "guillaume@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Guillaume");
d->subscribe = TRUE;
d->publish = TRUE;
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (d->tags, cambridge, cambridge);
g_hash_table_insert (d->tags, francophones, francophones);
handle = tp_handle_ensure (self->priv->contact_repo, "olivier@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Olivier");
d->subscribe = TRUE;
d->publish = TRUE;
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (d->tags, montreal, montreal);
g_hash_table_insert (d->tags, francophones, francophones);
handle = tp_handle_ensure (self->priv->contact_repo, "travis@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Travis");
d->subscribe = TRUE;
d->publish = TRUE;
/* Add a couple of people whose presence we've requested. They are
* remote-pending in subscribe */
handle = tp_handle_ensure (self->priv->contact_repo, "geraldine@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Géraldine");
d->subscribe_requested = TRUE;
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (d->tags, cambridge, cambridge);
g_hash_table_insert (d->tags, francophones, francophones);
handle = tp_handle_ensure (self->priv->contact_repo, "helen@example.com",
NULL, NULL);
d = ensure_contact (self, handle, NULL);
g_free (d->alias);
d->alias = g_strdup ("Helen");
d->subscribe_requested = TRUE;
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (d->tags, cambridge, cambridge);
/* Receive a couple of authorization requests too. These people are
* local-pending in publish; they're not actually on our protocol-level
* contact list */
handle = tp_handle_ensure (self->priv->contact_repo, "wim@example.com",
NULL, NULL);
tp_handle_set_add (self->priv->contacts, handle);
g_hash_table_insert (self->priv->publish_requests,
GUINT_TO_POINTER (handle), g_strdup ("I'm more metal than you!"));
handle = tp_handle_ensure (self->priv->contact_repo, "christian@example.com",
NULL, NULL);
tp_handle_set_add (self->priv->contacts, handle);
g_hash_table_insert (self->priv->publish_requests,
GUINT_TO_POINTER (handle),
g_strdup ("I have some fermented herring for you"));
/* Add a couple of blocked contacts. */
handle = tp_handle_ensure (self->priv->contact_repo, "bill@example.com",
NULL, NULL);
tp_handle_set_add (self->priv->blocked_contacts, handle);
handle = tp_handle_ensure (self->priv->contact_repo, "steve@example.com",
NULL, NULL);
tp_handle_set_add (self->priv->blocked_contacts, handle);
g_hash_table_iter_init (&iter, self->priv->contact_details);
/* emit initial aliases, presences */
while (g_hash_table_iter_next (&iter, &handle_p, NULL))
{
handle = GPOINTER_TO_UINT (handle_p);
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
}
/* ... and off we go */
tp_base_contact_list_set_list_received (contact_list);
return FALSE;
}
static void
status_changed_cb (TpBaseConnection *conn,
guint status,
guint reason,
ExampleContactList *self)
{
switch (status)
{
case TP_CONNECTION_STATUS_CONNECTED:
{
/* Do network I/O to get the contact list. This connection manager
* doesn't really have a server, so simulate a small network delay
* then invent a contact list */
tp_base_contact_list_set_list_pending ((TpBaseContactList *) self);
g_timeout_add_full (G_PRIORITY_DEFAULT,
2 * self->priv->simulation_delay, receive_contact_lists,
g_object_ref (self), g_object_unref);
}
break;
case TP_CONNECTION_STATUS_DISCONNECTED:
{
example_contact_list_close_all (self);
tp_clear_object (&self->priv->conn);
}
break;
}
}
static void
constructed (GObject *object)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (object);
void (*chain_up) (GObject *) =
((GObjectClass *) example_contact_list_parent_class)->constructed;
if (chain_up != NULL)
{
chain_up (object);
}
g_object_get (self,
"connection", &self->priv->conn,
NULL);
g_assert (self->priv->conn != NULL);
self->priv->contact_repo = tp_base_connection_get_handles (self->priv->conn,
TP_HANDLE_TYPE_CONTACT);
self->priv->contacts = tp_handle_set_new (self->priv->contact_repo);
self->priv->blocked_contacts = tp_handle_set_new (self->priv->contact_repo);
self->priv->cancelled_publish_requests = tp_handle_set_new (
self->priv->contact_repo);
self->priv->status_changed_id = g_signal_connect (self->priv->conn,
"status-changed", (GCallback) status_changed_cb, self);
}
static void
send_updated_roster (ExampleContactList *self,
TpHandle contact)
{
ExampleContactDetails *d = g_hash_table_lookup (self->priv->contact_details,
GUINT_TO_POINTER (contact));
const gchar *request = g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (contact));
const gchar *identifier = tp_handle_inspect (self->priv->contact_repo,
contact);
/* In a real connection manager, we'd transmit these new details to the
* server, rather than just printing messages. */
if (d == NULL)
{
g_message ("Deleting contact %s from server", identifier);
}
else
{
g_message ("Transmitting new state of contact %s to server", identifier);
g_message ("\talias = %s", d->alias);
g_message ("\tcan see our presence = %s",
d->publish ? "yes" :
(request != NULL ? "no, but has requested it" : "no"));
g_message ("\tsends us presence = %s",
d->subscribe ? "yes" :
(d->subscribe_requested ? "no, but we have requested it" :
(d->subscribe_rejected ? "no, request refused" : "no")));
if (d->tags == NULL || g_hash_table_size (d->tags) == 0)
{
g_message ("\tnot in any groups");
}
else
{
GHashTableIter iter;
gpointer k;
g_hash_table_iter_init (&iter, d->tags);
while (g_hash_table_iter_next (&iter, &k, NULL))
{
g_message ("\tin group: %s", (gchar *) k);
}
}
}
}
static void
example_contact_list_set_group_members_async (TpBaseContactList *contact_list,
const gchar *group,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *new_contacts = tp_handle_set_new (self->priv->contact_repo);
TpHandleSet *added = tp_handle_set_new (self->priv->contact_repo);
TpHandleSet *removed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
gchar *tag = ensure_tag (self, group, TRUE);
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
gboolean created = FALSE, updated = FALSE;
ExampleContactDetails *d = ensure_contact (self, member, &created);
if (created)
tp_handle_set_add (new_contacts, member);
if (d->tags == NULL)
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
if (g_hash_table_lookup (d->tags, tag) == NULL)
{
g_hash_table_insert (d->tags, tag, tag);
updated = TRUE;
}
if (created || updated)
{
send_updated_roster (self, member);
tp_handle_set_add (added, member);
}
}
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (self->priv->contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d;
if (tp_handle_set_is_member (contacts, member))
continue;
d = lookup_contact (self, member);
if (d != NULL && d->tags != NULL && g_hash_table_remove (d->tags, group))
tp_handle_set_add (removed, member);
}
if (!tp_handle_set_is_empty (new_contacts))
tp_base_contact_list_contacts_changed (contact_list, new_contacts, NULL);
if (!tp_handle_set_is_empty (added))
tp_base_contact_list_groups_changed (contact_list, added, &group, 1,
NULL, 0);
if (!tp_handle_set_is_empty (removed))
tp_base_contact_list_groups_changed (contact_list, removed, NULL, 0,
&group, 1);
tp_handle_set_destroy (added);
tp_handle_set_destroy (removed);
tp_handle_set_destroy (new_contacts);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_set_group_members_async);
}
static void
example_contact_list_add_to_group_async (TpBaseContactList *contact_list,
const gchar *group,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *new_contacts = tp_handle_set_new (self->priv->contact_repo);
TpHandleSet *new_to_group = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
gchar *tag = ensure_tag (self, group, TRUE);
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
gboolean created = FALSE, updated = FALSE;
ExampleContactDetails *d = ensure_contact (self, member, &created);
if (created)
tp_handle_set_add (new_contacts, member);
if (d->tags == NULL)
d->tags = g_hash_table_new (g_str_hash, g_str_equal);
if (g_hash_table_lookup (d->tags, tag) == NULL)
{
g_hash_table_insert (d->tags, tag, tag);
updated = TRUE;
}
if (created || updated)
{
send_updated_roster (self, member);
tp_handle_set_add (new_to_group, member);
}
}
if (!tp_handle_set_is_empty (new_contacts))
tp_base_contact_list_contacts_changed (contact_list, new_contacts, NULL);
if (!tp_handle_set_is_empty (new_to_group))
tp_base_contact_list_groups_changed (contact_list, new_to_group, &group, 1,
NULL, 0);
tp_handle_set_destroy (new_to_group);
tp_handle_set_destroy (new_contacts);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_add_to_group_async);
}
static void
example_contact_list_remove_from_group_async (TpBaseContactList *contact_list,
const gchar *group,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = lookup_contact (self, member);
/* If not on the roster or not in any groups, we have nothing to do */
if (d != NULL && d->tags != NULL && g_hash_table_remove (d->tags, group))
{
send_updated_roster (self, member);
tp_handle_set_add (changed, member);
}
}
if (!tp_handle_set_is_empty (changed))
tp_base_contact_list_groups_changed (contact_list, changed, NULL, 0,
&group, 1);
tp_handle_set_destroy (changed);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_remove_from_group_async);
}
typedef struct {
ExampleContactList *self;
TpHandle contact;
} SelfAndContact;
static SelfAndContact *
self_and_contact_new (ExampleContactList *self,
TpHandle contact)
{
SelfAndContact *ret = g_slice_new0 (SelfAndContact);
ret->self = g_object_ref (self);
ret->contact = contact;
return ret;
}
static void
self_and_contact_destroy (gpointer p)
{
SelfAndContact *s = p;
g_object_unref (s->self);
g_slice_free (SelfAndContact, s);
}
static void
receive_auth_request (ExampleContactList *self,
TpHandle contact)
{
ExampleContactDetails *d;
/* if shutting down, do nothing */
if (self->priv->conn == NULL)
return;
/* A remote contact has asked to see our presence.
*
* In a real connection manager this would be the result of incoming
* data from the server. */
g_message ("From server: %s has sent us a publish request",
tp_handle_inspect (self->priv->contact_repo, contact));
d = lookup_contact (self, contact);
if (d != NULL && d->publish)
return;
if (d != NULL && d->pre_approved)
{
/* the user already said yes, no need to signal anything */
g_message ("... this publish request was already approved");
d->pre_approved = FALSE;
d->publish = TRUE;
g_hash_table_remove (self->priv->publish_requests,
GUINT_TO_POINTER (contact));
tp_handle_set_remove (self->priv->cancelled_publish_requests, contact);
send_updated_roster (self, contact);
}
else
{
tp_handle_set_add (self->priv->contacts, contact);
g_hash_table_insert (self->priv->publish_requests,
GUINT_TO_POINTER (contact),
g_strdup ("May I see your presence, please?"));
}
tp_base_contact_list_one_contact_changed ((TpBaseContactList *) self,
contact);
/* If the contact has a name ending with "@cancel.something", they
* immediately take it back; this is mainly for the regression test. */
if (strstr (tp_handle_inspect (self->priv->contact_repo, contact),
"@cancel.") != NULL)
{
g_message ("From server: %s has cancelled their publish request",
tp_handle_inspect (self->priv->contact_repo, contact));
d->publish = FALSE;
d->pre_approved = FALSE;
g_hash_table_remove (self->priv->publish_requests,
GUINT_TO_POINTER (contact));
tp_handle_set_add (self->priv->cancelled_publish_requests, contact);
tp_base_contact_list_one_contact_changed ((TpBaseContactList *) self,
contact);
}
}
static gboolean
receive_authorized (gpointer p)
{
SelfAndContact *s = p;
ExampleContactDetails *d;
/* if shutting down, do nothing */
if (s->self->priv->conn == NULL)
return FALSE;
/* A remote contact has accepted our request to see their presence.
*
* In a real connection manager this would be the result of incoming
* data from the server. */
g_message ("From server: %s has accepted our subscribe request",
tp_handle_inspect (s->self->priv->contact_repo, s->contact));
d = ensure_contact (s->self, s->contact, NULL);
/* if we were already subscribed to them, then nothing really happened */
if (d->subscribe)
return FALSE;
/* DITTO, if our subscription request was cancelled in the meantime */
if (!d->subscribe_requested)
return FALSE;
d->subscribe_requested = FALSE;
d->subscribe_rejected = FALSE;
d->subscribe = TRUE;
tp_base_contact_list_one_contact_changed ((TpBaseContactList *) s->self,
s->contact);
/* their presence changes to something other than UNKNOWN */
g_signal_emit (s->self, signals[PRESENCE_UPDATED], 0, s->contact);
/* if we're not publishing to them, also pretend they have asked us to
* do so */
if (!d->publish)
{
receive_auth_request (s->self, s->contact);
}
return FALSE;
}
static gboolean
receive_unauthorized (gpointer p)
{
SelfAndContact *s = p;
ExampleContactDetails *d;
/* if shutting down, do nothing */
if (s->self->priv->conn == NULL)
return FALSE;
/* A remote contact has rejected our request to see their presence.
*
* In a real connection manager this would be the result of incoming
* data from the server. */
g_message ("From server: %s has rejected our subscribe request",
tp_handle_inspect (s->self->priv->contact_repo, s->contact));
d = ensure_contact (s->self, s->contact, NULL);
if (!d->subscribe && !d->subscribe_requested)
return FALSE;
d->subscribe_requested = FALSE;
d->subscribe_rejected = TRUE;
d->subscribe = FALSE;
tp_base_contact_list_one_contact_changed ((TpBaseContactList *) s->self,
s->contact);
/* their presence changes to UNKNOWN */
g_signal_emit (s->self, signals[PRESENCE_UPDATED], 0, s->contact);
return FALSE;
}
static gboolean
auth_request_cb (gpointer p)
{
SelfAndContact *s = p;
receive_auth_request (s->self, s->contact);
return FALSE;
}
ExampleContactListPresence
example_contact_list_get_presence (ExampleContactList *self,
TpHandle contact)
{
ExampleContactDetails *d = lookup_contact (self, contact);
const gchar *id;
if (d == NULL || !d->subscribe)
{
/* we don't know the presence of people not on the subscribe list,
* by definition */
return EXAMPLE_CONTACT_LIST_PRESENCE_UNKNOWN;
}
id = tp_handle_inspect (self->priv->contact_repo, contact);
/* In this example CM, we fake contacts' presence based on their name:
* contacts in the first half of the alphabet are available, the rest
* (including non-alphabetic and non-ASCII initial letters) are away. */
if ((id[0] >= 'A' && id[0] <= 'M') || (id[0] >= 'a' && id[0] <= 'm'))
{
return EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE;
}
return EXAMPLE_CONTACT_LIST_PRESENCE_AWAY;
}
const gchar *
example_contact_list_get_alias (ExampleContactList *self,
TpHandle contact)
{
ExampleContactDetails *d = lookup_contact (self, contact);
if (d == NULL)
{
/* we don't have a user-defined alias for people not on the roster */
return tp_handle_inspect (self->priv->contact_repo, contact);
}
return d->alias;
}
void
example_contact_list_set_alias (ExampleContactList *self,
TpHandle contact,
const gchar *alias)
{
gboolean created;
ExampleContactDetails *d;
gchar *old;
/* if shutting down, do nothing */
if (self->priv->conn == NULL)
return;
d = ensure_contact (self, contact, &created);
if (created)
{
tp_base_contact_list_one_contact_changed (
(TpBaseContactList *) self, contact);
}
/* FIXME: if stored list hasn't been retrieved yet, queue the change for
* later */
old = d->alias;
d->alias = g_strdup (alias);
if (created || tp_strdiff (old, alias))
send_updated_roster (self, contact);
g_free (old);
}
static TpHandleSet *
example_contact_list_dup_contacts (TpBaseContactList *contact_list)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
return tp_handle_set_copy (self->priv->contacts);
}
static TpHandleSet *
example_contact_list_dup_group_members (TpBaseContactList *contact_list,
const gchar *group)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpIntsetFastIter iter;
TpHandle member;
TpHandleSet *members = tp_handle_set_new (self->priv->contact_repo);
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (self->priv->contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = lookup_contact (self, member);
if (d != NULL && d->tags != NULL &&
g_hash_table_lookup_extended (d->tags, group, NULL, NULL))
tp_handle_set_add (members, member);
}
return members;
}
static const ExampleContactDetails no_details = {
NULL,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
NULL
};
static inline TpSubscriptionState
compose_presence (gboolean full,
gboolean ask,
gboolean removed_remotely)
{
if (full)
return TP_SUBSCRIPTION_STATE_YES;
else if (ask)
return TP_SUBSCRIPTION_STATE_ASK;
else if (removed_remotely)
return TP_SUBSCRIPTION_STATE_REMOVED_REMOTELY;
else
return TP_SUBSCRIPTION_STATE_NO;
}
static void
example_contact_list_dup_states (TpBaseContactList *contact_list,
TpHandle contact,
TpSubscriptionState *subscribe,
TpSubscriptionState *publish,
gchar **publish_request)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
const ExampleContactDetails *details = lookup_contact (self, contact);
const gchar *request = g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (contact));
if (details == NULL)
details = &no_details;
if (subscribe != NULL)
*subscribe = compose_presence (details->subscribe,
details->subscribe_requested, details->subscribe_rejected);
if (publish != NULL)
*publish = compose_presence (details->publish, (request != NULL),
tp_handle_set_is_member (self->priv->cancelled_publish_requests,
contact));
if (publish_request != NULL)
*publish_request = g_strdup (request);
}
static void
example_contact_list_request_subscription_async (
TpBaseContactList *contact_list,
TpHandleSet *contacts,
const gchar *message,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
gboolean created;
ExampleContactDetails *d = ensure_contact (self, member, &created);
gchar *message_lc;
/* if they already authorized us, it's a no-op */
if (d->subscribe)
continue;
/* In a real connection manager we'd start a network request here */
g_message ("Transmitting authorization request to %s: %s",
tp_handle_inspect (self->priv->contact_repo, member),
message);
tp_handle_set_add (changed, member);
d->subscribe_rejected = FALSE;
d->subscribe_requested = TRUE;
send_updated_roster (self, member);
/* Pretend that after a delay, the contact notices the request
* and allows or rejects it. In this example connection manager,
* empty requests are allowed, as are requests that contain "please"
* case-insensitively. All other requests are denied. */
message_lc = g_ascii_strdown (message, -1);
if (message[0] == '\0' || strstr (message_lc, "please") != NULL)
{
g_timeout_add_full (G_PRIORITY_LOW,
self->priv->simulation_delay, receive_authorized,
self_and_contact_new (self, member),
self_and_contact_destroy);
}
else
{
g_timeout_add_full (G_PRIORITY_LOW,
self->priv->simulation_delay,
receive_unauthorized,
self_and_contact_new (self, member),
self_and_contact_destroy);
}
g_free (message_lc);
}
tp_base_contact_list_contacts_changed (contact_list, changed, NULL);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_request_subscription_async);
}
static void
example_contact_list_authorize_publication_async (
TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = ensure_contact (self, member, NULL);
const gchar *request = g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (member));
if (tp_handle_set_remove (self->priv->cancelled_publish_requests,
member))
tp_handle_set_add (changed, member);
/* We would like member to see our presence. In this simulated protocol,
* this is meaningless, unless they have asked for it; but we can still
* remember the pre-authorization in case they ask later. */
if (request == NULL)
{
d->pre_approved = TRUE;
}
else if (!d->publish)
{
d->publish = TRUE;
g_hash_table_remove (self->priv->publish_requests,
GUINT_TO_POINTER (member));
send_updated_roster (self, member);
tp_handle_set_add (changed, member);
}
}
tp_base_contact_list_contacts_changed (contact_list, changed, NULL);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_authorize_publication_async);
}
static void
example_contact_list_store_contacts_async (
TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
/* We would like member to be on the roster, but nothing more. */
if (lookup_contact (self, member) == NULL)
{
gboolean created;
ensure_contact (self, member, &created);
send_updated_roster (self, member);
/* If we'd had a publish request from this member, then adding them
* to the protocol-level contact list doesn't actually cause a
* state change visible on Telepathy. */
if (created)
tp_handle_set_add (changed, member);
}
}
tp_base_contact_list_contacts_changed (contact_list, changed, NULL);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_store_contacts_async);
}
static void
example_contact_list_remove_contacts_async (TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *removed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
/* we would like to remove member from the roster altogether */
if (lookup_contact (self, member) != NULL
|| g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (member)) != NULL
|| tp_handle_set_is_member (self->priv->cancelled_publish_requests,
member))
{
tp_handle_set_add (removed, member);
g_hash_table_remove (self->priv->contact_details,
GUINT_TO_POINTER (member));
g_hash_table_remove (self->priv->publish_requests,
GUINT_TO_POINTER (member));
tp_handle_set_remove (self->priv->contacts, member);
tp_handle_set_remove (self->priv->cancelled_publish_requests,
member);
send_updated_roster (self, member);
/* since they're no longer on the subscribe list, we can't
* see their presence, so emit a signal changing it to
* UNKNOWN */
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, member);
}
}
tp_base_contact_list_contacts_changed (contact_list, NULL, removed);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_remove_contacts_async);
}
static void
example_contact_list_unsubscribe_async (TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = lookup_contact (self, member);
/* we would like to avoid receiving member's presence any more,
* or we would like to cancel an outstanding request for their
* presence */
if (d != NULL)
{
if (d->subscribe_requested)
{
g_message ("Cancelling our authorization request to %s",
tp_handle_inspect (self->priv->contact_repo, member));
d->subscribe_requested = FALSE;
tp_handle_set_add (changed, member);
send_updated_roster (self, member);
}
else if (d->subscribe_rejected)
{
g_message ("Forgetting rejected authorization request to %s",
tp_handle_inspect (self->priv->contact_repo, member));
d->subscribe_rejected = FALSE;
tp_handle_set_add (changed, member);
send_updated_roster (self, member);
}
else if (d->subscribe)
{
g_message ("We no longer want presence from %s",
tp_handle_inspect (self->priv->contact_repo, member));
d->subscribe = FALSE;
/* since they're no longer on the subscribe list, we can't
* see their presence, so emit a signal changing it to
* UNKNOWN */
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, member);
tp_handle_set_add (changed, member);
send_updated_roster (self, member);
}
}
}
tp_base_contact_list_contacts_changed (contact_list, changed, NULL);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_unsubscribe_async);
}
static void
example_contact_list_unpublish_async (TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpHandleSet *removed = tp_handle_set_new (self->priv->contact_repo);
TpIntsetFastIter iter;
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = lookup_contact (self, member);
const gchar *request = g_hash_table_lookup (self->priv->publish_requests,
GUINT_TO_POINTER (member));
/* we would like member not to see our presence any more, or we
* would like to reject a request from them to see our presence */
if (request != NULL)
{
g_message ("Rejecting authorization request from %s",
tp_handle_inspect (self->priv->contact_repo, member));
g_hash_table_remove (self->priv->publish_requests,
GUINT_TO_POINTER (member));
if (d == NULL)
{
/* the contact wasn't actually on our protocol-level contact
* list, only on the Telepathy-level contact list, so rejecting
* authorization makes them disappear */
tp_handle_set_add (removed, member);
}
else
{
tp_handle_set_add (changed, member);
}
}
if (tp_handle_set_remove (self->priv->cancelled_publish_requests,
member))
{
g_message ("Acknowledging remotely-cancelled publish request");
tp_handle_set_add (changed, member);
}
if (d != NULL)
{
d->pre_approved = FALSE;
if (d->publish)
{
g_message ("Removing authorization from %s",
tp_handle_inspect (self->priv->contact_repo, member));
d->publish = FALSE;
tp_handle_set_add (changed, member);
send_updated_roster (self, member);
/* Pretend that after a delay, the contact notices the change
* and asks for our presence again */
g_timeout_add_full (G_PRIORITY_LOW,
self->priv->simulation_delay, auth_request_cb,
self_and_contact_new (self, member),
self_and_contact_destroy);
}
}
}
tp_base_contact_list_contacts_changed (contact_list, changed, removed);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_unpublish_async);
}
static TpHandleSet *
example_contact_list_dup_blocked_contacts (TpBaseContactList *contact_list)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
return tp_handle_set_copy (self->priv->blocked_contacts);
}
static void
example_contact_list_block_contacts_async (TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpIntsetFastIter iter;
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
if (!tp_handle_set_is_member (self->priv->blocked_contacts, member))
{
g_message ("Adding contact %s to blocked list",
tp_handle_inspect (self->priv->contact_repo, member));
tp_handle_set_add (self->priv->blocked_contacts, member);
tp_handle_set_add (changed, member);
}
}
tp_base_contact_list_contact_blocking_changed (contact_list, changed);
tp_handle_set_destroy (changed);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_block_contacts_async);
}
static void
example_contact_list_unblock_contacts_async (TpBaseContactList *contact_list,
TpHandleSet *contacts,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpIntsetFastIter iter;
TpHandleSet *changed = tp_handle_set_new (self->priv->contact_repo);
TpHandle member;
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
if (tp_handle_set_remove (self->priv->blocked_contacts, member))
{
g_message ("Removing contact %s from blocked list",
tp_handle_inspect (self->priv->contact_repo, member));
tp_handle_set_add (changed, member);
}
}
tp_base_contact_list_contact_blocking_changed (contact_list, changed);
tp_handle_set_destroy (changed);
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, example_contact_list_unblock_contacts_async);
}
static guint
example_contact_list_get_group_storage (
TpBaseContactList *contact_list G_GNUC_UNUSED)
{
return TP_CONTACT_METADATA_STORAGE_TYPE_ANYONE;
}
static GStrv
example_contact_list_dup_groups (TpBaseContactList *contact_list)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
GPtrArray *tags = g_ptr_array_sized_new (
g_hash_table_size (self->priv->all_tags) + 1);
GHashTableIter iter;
gpointer tag;
g_hash_table_iter_init (&iter, self->priv->all_tags);
while (g_hash_table_iter_next (&iter, &tag, NULL))
g_ptr_array_add (tags, g_strdup (tag));
g_ptr_array_add (tags, NULL);
return (GStrv) g_ptr_array_free (tags, FALSE);
}
static GStrv
example_contact_list_dup_contact_groups (TpBaseContactList *contact_list,
TpHandle contact)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
GPtrArray *tags = g_ptr_array_sized_new (
g_hash_table_size (self->priv->all_tags) + 1);
ExampleContactDetails *d = lookup_contact (self, contact);
if (d != NULL && d->tags != NULL)
{
GHashTableIter iter;
gpointer tag;
g_hash_table_iter_init (&iter, d->tags);
while (g_hash_table_iter_next (&iter, &tag, NULL))
g_ptr_array_add (tags, g_strdup (tag));
}
g_ptr_array_add (tags, NULL);
return (GStrv) g_ptr_array_free (tags, FALSE);
}
static void
example_contact_list_remove_group_async (TpBaseContactList *contact_list,
const gchar *group,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
TpIntsetFastIter iter;
TpHandle member;
/* signal the deletion */
g_message ("deleting group %s", group);
tp_base_contact_list_groups_removed (contact_list, &group, 1);
/* apply the change to our model of the contacts too; we don't need to signal
* the change, because TpBaseContactList already did */
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (self->priv->contacts));
while (tp_intset_fast_iter_next (&iter, &member))
{
ExampleContactDetails *d = lookup_contact (self, member);
if (d != NULL && d->tags != NULL)
g_hash_table_remove (d->tags, group);
}
tp_simple_async_report_success_in_idle ((GObject *) contact_list, callback,
user_data, example_contact_list_remove_group_async);
}
static gchar *
example_contact_list_normalize_group (TpBaseContactList *contact_list,
const gchar *id)
{
if (id[0] == '\0')
return NULL;
return g_utf8_normalize (id, -1, G_NORMALIZE_ALL_COMPOSE);
}
static void
example_contact_list_rename_group_async (TpBaseContactList *contact_list,
const gchar *old_name,
const gchar *new_name,
GAsyncReadyCallback callback,
gpointer user_data)
{
ExampleContactList *self = EXAMPLE_CONTACT_LIST (contact_list);
gchar *tag = ensure_tag (self, new_name, FALSE);
GHashTableIter iter;
gpointer v;
/* signal the rename */
g_print ("renaming group %s to %s", old_name, new_name);
tp_base_contact_list_group_renamed (contact_list, old_name, new_name);
/* update our model (this doesn't need to signal anything because
* TpBaseContactList already did) */
g_hash_table_iter_init (&iter, self->priv->contact_details);
while (g_hash_table_iter_next (&iter, NULL, &v))
{
ExampleContactDetails *d = v;
if (d->tags != NULL && g_hash_table_remove (d->tags, old_name))
g_hash_table_insert (d->tags, tag, tag);
}
tp_simple_async_report_success_in_idle ((GObject *) contact_list, callback,
user_data, example_contact_list_rename_group_async);
}
static void
example_contact_list_class_init (ExampleContactListClass *klass)
{
TpBaseContactListClass *contact_list_class =
(TpBaseContactListClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
g_object_class_install_property (object_class, PROP_SIMULATION_DELAY,
g_param_spec_uint ("simulation-delay", "Simulation delay",
"Delay between simulated network events",
0, G_MAXUINT32, 1000,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
contact_list_class->dup_contacts = example_contact_list_dup_contacts;
contact_list_class->dup_states = example_contact_list_dup_states;
/* for this example CM we pretend there is a server-stored contact list,
* like in XMPP, even though there obviously isn't really */
contact_list_class->get_contact_list_persists =
tp_base_contact_list_true_func;
g_type_class_add_private (klass, sizeof (ExampleContactListPrivate));
signals[ALIAS_UPDATED] = g_signal_new ("alias-updated",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
signals[PRESENCE_UPDATED] = g_signal_new ("presence-updated",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
}
static void
mutable_contact_list_iface_init (TpMutableContactListInterface *iface)
{
iface->can_change_contact_list = tp_base_contact_list_true_func;
iface->get_request_uses_message = tp_base_contact_list_true_func;
iface->request_subscription_async =
example_contact_list_request_subscription_async;
iface->authorize_publication_async =
example_contact_list_authorize_publication_async;
iface->store_contacts_async = example_contact_list_store_contacts_async;
iface->remove_contacts_async = example_contact_list_remove_contacts_async;
iface->unsubscribe_async = example_contact_list_unsubscribe_async;
iface->unpublish_async = example_contact_list_unpublish_async;
}
static void
blockable_contact_list_iface_init (TpBlockableContactListInterface *iface)
{
iface->can_block = tp_base_contact_list_true_func;
iface->dup_blocked_contacts = example_contact_list_dup_blocked_contacts;
iface->block_contacts_async = example_contact_list_block_contacts_async;
iface->unblock_contacts_async = example_contact_list_unblock_contacts_async;
}
static void
contact_group_list_iface_init (TpContactGroupListInterface *iface)
{
iface->dup_groups = example_contact_list_dup_groups;
iface->dup_group_members = example_contact_list_dup_group_members;
iface->dup_contact_groups = example_contact_list_dup_contact_groups;
iface->normalize_group = example_contact_list_normalize_group;
}
static void
mutable_contact_group_list_iface_init (
TpMutableContactGroupListInterface *iface)
{
iface->set_group_members_async =
example_contact_list_set_group_members_async;
iface->add_to_group_async = example_contact_list_add_to_group_async;
iface->remove_from_group_async =
example_contact_list_remove_from_group_async;
iface->remove_group_async = example_contact_list_remove_group_async;
iface->rename_group_async = example_contact_list_rename_group_async;
iface->set_contact_groups_async =
example_contact_list_set_contact_groups_async;
iface->get_group_storage = example_contact_list_get_group_storage;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/conn.c 0000664 0001750 0001750 00000043673 12470405660 021324 0 ustar jr jr /*
* conn.c - an example connection
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#include "conn.h"
#include
#include
#include
#include
#include "contact-list.h"
#include "protocol.h"
static void init_aliasing (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (ExampleContactListConnection,
example_contact_list_connection,
TP_TYPE_BASE_CONNECTION,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING,
init_aliasing);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
tp_contacts_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST,
tp_base_contact_list_mixin_list_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS,
tp_base_contact_list_mixin_groups_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_BLOCKING,
tp_base_contact_list_mixin_blocking_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE,
tp_presence_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
tp_presence_mixin_simple_presence_iface_init))
enum
{
PROP_ACCOUNT = 1,
PROP_SIMULATION_DELAY,
N_PROPS
};
struct _ExampleContactListConnectionPrivate
{
gchar *account;
guint simulation_delay;
ExampleContactList *contact_list;
gboolean away;
};
static void
example_contact_list_connection_init (ExampleContactListConnection *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
ExampleContactListConnectionPrivate);
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *spec)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
switch (property_id)
{
case PROP_ACCOUNT:
g_value_set_string (value, self->priv->account);
break;
case PROP_SIMULATION_DELAY:
g_value_set_uint (value, self->priv->simulation_delay);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *spec)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
switch (property_id)
{
case PROP_ACCOUNT:
g_free (self->priv->account);
self->priv->account = g_value_dup_string (value);
break;
case PROP_SIMULATION_DELAY:
self->priv->simulation_delay = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
}
static void
finalize (GObject *object)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
tp_contacts_mixin_finalize (object);
g_free (self->priv->account);
G_OBJECT_CLASS (example_contact_list_connection_parent_class)->finalize (
object);
}
static gchar *
get_unique_connection_name (TpBaseConnection *conn)
{
ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (conn);
return g_strdup_printf ("%s@%p", self->priv->account, self);
}
gchar *
example_contact_list_normalize_contact (TpHandleRepoIface *repo,
const gchar *id,
gpointer context,
GError **error)
{
gchar *normal = NULL;
if (example_contact_list_protocol_check_contact_id (id, &normal, error))
return normal;
else
return NULL;
}
static void
create_handle_repos (TpBaseConnection *conn,
TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES])
{
repos[TP_HANDLE_TYPE_CONTACT] = tp_dynamic_handle_repo_new
(TP_HANDLE_TYPE_CONTACT, example_contact_list_normalize_contact, NULL);
}
static void
alias_updated_cb (ExampleContactList *contact_list,
TpHandle contact,
ExampleContactListConnection *self)
{
GPtrArray *aliases;
GValueArray *pair;
pair = g_value_array_new (2);
g_value_array_append (pair, NULL);
g_value_array_append (pair, NULL);
g_value_init (pair->values + 0, G_TYPE_UINT);
g_value_init (pair->values + 1, G_TYPE_STRING);
g_value_set_uint (pair->values + 0, contact);
g_value_set_string (pair->values + 1,
example_contact_list_get_alias (contact_list, contact));
aliases = g_ptr_array_sized_new (1);
g_ptr_array_add (aliases, pair);
tp_svc_connection_interface_aliasing_emit_aliases_changed (self, aliases);
g_ptr_array_free (aliases, TRUE);
g_value_array_free (pair);
}
static void
presence_updated_cb (ExampleContactList *contact_list,
TpHandle contact,
ExampleContactListConnection *self)
{
TpBaseConnection *base = (TpBaseConnection *) self;
TpPresenceStatus *status;
/* we ignore the presence indicated by the contact list for our own handle */
if (contact == base->self_handle)
return;
status = tp_presence_status_new (
example_contact_list_get_presence (contact_list, contact),
NULL);
tp_presence_mixin_emit_one_presence_update ((GObject *) self,
contact, status);
tp_presence_status_free (status);
}
static GPtrArray *
create_channel_managers (TpBaseConnection *conn)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (conn);
GPtrArray *ret = g_ptr_array_sized_new (1);
self->priv->contact_list = EXAMPLE_CONTACT_LIST (g_object_new (
EXAMPLE_TYPE_CONTACT_LIST,
"connection", conn,
"simulation-delay", self->priv->simulation_delay,
NULL));
g_signal_connect (self->priv->contact_list, "alias-updated",
G_CALLBACK (alias_updated_cb), self);
g_signal_connect (self->priv->contact_list, "presence-updated",
G_CALLBACK (presence_updated_cb), self);
g_ptr_array_add (ret, self->priv->contact_list);
return ret;
}
static gboolean
start_connecting (TpBaseConnection *conn,
GError **error)
{
ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (conn);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
TP_HANDLE_TYPE_CONTACT);
/* In a real connection manager we'd ask the underlying implementation to
* start connecting, then go to state CONNECTED when finished, but here
* we can do it immediately. */
conn->self_handle = tp_handle_ensure (contact_repo, self->priv->account,
NULL, error);
if (conn->self_handle == 0)
return FALSE;
tp_base_connection_change_status (conn, TP_CONNECTION_STATUS_CONNECTED,
TP_CONNECTION_STATUS_REASON_REQUESTED);
return TRUE;
}
static void
shut_down (TpBaseConnection *conn)
{
/* In a real connection manager we'd ask the underlying implementation to
* start shutting down, then call this function when finished, but here
* we can do it immediately. */
tp_base_connection_finish_shutdown (conn);
}
static void
aliasing_fill_contact_attributes (GObject *object,
const GArray *contacts,
GHashTable *attributes)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
guint i;
for (i = 0; i < contacts->len; i++)
{
TpHandle contact = g_array_index (contacts, guint, i);
tp_contacts_mixin_set_contact_attribute (attributes, contact,
TP_TOKEN_CONNECTION_INTERFACE_ALIASING_ALIAS,
tp_g_value_slice_new_string (
example_contact_list_get_alias (self->priv->contact_list,
contact)));
}
}
static void
constructed (GObject *object)
{
TpBaseConnection *base = TP_BASE_CONNECTION (object);
void (*chain_up) (GObject *) =
G_OBJECT_CLASS (example_contact_list_connection_parent_class)->constructed;
if (chain_up != NULL)
chain_up (object);
tp_contacts_mixin_init (object,
G_STRUCT_OFFSET (ExampleContactListConnection, contacts_mixin));
tp_base_connection_register_with_contacts_mixin (base);
tp_base_contact_list_mixin_register_with_contacts_mixin (base);
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
aliasing_fill_contact_attributes);
tp_presence_mixin_init (object,
G_STRUCT_OFFSET (ExampleContactListConnection, presence_mixin));
tp_presence_mixin_simple_presence_register_with_contacts_mixin (object);
}
static gboolean
status_available (GObject *object,
guint index_)
{
TpBaseConnection *base = TP_BASE_CONNECTION (object);
if (base->status != TP_CONNECTION_STATUS_CONNECTED)
return FALSE;
return TRUE;
}
static GHashTable *
get_contact_statuses (GObject *object,
const GArray *contacts,
GError **error)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
TpBaseConnection *base = TP_BASE_CONNECTION (object);
guint i;
GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) tp_presence_status_free);
for (i = 0; i < contacts->len; i++)
{
TpHandle contact = g_array_index (contacts, guint, i);
ExampleContactListPresence presence;
GHashTable *parameters;
/* we get our own status from the connection, and everyone else's status
* from the contact lists */
if (contact == base->self_handle)
{
presence = (self->priv->away ? EXAMPLE_CONTACT_LIST_PRESENCE_AWAY
: EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE);
}
else
{
presence = example_contact_list_get_presence (
self->priv->contact_list, contact);
}
parameters = g_hash_table_new_full (g_str_hash,
g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);
g_hash_table_insert (result, GUINT_TO_POINTER (contact),
tp_presence_status_new (presence, parameters));
g_hash_table_destroy (parameters);
}
return result;
}
static gboolean
set_own_status (GObject *object,
const TpPresenceStatus *status,
GError **error)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (object);
TpBaseConnection *base = TP_BASE_CONNECTION (object);
GHashTable *presences;
if (status->index == EXAMPLE_CONTACT_LIST_PRESENCE_AWAY)
{
if (self->priv->away)
return TRUE;
self->priv->away = TRUE;
}
else
{
if (!self->priv->away)
return TRUE;
self->priv->away = FALSE;
}
presences = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, NULL);
g_hash_table_insert (presences, GUINT_TO_POINTER (base->self_handle),
(gpointer) status);
tp_presence_mixin_emit_presence_update (object, presences);
g_hash_table_destroy (presences);
return TRUE;
}
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_BLOCKING,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
NULL };
const gchar * const *
example_contact_list_connection_get_possible_interfaces (void)
{
/* in this example CM we don't have any extra interfaces that are sometimes,
* but not always, present */
return interfaces_always_present;
}
static void
example_contact_list_connection_class_init (
ExampleContactListConnectionClass *klass)
{
TpBaseConnectionClass *base_class = (TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->constructed = constructed;
object_class->finalize = finalize;
g_type_class_add_private (klass,
sizeof (ExampleContactListConnectionPrivate));
base_class->create_handle_repos = create_handle_repos;
base_class->get_unique_connection_name = get_unique_connection_name;
base_class->create_channel_managers = create_channel_managers;
base_class->start_connecting = start_connecting;
base_class->shut_down = shut_down;
base_class->interfaces_always_present = interfaces_always_present;
param_spec = g_param_spec_string ("account", "Account name",
"The username of this user", NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
param_spec = g_param_spec_uint ("simulation-delay", "Simulation delay",
"Delay between simulated network events",
0, G_MAXUINT32, 1000,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SIMULATION_DELAY,
param_spec);
tp_contacts_mixin_class_init (object_class,
G_STRUCT_OFFSET (ExampleContactListConnectionClass, contacts_mixin));
tp_presence_mixin_class_init (object_class,
G_STRUCT_OFFSET (ExampleContactListConnectionClass, presence_mixin),
status_available, get_contact_statuses, set_own_status,
example_contact_list_presence_statuses ());
tp_presence_mixin_simple_presence_init_dbus_properties (object_class);
tp_base_contact_list_mixin_class_init (base_class);
}
static void
get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
DBusGMethodInvocation *context)
{
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context,
TP_CONNECTION_ALIAS_FLAG_USER_SET);
}
static void
get_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
const GArray *contacts,
DBusGMethodInvocation *context)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GHashTable *result;
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
for (i = 0; i < contacts->len; i++)
{
TpHandle contact = g_array_index (contacts, TpHandle, i);
const gchar *alias = example_contact_list_get_alias (
self->priv->contact_list, contact);
g_hash_table_insert (result, GUINT_TO_POINTER (contact),
(gchar *) alias);
}
tp_svc_connection_interface_aliasing_return_from_get_aliases (context,
result);
g_hash_table_destroy (result);
}
static void
request_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
const GArray *contacts,
DBusGMethodInvocation *context)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GPtrArray *result;
gchar **strings;
GError *error = NULL;
guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
result = g_ptr_array_sized_new (contacts->len + 1);
for (i = 0; i < contacts->len; i++)
{
TpHandle contact = g_array_index (contacts, TpHandle, i);
const gchar *alias = example_contact_list_get_alias (
self->priv->contact_list, contact);
g_ptr_array_add (result, (gchar *) alias);
}
g_ptr_array_add (result, NULL);
strings = (gchar **) g_ptr_array_free (result, FALSE);
tp_svc_connection_interface_aliasing_return_from_request_aliases (context,
(const gchar **) strings);
g_free (strings);
}
static void
set_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
GHashTable *aliases,
DBusGMethodInvocation *context)
{
ExampleContactListConnection *self =
EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, aliases);
while (g_hash_table_iter_next (&iter, &key, &value))
{
GError *error = NULL;
if (!tp_handle_is_valid (contact_repo, GPOINTER_TO_UINT (key),
&error))
{
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
}
g_hash_table_iter_init (&iter, aliases);
while (g_hash_table_iter_next (&iter, &key, &value))
{
example_contact_list_set_alias (self->priv->contact_list,
GPOINTER_TO_UINT (key), value);
}
tp_svc_connection_interface_aliasing_return_from_set_aliases (context);
}
static void
init_aliasing (gpointer iface,
gpointer iface_data G_GNUC_UNUSED)
{
TpSvcConnectionInterfaceAliasingClass *klass = iface;
#define IMPLEMENT(x) tp_svc_connection_interface_aliasing_implement_##x (\
klass, x)
IMPLEMENT(get_alias_flags);
IMPLEMENT(request_aliases);
IMPLEMENT(get_aliases);
IMPLEMENT(set_aliases);
#undef IMPLEMENT
}
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/protocol.h 0000664 0001750 0001750 00000004135 12470405660 022223 0 ustar jr jr /*
* protocol.h - header for an example Protocol
* Copyright © 2007-2010 Collabora Ltd.
*
* 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.
*/
#ifndef EXAMPLE_CONTACT_LIST_PROTOCOL_H
#define EXAMPLE_CONTACT_LIST_PROTOCOL_H
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleContactListProtocol
ExampleContactListProtocol;
typedef struct _ExampleContactListProtocolPrivate
ExampleContactListProtocolPrivate;
typedef struct _ExampleContactListProtocolClass
ExampleContactListProtocolClass;
typedef struct _ExampleContactListProtocolClassPrivate
ExampleContactListProtocolClassPrivate;
struct _ExampleContactListProtocolClass {
TpBaseProtocolClass parent_class;
ExampleContactListProtocolClassPrivate *priv;
};
struct _ExampleContactListProtocol {
TpBaseProtocol parent;
ExampleContactListProtocolPrivate *priv;
};
GType example_contact_list_protocol_get_type (void);
#define EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL \
(example_contact_list_protocol_get_type ())
#define EXAMPLE_CONTACT_LIST_PROTOCOL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL, \
ExampleContactListProtocol))
#define EXAMPLE_CONTACT_LIST_PROTOCOL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL, \
ExampleContactListProtocolClass))
#define EXAMPLE_IS_CONTACT_LIST_PROTOCOL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL))
#define EXAMPLE_IS_CONTACT_LIST_PROTOCOL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL))
#define EXAMPLE_CONTACT_LIST_PROTOCOL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL, \
ExampleContactListProtocolClass))
gboolean example_contact_list_protocol_check_contact_id (const gchar *id,
gchar **normal,
GError **error);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/connection-manager.c 0000664 0001750 0001750 00000004160 12470405660 024122 0 ustar jr jr /*
* manager.c - an example connection manager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#include "connection-manager.h"
#include
#include
#include
#include "conn.h"
#include "protocol.h"
G_DEFINE_TYPE (ExampleContactListConnectionManager,
example_contact_list_connection_manager,
TP_TYPE_BASE_CONNECTION_MANAGER)
struct _ExampleContactListConnectionManagerPrivate
{
int dummy;
};
static void
example_contact_list_connection_manager_init (
ExampleContactListConnectionManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION_MANAGER,
ExampleContactListConnectionManagerPrivate);
}
static void
example_contact_list_connection_manager_constructed (GObject *object)
{
ExampleContactListConnectionManager *self =
EXAMPLE_CONTACT_LIST_CONNECTION_MANAGER (object);
TpBaseConnectionManager *base = (TpBaseConnectionManager *) self;
void (*constructed) (GObject *) =
((GObjectClass *) example_contact_list_connection_manager_parent_class)->constructed;
TpBaseProtocol *protocol;
if (constructed != NULL)
constructed (object);
protocol = g_object_new (EXAMPLE_TYPE_CONTACT_LIST_PROTOCOL,
"name", "example",
NULL);
tp_base_connection_manager_add_protocol (base, protocol);
g_object_unref (protocol);
}
static void
example_contact_list_connection_manager_class_init (
ExampleContactListConnectionManagerClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
TpBaseConnectionManagerClass *base_class =
(TpBaseConnectionManagerClass *) klass;
g_type_class_add_private (klass,
sizeof (ExampleContactListConnectionManagerPrivate));
object_class->constructed = example_contact_list_connection_manager_constructed;
base_class->cm_dbus_name = "example_contact_list";
}
telepathy-qt-0.9.6~git1/tests/lib/glib/contactlist2/protocol.c 0000664 0001750 0001750 00000011522 12470405660 022214 0 ustar jr jr /*
* protocol.c - an example Protocol
*
* Copyright © 2007-2010 Collabora Ltd.
*
* 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.
*/
#include "protocol.h"
#include
#include "conn.h"
#include "contact-list.h"
G_DEFINE_TYPE (ExampleContactListProtocol,
example_contact_list_protocol,
TP_TYPE_BASE_PROTOCOL)
static void
example_contact_list_protocol_init (
ExampleContactListProtocol *self)
{
}
gboolean
example_contact_list_protocol_check_contact_id (const gchar *id,
gchar **normal,
GError **error)
{
g_return_val_if_fail (id != NULL, FALSE);
if (id[0] == '\0')
{
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_HANDLE,
"ID must not be empty");
return FALSE;
}
if (normal != NULL)
*normal = g_utf8_normalize (id, -1, G_NORMALIZE_ALL_COMPOSE);
return TRUE;
}
static gboolean
account_param_filter (const TpCMParamSpec *paramspec,
GValue *value,
GError **error)
{
const gchar *id = g_value_get_string (value);
return example_contact_list_protocol_check_contact_id (id, NULL, error);
}
static const TpCMParamSpec example_contact_list_example_params[] = {
{ "account", "s", G_TYPE_STRING,
TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_REGISTER,
NULL, /* no default */
0, /* unused, formerly struct offset */
account_param_filter,
NULL, /* filter data, unused here */
NULL }, /* setter data, now unused */
{ "simulation-delay", "u", G_TYPE_UINT,
TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT,
GUINT_TO_POINTER (1000), /* default */
0, /* unused, formerly struct offset */
NULL, /* no filter */
NULL, /* filter data, unused here */
NULL }, /* setter data, now unused */
{ NULL }
};
static const TpCMParamSpec *
get_parameters (TpBaseProtocol *self)
{
return example_contact_list_example_params;
}
static TpBaseConnection *
new_connection (TpBaseProtocol *protocol,
GHashTable *asv,
GError **error)
{
ExampleContactListConnection *conn;
const gchar *account;
guint sim_delay;
account = tp_asv_get_string (asv, "account");
/* telepathy-glib checked this for us */
g_assert (account != NULL);
sim_delay = tp_asv_get_uint32 (asv, "simulation-delay", NULL);
conn = EXAMPLE_CONTACT_LIST_CONNECTION (
g_object_new (EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
"account", account,
"protocol", tp_base_protocol_get_name (protocol),
"simulation-delay", sim_delay,
NULL));
return (TpBaseConnection *) conn;
}
static gchar *
normalize_contact (TpBaseProtocol *self G_GNUC_UNUSED,
const gchar *contact,
GError **error)
{
gchar *normal;
if (example_contact_list_protocol_check_contact_id (contact, &normal, error))
return normal;
else
return NULL;
}
static gchar *
identify_account (TpBaseProtocol *self G_GNUC_UNUSED,
GHashTable *asv,
GError **error)
{
const gchar *account = tp_asv_get_string (asv, "account");
if (account != NULL)
return normalize_contact (self, account, error);
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"'account' parameter not given");
return NULL;
}
static GStrv
get_interfaces (TpBaseProtocol *self)
{
return NULL;
}
static void
get_connection_details (TpBaseProtocol *self G_GNUC_UNUSED,
GStrv *connection_interfaces,
GType **channel_managers,
gchar **icon_name,
gchar **english_name,
gchar **vcard_field)
{
if (connection_interfaces != NULL)
{
*connection_interfaces = g_strdupv (
(GStrv) example_contact_list_connection_get_possible_interfaces ());
}
if (channel_managers != NULL)
{
GType types[] = { EXAMPLE_TYPE_CONTACT_LIST, G_TYPE_INVALID };
*channel_managers = g_memdup (types, sizeof (types));
}
if (icon_name != NULL)
*icon_name = g_strdup ("face-smile");
if (english_name != NULL)
*english_name = g_strdup ("Example with a contact list");
if (vcard_field != NULL)
*vcard_field = g_strdup ("x-telepathy-example");
}
static void
example_contact_list_protocol_class_init (
ExampleContactListProtocolClass *klass)
{
TpBaseProtocolClass *base_class =
(TpBaseProtocolClass *) klass;
base_class->get_parameters = get_parameters;
base_class->new_connection = new_connection;
base_class->normalize_contact = normalize_contact;
base_class->identify_account = identify_account;
base_class->get_interfaces = get_interfaces;
base_class->get_connection_details = get_connection_details;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/textchan-null.h 0000664 0001750 0001750 00000011742 12470405660 020541 0 ustar jr jr /*
* /dev/null as a text channel
*
* Copyright (C) 2008 Collabora Ltd.
* Copyright (C) 2008 Nokia Corporation
*
* 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.
*/
#ifndef __TP_TESTS_TEXT_CHANNEL_NULL_H__
#define __TP_TESTS_TEXT_CHANNEL_NULL_H__
#include
#include
#include
#include
G_BEGIN_DECLS
typedef struct _TpTestsTextChannelNull TpTestsTextChannelNull;
typedef struct _TpTestsTextChannelNullClass TpTestsTextChannelNullClass;
typedef struct _TpTestsTextChannelNullPrivate TpTestsTextChannelNullPrivate;
GType tp_tests_text_channel_null_get_type (void);
#define TP_TESTS_TYPE_TEXT_CHANNEL_NULL \
(tp_tests_text_channel_null_get_type ())
#define TP_TESTS_TEXT_CHANNEL_NULL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
TpTestsTextChannelNull))
#define TP_TESTS_TEXT_CHANNEL_NULL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
TpTestsTextChannelNullClass))
#define TP_TESTS_IS_TEXT_CHANNEL_NULL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL))
#define TP_TESTS_IS_TEXT_CHANNEL_NULL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_NULL))
#define TP_TESTS_TEXT_CHANNEL_NULL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
TpTestsTextChannelNullClass))
struct _TpTestsTextChannelNullClass {
GObjectClass parent_class;
const gchar **interfaces;
TpTextMixinClass text_class;
};
struct _TpTestsTextChannelNull {
GObject parent;
TpTextMixin text;
guint get_handle_called;
guint get_interfaces_called;
guint get_channel_type_called;
TpTestsTextChannelNullPrivate *priv;
};
/* Subclass with D-Bus properties */
typedef struct _TestPropsTextChannel TpTestsPropsTextChannel;
typedef struct _TestPropsTextChannelClass TpTestsPropsTextChannelClass;
struct _TestPropsTextChannel {
TpTestsTextChannelNull parent;
GHashTable *dbus_property_interfaces_retrieved;
};
struct _TestPropsTextChannelClass {
TpTestsTextChannelNullClass parent;
TpDBusPropertiesMixinClass dbus_properties_class;
};
GType tp_tests_props_text_channel_get_type (void);
#define TP_TESTS_TYPE_PROPS_TEXT_CHANNEL \
(tp_tests_props_text_channel_get_type ())
#define TP_TESTS_PROPS_TEXT_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
TpTestsPropsTextChannel))
#define TP_TESTS_PROPS_TEXT_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
TpTestsPropsTextChannelClass))
#define TP_TESTS_IS_PROPS_TEXT_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL))
#define TP_TESTS_IS_PROPS_TEXT_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL))
#define TP_TESTS_PROPS_TEXT_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
TpTestsPropsTextChannelClass))
/* Subclass with D-Bus properties and Group */
typedef struct _TestPropsGroupTextChannel TpTestsPropsGroupTextChannel;
typedef struct _TestPropsGroupTextChannelClass TpTestsPropsGroupTextChannelClass;
struct _TestPropsGroupTextChannel {
TpTestsPropsTextChannel parent;
TpGroupMixin group;
};
struct _TestPropsGroupTextChannelClass {
TpTestsPropsTextChannelClass parent;
TpGroupMixinClass group_class;
};
GType tp_tests_props_group_text_channel_get_type (void);
#define TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL \
(tp_tests_props_group_text_channel_get_type ())
#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
TpTestsPropsGroupTextChannel))
#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
TpTestsPropsGroupTextChannelClass))
#define TP_TESTS_IS_PROPS_GROUP_TEXT_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL))
#define TP_TESTS_IS_PROPS_GROUP_TEXT_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL))
#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
TpTestsPropsGroupTextChannelClass))
void tp_tests_text_channel_null_close (TpTestsTextChannelNull *self);
GHashTable * tp_tests_text_channel_get_props (TpTestsTextChannelNull *self);
G_END_DECLS
#endif /* #ifndef __TP_TESTS_TEXT_CHANNEL_NULL_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/captcha-chan.c 0000664 0001750 0001750 00000041713 12470405660 020261 0 ustar jr jr /*
* captcha-chan.c - Simple captcha channel
*
* Copyright (C) 2012 Collabora Ltd.
*
* 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.
*/
#include "captcha-chan.h"
#include
#include
#include
#include
enum
{
PROP_METHOD = 1,
PROP_RETRY,
PROP_STATUS,
PROP_ERROR,
PROP_ERROR_DETAILS
};
struct _TpTestsCaptchaChannelPrivate {
TpCaptchaStatus status;
TpSocketAccessControl access_control;
GHashTable *parameters;
gchar *error_string;
GHashTable *error_details;
gboolean can_retry;
gboolean is_retrying;
};
static void
tp_tests_captcha_channel_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) object;
switch (property_id)
{
case PROP_METHOD:
g_value_set_string (value, TP_IFACE_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION);
break;
case PROP_RETRY:
g_value_set_boolean (value, self->priv->can_retry);
break;
case PROP_STATUS:
g_value_set_uint (value, self->priv->status);
break;
case PROP_ERROR:
g_value_set_string (value, self->priv->error_string);
break;
case PROP_ERROR_DETAILS:
g_value_set_boxed (value, self->priv->error_details);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
tp_tests_captcha_channel_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) object;
switch (property_id)
{
case PROP_RETRY:
self->priv->can_retry = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void captcha_iface_init (gpointer iface, gpointer data);
G_DEFINE_TYPE_WITH_CODE (TpTestsCaptchaChannel,
tp_tests_captcha_channel,
TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_SERVER_AUTHENTICATION,
NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION,
captcha_iface_init);
)
/* type definition stuff */
static const char * tp_tests_captcha_channel_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION,
NULL
};
static void
tp_tests_captcha_channel_init (TpTestsCaptchaChannel *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
TP_TESTS_TYPE_CAPTCHA_CHANNEL, TpTestsCaptchaChannelPrivate);
}
static GObject *
constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
GObject *object =
G_OBJECT_CLASS (tp_tests_captcha_channel_parent_class)->constructor (
type, n_props, props);
TpTestsCaptchaChannel *self = TP_TESTS_CAPTCHA_CHANNEL (object);
self->priv->status = TP_CAPTCHA_STATUS_LOCAL_PENDING;
self->priv->is_retrying = FALSE;
self->priv->error_string = NULL;
self->priv->error_details = tp_asv_new (NULL, NULL);
tp_base_channel_register (TP_BASE_CHANNEL (self));
return object;
}
static void
dispose (GObject *object)
{
// TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) object;
// Free memory here if needed
((GObjectClass *) tp_tests_captcha_channel_parent_class)->dispose (
object);
}
static void
channel_close (TpBaseChannel *channel)
{
tp_base_channel_destroyed (channel);
}
static void
fill_immutable_properties (TpBaseChannel *chan,
GHashTable *properties)
{
TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
tp_tests_captcha_channel_parent_class);
tp_dbus_properties_mixin_fill_properties_hash (
G_OBJECT (chan), properties,
TP_IFACE_CHANNEL_TYPE_SERVER_AUTHENTICATION, "AuthenticationMethod",
TP_IFACE_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION, "CanRetryCaptcha",
NULL);
klass->fill_immutable_properties (chan, properties);
}
static void
tp_tests_captcha_channel_class_init (TpTestsCaptchaChannelClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
GParamSpec *param_spec;
static TpDBusPropertiesMixinPropImpl server_authentication_props[] = {
{ "AuthenticationMethod", "authentication-method", NULL },
{ NULL, NULL, NULL }
};
static TpDBusPropertiesMixinPropImpl captcha_authentication_props[] = {
{ "CanRetryCaptcha", "can-retry-captcha", NULL },
{ "CaptchaStatus", "captcha-status", NULL },
{ "CaptchaError", "captcha-error", NULL },
{ "CaptchaErrorDetails", "captcha-error-details", NULL },
{ NULL }
};
object_class->constructor = constructor;
object_class->get_property = tp_tests_captcha_channel_get_property;
object_class->set_property = tp_tests_captcha_channel_set_property;
object_class->dispose = dispose;
base_class->channel_type = TP_IFACE_CHANNEL_TYPE_SERVER_AUTHENTICATION;
base_class->target_handle_type = TP_HANDLE_TYPE_NONE;
base_class->interfaces = tp_tests_captcha_channel_interfaces;
base_class->close = channel_close;
base_class->fill_immutable_properties = fill_immutable_properties;
param_spec = g_param_spec_string ("authentication-method", "AuthenticationMethod",
"the authentication method for this channel",
"",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_METHOD, param_spec);
param_spec = g_param_spec_boolean (
"can-retry-captcha", "CanRetryCaptcha",
"Whether Captcha can be retried or not.",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_RETRY,
param_spec);
param_spec = g_param_spec_string (
"captcha-error", "CaptchaError",
"error details of the captcha",
"",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ERROR,
param_spec);
param_spec = g_param_spec_boxed (
"captcha-error-details", "CaptchaErrorDetails",
"error details of the captcha",
TP_HASH_TYPE_STRING_VARIANT_MAP,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ERROR_DETAILS,
param_spec);
param_spec = g_param_spec_uint (
"captcha-status", "CaptchaStatus",
"state of the captcha",
0, NUM_TP_CAPTCHA_STATUSES - 1, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_STATUS,
param_spec);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
server_authentication_props);
tp_dbus_properties_mixin_implement_interface (object_class,
TP_IFACE_QUARK_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION,
tp_dbus_properties_mixin_getter_gobject_properties, NULL,
captcha_authentication_props);
g_type_class_add_private (object_class,
sizeof (TpTestsCaptchaChannelPrivate));
}
static void
set_status (TpTestsCaptchaChannel *self,
guint status,
const gchar *error,
GHashTable *error_details)
{
GPtrArray *changed = g_ptr_array_new ();
GHashTable *realerrors = error_details == NULL ? tp_asv_new (NULL, NULL) : error_details;
if (self->priv->status != status)
{
self->priv->status = status;
g_ptr_array_add (changed, (gpointer) "CaptchaStatus");
}
if (self->priv->error_string != error)
{
g_free (self->priv->error_string);
self->priv->error_string = g_strdup (error);
g_ptr_array_add (changed, (gpointer) "CaptchaError");
}
if (self->priv->error_details != realerrors)
{
if (self->priv->error_details != NULL)
g_hash_table_unref (self->priv->error_details);
self->priv->error_details = realerrors;
if (self->priv->error_details != NULL)
g_hash_table_ref (self->priv->error_details);
g_ptr_array_add (changed, (gpointer) "CaptchaErrorDetails");
}
if (changed->len > 0)
{
g_ptr_array_add (changed, NULL);
tp_dbus_properties_mixin_emit_properties_changed (G_OBJECT (self),
TP_IFACE_CHANNEL_INTERFACE_CAPTCHA_AUTHENTICATION,
(const gchar * const *) changed->pdata);
}
g_ptr_array_unref (changed);
}
static void
captcha_auth_answer_captchas (TpSvcChannelInterfaceCaptchaAuthentication *iface,
GHashTable *answers,
DBusGMethodInvocation *context)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) iface;
const gchar *answer;
GError *error;
if (self->priv->status != TP_CAPTCHA_STATUS_LOCAL_PENDING)
{
error = g_error_new (TP_ERROR,
TP_ERROR_NOT_AVAILABLE, "Captcha status is in state %u",
self->priv->status);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
set_status(self, TP_CAPTCHA_STATUS_REMOTE_PENDING, NULL, NULL);
answer = (const gchar *) g_hash_table_lookup (answers,
GUINT_TO_POINTER (42));
if (answer == NULL)
{
error = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Missing required challenge ID (%u)", 42);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
if (tp_str_empty (answer))
{
error = g_error_new_literal (TP_ERROR,
TP_ERROR_INVALID_ARGUMENT, "Empty answer");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
if (tp_strdiff (answer, "This is the right answer"))
{
if (self->priv->can_retry)
{
set_status(self, TP_CAPTCHA_STATUS_TRY_AGAIN, NULL, NULL);
}
else
{
set_status(self, TP_CAPTCHA_STATUS_FAILED, NULL, NULL);
}
error = g_error_new_literal (TP_ERROR,
TP_ERROR_INVALID_ARGUMENT, "Wrong answer");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
else
{
set_status(self, TP_CAPTCHA_STATUS_SUCCEEDED, NULL, NULL);
}
tp_svc_channel_interface_captcha_authentication_return_from_answer_captchas (context);
}
static void
captcha_auth_get_captchas (TpSvcChannelInterfaceCaptchaAuthentication *iface,
DBusGMethodInvocation *context)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) iface;
GPtrArray *infos;
GValueArray *info;
static const gchar *mime_types_1[] = { "image/png", NULL };
static const gchar *mime_types_2[] = { "lol/wut", NULL };
static const gchar *no_mime_types[] = { NULL };
if (self->priv->status != TP_CAPTCHA_STATUS_LOCAL_PENDING &&
self->priv->status != TP_CAPTCHA_STATUS_TRY_AGAIN)
{
GError *error = g_error_new (TP_ERROR,
TP_ERROR_NOT_AVAILABLE, "Captcha status is in state %u",
self->priv->status);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
/* Yes, g_ptr_array_new_full() could be used here, but use
* these functions instead to support older GLibs */
infos = g_ptr_array_sized_new (5);
g_ptr_array_set_free_func (infos, (GDestroyNotify) g_value_array_free);
info = tp_value_array_build (5,
G_TYPE_UINT, 42,
G_TYPE_STRING, "ocr",
G_TYPE_STRING, "Enter the text displayed",
G_TYPE_UINT, 0,
G_TYPE_STRV, mime_types_1,
G_TYPE_INVALID);
g_ptr_array_add (infos, info);
info = tp_value_array_build (5,
G_TYPE_UINT, 76,
G_TYPE_STRING, "picture_q",
G_TYPE_STRING, "What in this picture?",
G_TYPE_UINT, 0,
G_TYPE_STRV, mime_types_2,
G_TYPE_INVALID);
g_ptr_array_add (infos, info);
info = tp_value_array_build (5,
G_TYPE_UINT, 15,
G_TYPE_STRING, "qa",
G_TYPE_STRING, "What is the answer?",
G_TYPE_UINT, 0,
G_TYPE_STRV, no_mime_types,
G_TYPE_INVALID);
g_ptr_array_add (infos, info);
info = tp_value_array_build (5,
G_TYPE_UINT, 51,
G_TYPE_STRING, "video_q",
G_TYPE_STRING, "Totallyfake",
G_TYPE_UINT, 0,
G_TYPE_STRV, no_mime_types,
G_TYPE_INVALID);
g_ptr_array_add (infos, info);
info = tp_value_array_build (5,
G_TYPE_UINT, 17,
G_TYPE_STRING, "video_recog",
G_TYPE_STRING, "Totallyfakeurgonnadie",
G_TYPE_UINT, 0,
G_TYPE_STRV, mime_types_2,
G_TYPE_INVALID);
g_ptr_array_add (infos, info);
if (self->priv->status == TP_CAPTCHA_STATUS_TRY_AGAIN)
{
/* Handler started trying again, change status back */
set_status (self,
TP_CAPTCHA_STATUS_LOCAL_PENDING, NULL, NULL);
self->priv->is_retrying = TRUE;
}
tp_svc_channel_interface_captcha_authentication_return_from_get_captchas (context,
infos, 1, "");
g_ptr_array_unref (infos);
}
static void
captcha_auth_get_captcha_data (TpSvcChannelInterfaceCaptchaAuthentication *iface,
guint id,
const gchar *mime_type,
DBusGMethodInvocation *context)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) iface;
GArray *captcha;
if (self->priv->status != TP_CAPTCHA_STATUS_LOCAL_PENDING)
{
GError *error = g_error_new (TP_ERROR,
TP_ERROR_NOT_AVAILABLE, "Captcha status is in state %u",
self->priv->status);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
if (id != 42 && id != 76)
{
GError *error = g_error_new (TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"Invalid captcha ID (%u).",
id);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
if (tp_strdiff (mime_type, "image/png") && tp_strdiff (mime_type, "lol/wut"))
{
GError *error = g_error_new (TP_ERROR,
TP_ERROR_INVALID_ARGUMENT,
"MIME type '%s' was not in the list provided. ", mime_type);
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
captcha = g_array_new (TRUE, FALSE, sizeof (guchar));
if (self->priv->is_retrying)
{
g_array_append_vals (captcha,
"This is a reloaded payload", 26);
}
else
{
g_array_append_vals (captcha,
"This is a fake payload", 22);
}
tp_svc_channel_interface_captcha_authentication_return_from_get_captcha_data (context,
captcha);
g_array_unref (captcha);
}
static void
captcha_auth_cancel_captcha (TpSvcChannelInterfaceCaptchaAuthentication *iface,
guint reason,
const gchar *debug_message,
DBusGMethodInvocation *context)
{
TpTestsCaptchaChannel *self = (TpTestsCaptchaChannel *) iface;
const gchar *error = NULL;
GError *gerror = NULL;
GHashTable *error_details = NULL;
if (self->priv->status == TP_CAPTCHA_STATUS_FAILED)
{
gerror = g_error_new_literal (TP_ERROR,
TP_ERROR_NOT_AVAILABLE, "Captcha status is already Failed");
dbus_g_method_return_error (context, gerror);
g_error_free (gerror);
return;
}
switch (reason)
{
case TP_CAPTCHA_CANCEL_REASON_USER_CANCELLED:
error = TP_ERROR_STR_CANCELLED;
break;
case TP_CAPTCHA_CANCEL_REASON_NOT_SUPPORTED:
error = TP_ERROR_STR_CAPTCHA_NOT_SUPPORTED;
break;
case TP_CAPTCHA_CANCEL_REASON_SERVICE_CONFUSED:
error = TP_ERROR_STR_SERVICE_CONFUSED;
break;
default:
g_warning ("Unknown cancel reason");
}
error_details = tp_asv_new (
"debug-message", G_TYPE_STRING, debug_message,
NULL);
set_status (self, TP_CAPTCHA_STATUS_FAILED,
error, error_details);
g_hash_table_unref (error_details);
tp_svc_channel_interface_captcha_authentication_return_from_cancel_captcha (context);
}
static void
captcha_iface_init (gpointer g_iface,
gpointer data G_GNUC_UNUSED)
{
TpSvcChannelInterfaceCaptchaAuthenticationClass *iface =
(TpSvcChannelInterfaceCaptchaAuthenticationClass *) g_iface;
#define IMPLEMENT(x) \
tp_svc_channel_interface_captcha_authentication_implement_##x (iface, \
captcha_auth_##x)
IMPLEMENT(answer_captchas);
IMPLEMENT(get_captchas);
IMPLEMENT(get_captcha_data);
IMPLEMENT(cancel_captcha);
#undef IMPLEMENT
}
telepathy-qt-0.9.6~git1/tests/lib/glib/bug16307-conn.h 0000664 0001750 0001750 00000004220 12470405660 020055 0 ustar jr jr /*
* bug16307-conn.h - header for a connection that reproduces the #15307 bug
*
* Copyright (C) 2007-2008 Collabora Ltd.
* Copyright (C) 2007-2008 Nokia Corporation
*
* 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.
*/
#ifndef __TP_TESTS_BUG16307_CONN_H__
#define __TP_TESTS_BUG16307_CONN_H__
#include
#include
#include "simple-conn.h"
G_BEGIN_DECLS
typedef struct _TpTestsBug16307Connection TpTestsBug16307Connection;
typedef struct _TpTestsBug16307ConnectionClass TpTestsBug16307ConnectionClass;
typedef struct _TpTestsBug16307ConnectionPrivate TpTestsBug16307ConnectionPrivate;
struct _TpTestsBug16307ConnectionClass {
TpTestsSimpleConnectionClass parent_class;
};
struct _TpTestsBug16307Connection {
TpTestsSimpleConnection parent;
TpTestsBug16307ConnectionPrivate *priv;
};
GType tp_tests_bug16307_connection_get_type (void);
/* TYPE MACROS */
#define TP_TESTS_TYPE_BUG16307_CONNECTION \
(tp_tests_bug16307_connection_get_type ())
#define TP_TESTS_BUG16307_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_BUG16307_CONNECTION, \
TpTestsBug16307Connection))
#define TP_TESTS_BUG16307_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_BUG16307_CONNECTION, \
TpTestsBug16307ConnectionClass))
#define TP_TESTS_BUG16307_IS_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_BUG16307_CONNECTION))
#define TP_TESTS_BUG16307_IS_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_BUG16307_CONNECTION))
#define TP_TESTS_BUG16307_CONNECTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_BUG16307_CONNECTION, \
TpTestsBug16307ConnectionClass))
/* Cause "network events", for debugging/testing */
void tp_tests_bug16307_connection_inject_get_status_return (TpTestsBug16307Connection *self);
G_END_DECLS
#endif /* #ifndef __TP_TESTS_BUG16307_CONN_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/util.c 0000664 0001750 0001750 00000026753 12470405660 016733 0 ustar jr jr /* Simple utility code used by the regression tests.
*
* Copyright © 2008-2010 Collabora Ltd.
* Copyright © 2008 Nokia Corporation
*
* 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.
*/
#include "config.h"
#include "util.h"
#include
#include
#include
#ifdef G_OS_UNIX
# include /* for alarm() */
#endif
#ifdef HAVE_GIO_UNIX
#include
#include
#endif
void
tp_tests_proxy_run_until_prepared (gpointer proxy,
const GQuark *features)
{
GError *error = NULL;
tp_tests_proxy_run_until_prepared_or_failed (proxy, features, &error);
g_assert_no_error (error);
}
/* A GAsyncReadyCallback whose user_data is a GAsyncResult **. It writes a
* reference to the result into that pointer. */
void
tp_tests_result_ready_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
GAsyncResult **result = user_data;
*result = g_object_ref (res);
}
/* Run until *result contains a result. Intended to be used with a pending
* async call that uses tp_tests_result_ready_cb. */
void
tp_tests_run_until_result (GAsyncResult **result)
{
/* not synchronous */
g_assert (*result == NULL);
while (*result == NULL)
g_main_context_iteration (NULL, TRUE);
}
gboolean
tp_tests_proxy_run_until_prepared_or_failed (gpointer proxy,
const GQuark *features,
GError **error)
{
GAsyncResult *result = NULL;
gboolean r;
tp_proxy_prepare_async (proxy, features, tp_tests_result_ready_cb, &result);
tp_tests_run_until_result (&result);
r = tp_proxy_prepare_finish (proxy, result, error);
g_object_unref (result);
return r;
}
TpDBusDaemon *
tp_tests_dbus_daemon_dup_or_die (void)
{
TpDBusDaemon *d = tp_dbus_daemon_dup (NULL);
/* In a shared library, this would be very bad (see fd.o #18832), but in a
* regression test that's going to be run under a temporary session bus,
* it's just what we want. */
if (d == NULL)
{
g_error ("Unable to connect to session bus");
}
return d;
}
static void
introspect_cb (TpProxy *proxy G_GNUC_UNUSED,
const gchar *xml G_GNUC_UNUSED,
const GError *error G_GNUC_UNUSED,
gpointer user_data,
GObject *weak_object G_GNUC_UNUSED)
{
g_main_loop_quit (user_data);
}
void
tp_tests_proxy_run_until_dbus_queue_processed (gpointer proxy)
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
tp_cli_dbus_introspectable_call_introspect (proxy, -1, introspect_cb,
loop, NULL, NULL);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
void
_test_assert_empty_strv (const char *file,
int line,
gconstpointer strv)
{
const gchar * const *strings = strv;
if (strv != NULL && strings[0] != NULL)
{
guint i;
g_message ("%s:%d: expected empty strv, but got:", file, line);
for (i = 0; strings[i] != NULL; i++)
{
g_message ("* \"%s\"", strings[i]);
}
g_error ("%s:%d: strv wasn't empty (see above for contents",
file, line);
}
}
void
_tp_tests_assert_strv_equals (const char *file,
int line,
const char *expected_desc,
gconstpointer expected_strv,
const char *actual_desc,
gconstpointer actual_strv)
{
const gchar * const *expected = expected_strv;
const gchar * const *actual = actual_strv;
guint i;
g_assert (expected != NULL);
g_assert (actual != NULL);
for (i = 0; expected[i] != NULL || actual[i] != NULL; i++)
{
if (expected[i] == NULL)
{
g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
"NULL == %s", file, line, expected_desc, i,
actual_desc, i, actual[i]);
}
else if (actual[i] == NULL)
{
g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
"%s == NULL", file, line, expected_desc, i,
actual_desc, i, expected[i]);
}
else if (tp_strdiff (expected[i], actual[i]))
{
g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
"%s == %s", file, line, expected_desc, i,
actual_desc, i, expected[i], actual[i]);
}
}
}
void
tp_tests_create_conn (GType conn_type,
const gchar *account,
gboolean connect,
TpBaseConnection **service_conn,
TpConnection **client_conn)
{
TpDBusDaemon *dbus;
TpSimpleClientFactory *factory;
gchar *name;
gchar *conn_path;
GError *error = NULL;
g_assert (service_conn != NULL);
g_assert (client_conn != NULL);
dbus = tp_tests_dbus_daemon_dup_or_die ();
factory = (TpSimpleClientFactory *) tp_automatic_client_factory_new (dbus);
*service_conn = tp_tests_object_new_static_class (
conn_type,
"account", account,
"protocol", "simple",
NULL);
g_assert (*service_conn != NULL);
g_assert (tp_base_connection_register (*service_conn, "simple",
&name, &conn_path, &error));
g_assert_no_error (error);
*client_conn = tp_simple_client_factory_ensure_connection (factory,
conn_path, NULL, &error);
g_assert (*client_conn != NULL);
g_assert_no_error (error);
if (connect)
{
GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
tp_cli_connection_call_connect (*client_conn, -1, NULL, NULL, NULL, NULL);
tp_tests_proxy_run_until_prepared (*client_conn, conn_features);
}
g_free (name);
g_free (conn_path);
g_object_unref (dbus);
g_object_unref (factory);
}
void
tp_tests_create_and_connect_conn (GType conn_type,
const gchar *account,
TpBaseConnection **service_conn,
TpConnection **client_conn)
{
tp_tests_create_conn (conn_type, account, TRUE, service_conn, client_conn);
}
/* This object exists solely so that tests/tests.supp can ignore "leaked"
* classes. */
gpointer
tp_tests_object_new_static_class (GType type,
...)
{
va_list ap;
GObject *object;
const gchar *first_property;
va_start (ap, type);
first_property = va_arg (ap, const gchar *);
object = g_object_new_valist (type, first_property, ap);
va_end (ap);
return object;
}
static gboolean
time_out (gpointer nil G_GNUC_UNUSED)
{
g_error ("Timed out");
g_assert_not_reached ();
return FALSE;
}
void
tp_tests_abort_after (guint sec)
{
gboolean debugger = FALSE;
gchar *contents;
if (g_file_get_contents ("/proc/self/status", &contents, NULL, NULL))
{
/* http://www.youtube.com/watch?v=SXmv8quf_xM */
#define TRACER_T "\nTracerPid:\t"
gchar *line = strstr (contents, TRACER_T);
if (line != NULL)
{
gchar *value = line + strlen (TRACER_T);
if (value[0] != '0' || value[1] != '\n')
debugger = TRUE;
}
g_free (contents);
}
if (g_getenv ("TP_TESTS_NO_TIMEOUT") != NULL || debugger)
return;
g_timeout_add_seconds (sec, time_out, NULL);
#ifdef G_OS_UNIX
/* On Unix, we can kill the process more reliably; this is a safety-catch
* in case it deadlocks or something, in which case the main loop won't be
* processed. The default handler for SIGALRM is process termination. */
alarm (sec + 2);
#endif
}
void
tp_tests_init (int *argc,
char ***argv)
{
g_type_init ();
tp_tests_abort_after (10);
tp_debug_set_flags ("all");
g_test_init (argc, argv, NULL);
}
void
_tp_destroy_socket_control_list (gpointer data)
{
GArray *tab = data;
g_array_unref (tab);
}
GValue *
_tp_create_local_socket (TpSocketAddressType address_type,
TpSocketAccessControl access_control,
GSocketService **service,
gchar **unix_address,
GError **error)
{
gboolean success;
GSocketAddress *address, *effective_address;
GValue *address_gvalue;
g_assert (service != NULL);
g_assert (unix_address != NULL);
switch (access_control)
{
case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
case TP_SOCKET_ACCESS_CONTROL_PORT:
break;
default:
g_assert_not_reached ();
}
switch (address_type)
{
#ifdef HAVE_GIO_UNIX
case TP_SOCKET_ADDRESS_TYPE_UNIX:
{
address = g_unix_socket_address_new (tmpnam (NULL));
break;
}
#endif
case TP_SOCKET_ADDRESS_TYPE_IPV4:
case TP_SOCKET_ADDRESS_TYPE_IPV6:
{
GInetAddress *localhost;
localhost = g_inet_address_new_loopback (
address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
G_SOCKET_FAMILY_IPV4 : G_SOCKET_FAMILY_IPV6);
address = g_inet_socket_address_new (localhost, 0);
g_object_unref (localhost);
break;
}
default:
g_assert_not_reached ();
}
*service = g_socket_service_new ();
success = g_socket_listener_add_address (
G_SOCKET_LISTENER (*service),
address, G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
NULL, &effective_address, NULL);
g_assert (success);
switch (address_type)
{
#ifdef HAVE_GIO_UNIX
case TP_SOCKET_ADDRESS_TYPE_UNIX:
*unix_address = g_strdup (g_unix_socket_address_get_path (
G_UNIX_SOCKET_ADDRESS (effective_address)));
address_gvalue = tp_g_value_slice_new_bytes (
g_unix_socket_address_get_path_len (
G_UNIX_SOCKET_ADDRESS (effective_address)),
g_unix_socket_address_get_path (
G_UNIX_SOCKET_ADDRESS (effective_address)));
break;
#endif
case TP_SOCKET_ADDRESS_TYPE_IPV4:
case TP_SOCKET_ADDRESS_TYPE_IPV6:
*unix_address = NULL;
address_gvalue = tp_g_value_slice_new_take_boxed (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
dbus_g_type_specialized_construct (
TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
dbus_g_type_struct_set (address_gvalue,
0, address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
"127.0.0.1" : "::1",
1, g_inet_socket_address_get_port (
G_INET_SOCKET_ADDRESS (effective_address)),
G_MAXUINT);
break;
default:
g_assert_not_reached ();
}
g_object_unref (address);
g_object_unref (effective_address);
return address_gvalue;
}
void
tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection)
{
GAsyncResult *result = NULL;
GError *error = NULL;
gboolean ok;
tp_connection_disconnect_async (connection, tp_tests_result_ready_cb,
&result);
tp_tests_run_until_result (&result);
ok = tp_connection_disconnect_finish (connection, result, &error);
g_assert_no_error (error);
g_assert (ok);
g_object_unref (result);
}
/* The following blocks require tp-glib 0.19 to compile. However, tp_tests_connection_run_until_contact_by_id
is never used in our code, so we simply disable its compilation. */
#if 0
static void
one_contact_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
TpConnection *connection = (TpConnection *) object;
TpContact **contact_loc = user_data;
GError *error = NULL;
*contact_loc = tp_connection_dup_contact_by_id_finish (connection, result,
&error);
g_assert_no_error (error);
g_assert (TP_IS_CONTACT (*contact_loc));
}
TpContact *
tp_tests_connection_run_until_contact_by_id (TpConnection *connection,
const gchar *id,
guint n_features,
const TpContactFeature *features)
{
TpContact *contact = NULL;
tp_connection_dup_contact_by_id_async (connection, id, n_features, features,
one_contact_cb, &contact);
while (contact == NULL)
g_main_context_iteration (NULL, TRUE);
return contact;
}
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/contact-search-chan.c 0000664 0001750 0001750 00000053313 12470405660 021553 0 ustar jr jr /*
* contact-search-channel.c - an tp_tests contact search channel
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "contact-search-chan.h"
#include
#include
#include
#include
#include
#include
#include
#include
static void contact_search_iface_init (gpointer iface, gpointer data);
static void channel_iface_init (gpointer iface, gpointer data);
G_DEFINE_TYPE_WITH_CODE (TpTestsContactSearchChannel,
tp_tests_contact_search_channel,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_CONTACT_SEARCH,
contact_search_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
tp_group_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL))
enum
{
PROP_OBJECT_PATH = 1,
PROP_CHANNEL_TYPE,
PROP_HANDLE_TYPE,
PROP_HANDLE,
PROP_TARGET_ID,
PROP_REQUESTED,
PROP_INITIATOR_HANDLE,
PROP_INITIATOR_ID,
PROP_CONNECTION,
PROP_INTERFACES,
PROP_CHANNEL_DESTROYED,
PROP_CHANNEL_PROPERTIES,
PROP_CONTACT_SEARCH_STATE,
PROP_CONTACT_SEARCH_LIMIT,
PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS,
PROP_CONTACT_SEARCH_SERVER,
N_PROPS
};
typedef struct
{
gchar *id;
gchar *employer;
GPtrArray *contact_info;
} TpTestsContactSearchContact;
struct _TpTestsContactSearchChannelPrivate
{
TpBaseConnection *conn;
gchar *object_path;
guint contact_search_state;
guint contact_search_limit;
gchar **contact_search_available_search_keys;
gchar *contact_search_server;
GSList *contact_search_contacts;
gboolean disposed;
gboolean closed;
};
static const gchar * tp_tests_contact_search_channel_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_GROUP,
NULL
};
static void
tp_tests_contact_search_channel_init (TpTestsContactSearchChannel *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_CONTACT_SEARCH_CHANNEL,
TpTestsContactSearchChannelPrivate);
}
static TpTestsContactSearchContact *
new_contact (const gchar *id, const gchar *employer, const gchar *fn)
{
TpTestsContactSearchContact *contact = g_new (TpTestsContactSearchContact, 1);
GPtrArray *contact_info = dbus_g_type_specialized_construct (
TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST);
const gchar * const field_values[2] = { fn, NULL };
contact->id = g_strdup (id);
contact->employer = g_strdup (employer);
g_ptr_array_add (contact_info, tp_value_array_build (3,
G_TYPE_STRING, "fn",
G_TYPE_STRV, NULL,
G_TYPE_STRV, field_values,
G_TYPE_INVALID));
contact->contact_info = contact_info;
return contact;
}
static void
free_contact (TpTestsContactSearchContact *contact)
{
g_free (contact->id);
g_free (contact->employer);
g_boxed_free (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, contact->contact_info);
g_free (contact);
}
static void
constructed (GObject *object)
{
void (*chain_up) (GObject *) =
((GObjectClass *) tp_tests_contact_search_channel_parent_class)->constructed;
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
(self->priv->conn, TP_HANDLE_TYPE_CONTACT);
TpDBusDaemon *bus;
if (chain_up != NULL)
{
chain_up (object);
}
bus = tp_dbus_daemon_dup (NULL);
tp_dbus_daemon_register_object (bus, self->priv->object_path, object);
tp_group_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactSearchChannel, group),
contact_repo, self->priv->conn->self_handle);
self->priv->contact_search_state = TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED;
self->priv->contact_search_limit = 0;
self->priv->contact_search_available_search_keys = g_new0 (gchar *, 2);
self->priv->contact_search_available_search_keys[0] = g_strdup ("employer");
self->priv->contact_search_server = g_strdup ("characters.shakespeare.lit");
self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts,
new_contact ("oggis", "Collabora", "Olli Salli"));
self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts,
new_contact ("andrunko", "Collabora", "Andre Moreira Magalhaes"));
self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts,
new_contact ("wjt", "Collabora", "Will Thompson"));
self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts,
new_contact ("foo", "Other Employer", "Foo"));
self->priv->contact_search_contacts = g_slist_append (self->priv->contact_search_contacts,
new_contact ("bar", "Other Employer", "Bar"));
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
g_value_set_string (value, self->priv->object_path);
break;
case PROP_CHANNEL_TYPE:
g_value_set_static_string (value, TP_IFACE_CHANNEL);
break;
case PROP_HANDLE_TYPE:
g_value_set_uint (value, TP_HANDLE_TYPE_NONE);
break;
case PROP_HANDLE:
g_value_set_uint (value, 0);
break;
case PROP_TARGET_ID:
g_value_set_string (value, "");
break;
case PROP_REQUESTED:
g_value_set_boolean (value, TRUE);
break;
case PROP_INITIATOR_HANDLE:
g_value_set_uint (value, 0);
break;
case PROP_INITIATOR_ID:
g_value_set_string (value, "");
break;
case PROP_CONNECTION:
g_value_set_object (value, self->priv->conn);
break;
case PROP_INTERFACES:
g_value_set_boxed (value, tp_tests_contact_search_channel_interfaces);
break;
case PROP_CHANNEL_DESTROYED:
g_value_set_boolean (value, self->priv->closed);
break;
case PROP_CHANNEL_PROPERTIES:
g_value_take_boxed (value,
tp_dbus_properties_mixin_make_properties_hash (object,
TP_IFACE_CHANNEL, "ChannelType",
TP_IFACE_CHANNEL, "TargetHandleType",
TP_IFACE_CHANNEL, "TargetHandle",
TP_IFACE_CHANNEL, "TargetID",
TP_IFACE_CHANNEL, "InitiatorHandle",
TP_IFACE_CHANNEL, "InitiatorID",
TP_IFACE_CHANNEL, "Requested",
TP_IFACE_CHANNEL, "Interfaces",
TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "SearchState",
TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "Limit",
TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "AvailableSearchKeys",
TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, "Server",
NULL));
break;
case PROP_CONTACT_SEARCH_STATE:
g_value_set_uint (value, self->priv->contact_search_state);
g_assert (G_VALUE_HOLDS (value, G_TYPE_UINT));
break;
case PROP_CONTACT_SEARCH_LIMIT:
g_value_set_uint (value, self->priv->contact_search_limit);
g_assert (G_VALUE_HOLDS (value, G_TYPE_UINT));
break;
case PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS:
g_value_set_boxed (value, self->priv->contact_search_available_search_keys);
g_assert (G_VALUE_HOLDS (value, G_TYPE_STRV));
break;
case PROP_CONTACT_SEARCH_SERVER:
g_value_set_string (value, self->priv->contact_search_server);
g_assert (G_VALUE_HOLDS (value, G_TYPE_STRING));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
self->priv->object_path = g_value_dup_string (value);
break;
case PROP_CONNECTION:
self->priv->conn = g_value_get_object (value);
break;
case PROP_CHANNEL_TYPE:
case PROP_HANDLE:
case PROP_HANDLE_TYPE:
case PROP_TARGET_ID:
case PROP_REQUESTED:
case PROP_INITIATOR_HANDLE:
case PROP_INITIATOR_ID:
/* these properties are not actually meaningfully changeable on this
* channel, so we do nothing */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
dispose (GObject *object)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object);
GSList *l;
if (self->priv->disposed)
{
return;
}
self->priv->disposed = TRUE;
g_strfreev (self->priv->contact_search_available_search_keys);
self->priv->contact_search_available_search_keys = NULL;
g_free (self->priv->contact_search_server);
self->priv->contact_search_server = NULL;
for (l = self->priv->contact_search_contacts; l != NULL; l = g_slist_next (l))
{
free_contact ((TpTestsContactSearchContact *) l->data);
}
g_slist_free (self->priv->contact_search_contacts);
if (!self->priv->closed)
{
self->priv->closed = TRUE;
tp_svc_channel_emit_closed (self);
}
((GObjectClass *) tp_tests_contact_search_channel_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (object);
g_free (self->priv->object_path);
tp_group_mixin_finalize (object);
((GObjectClass *) tp_tests_contact_search_channel_parent_class)->finalize (object);
}
static void
tp_tests_contact_search_channel_class_init (TpTestsContactSearchChannelClass *klass)
{
static TpDBusPropertiesMixinPropImpl channel_props[] = {
{ "TargetHandleType", "handle-type", NULL },
{ "TargetHandle", "handle", NULL },
{ "ChannelType", "channel-type", NULL },
{ "Interfaces", "interfaces", NULL },
{ "TargetID", "target-id", NULL },
{ "Requested", "requested", NULL },
{ "InitiatorHandle", "initiator-handle", NULL },
{ "InitiatorID", "initiator-id", NULL },
{ NULL }
};
static TpDBusPropertiesMixinPropImpl contact_search_props[] = {
{ "SearchState", "search-state", NULL },
{ "Limit", "limit", NULL },
{ "AvailableSearchKeys", "available-search-keys", NULL },
{ "Server", "server", NULL },
{ NULL }
};
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CHANNEL,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
channel_props,
},
{ TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
contact_search_props,
},
{ NULL }
};
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
g_type_class_add_private (klass,
sizeof (TpTestsContactSearchChannelPrivate));
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
g_object_class_override_property (object_class, PROP_OBJECT_PATH,
"object-path");
g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
"channel-type");
g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
"handle-type");
g_object_class_override_property (object_class, PROP_HANDLE,
"handle");
g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
"channel-destroyed");
g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
"channel-properties");
param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
"Connection object that owns this channel",
TP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
"Additional Channel.Interface.* interfaces",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
param_spec = g_param_spec_string ("target-id", "Peer's ID",
"The string obtained by inspecting the target handle",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle",
"The contact who initiated the channel",
0, G_MAXUINT32, 0,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE,
param_spec);
param_spec = g_param_spec_string ("initiator-id", "Initiator's ID",
"The string obtained by inspecting the initiator-handle",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_ID,
param_spec);
param_spec = g_param_spec_boolean ("requested", "Requested?",
"True if this channel was requested by the local user",
FALSE,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
param_spec = g_param_spec_uint ("search-state", "Search state",
"The search state",
0, NUM_TP_CHANNEL_CONTACT_SEARCH_STATES, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_STATE,
param_spec);
param_spec = g_param_spec_uint ("limit", "Search limit",
"The search limit",
0, G_MAXUINT32, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_LIMIT,
param_spec);
param_spec = g_param_spec_boxed ("available-search-keys", "Available Search Keys",
"The available search keys",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_AVAILABLE_SEARCH_KEYS, param_spec);
param_spec = g_param_spec_string ("server", "Server",
"The search server",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONTACT_SEARCH_SERVER,
param_spec);
klass->dbus_properties_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsContactSearchChannelClass,
dbus_properties_class));
tp_group_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpTestsContactSearchChannelClass, group_class),
NULL, NULL);
tp_group_mixin_init_dbus_properties (object_class);
}
static void
channel_close (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface);
if (!self->priv->closed)
{
self->priv->closed = TRUE;
tp_svc_channel_emit_closed (self);
}
tp_svc_channel_return_from_close (context);
}
static void
channel_get_channel_type (TpSvcChannel *iface G_GNUC_UNUSED,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_channel_type (context,
TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH);
}
static void
channel_get_handle (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0);
}
static void
channel_get_interfaces (TpSvcChannel *iface G_GNUC_UNUSED,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_interfaces (context,
tp_tests_contact_search_channel_interfaces);
}
static void
channel_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_implement_##x (klass, channel_##x)
IMPLEMENT (close);
IMPLEMENT (get_channel_type);
IMPLEMENT (get_handle);
IMPLEMENT (get_interfaces);
#undef IMPLEMENT
}
static void
change_search_state (TpTestsContactSearchChannel *self,
guint state,
const gchar *debug_message)
{
GHashTable *details = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, (GDestroyNotify) tp_g_value_slice_free);
g_hash_table_insert (details, "debug-message", tp_g_value_slice_new_string (debug_message));
self->priv->contact_search_state = state;
tp_svc_channel_type_contact_search_emit_search_state_changed (self,
self->priv->contact_search_state, "", details);
g_hash_table_destroy (details);
}
static gboolean
validate_terms (TpTestsContactSearchChannel *self,
GHashTable *terms,
GError **error)
{
const gchar * const *asks =
(const gchar * const *) self->priv->contact_search_available_search_keys;
GHashTableIter iter;
gpointer key;
g_hash_table_iter_init (&iter, terms);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
gchar *field = key;
if (!tp_strv_contains (asks, field))
{
g_debug ("%s is not in AvailableSearchKeys", field);
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"%s is not in AvailableSearchKeys", field);
return FALSE;
}
}
return TRUE;
}
static gboolean
do_search (TpTestsContactSearchChannel *self,
GHashTable *terms,
GError **error)
{
GHashTable *results = g_hash_table_new (g_str_hash, g_str_equal);
GHashTableIter iter;
gchar *key, *value;
if (!validate_terms (self, terms, error))
{
return FALSE;
}
g_debug ("Doing search");
change_search_state (self, TP_CHANNEL_CONTACT_SEARCH_STATE_IN_PROGRESS, "in progress");
g_hash_table_iter_init (&iter, terms);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value))
{
GSList *l;
for (l = self->priv->contact_search_contacts; l != NULL; l = g_slist_next (l))
{
TpTestsContactSearchContact *contact = (TpTestsContactSearchContact *) l->data;
if (strcmp (contact->employer, value) == 0)
{
g_hash_table_insert (results, contact->id, contact->contact_info);
}
}
}
tp_svc_channel_type_contact_search_emit_search_result_received (self,
results);
change_search_state (self, TP_CHANNEL_CONTACT_SEARCH_STATE_COMPLETED, "completed");
g_hash_table_destroy (results);
return TRUE;
}
static void
contact_search_search (TpSvcChannelTypeContactSearch *iface G_GNUC_UNUSED,
GHashTable *terms,
DBusGMethodInvocation *context)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface);
TpTestsContactSearchChannelPrivate *priv = self->priv;
GError *error = NULL;
if (priv->contact_search_state != TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED)
{
g_debug ("Search state is %d", priv->contact_search_state);
error = g_error_new (TP_ERROR, TP_ERROR_NOT_AVAILABLE,
"SearchState is %d", priv->contact_search_state);
goto err;
}
if (do_search (self, terms, &error))
{
tp_svc_channel_type_contact_search_return_from_search (context);
return;
}
err:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static void
contact_search_more (TpSvcChannelTypeContactSearch *iface G_GNUC_UNUSED,
DBusGMethodInvocation *context)
{
tp_svc_channel_type_contact_search_return_from_more (context);
}
static void
contact_search_stop (TpSvcChannelTypeContactSearch *iface,
DBusGMethodInvocation *context)
{
TpTestsContactSearchChannel *self = TP_TESTS_CONTACT_SEARCH_CHANNEL (iface);
TpTestsContactSearchChannelPrivate *priv = self->priv;
switch (priv->contact_search_state)
{
case TP_CHANNEL_CONTACT_SEARCH_STATE_IN_PROGRESS:
change_search_state (self,
TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED, "stopped while in progress");
case TP_CHANNEL_CONTACT_SEARCH_STATE_COMPLETED:
tp_svc_channel_type_contact_search_return_from_stop (context);
break;
case TP_CHANNEL_CONTACT_SEARCH_STATE_NOT_STARTED:
{
GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
"Search() hasn't been called yet" };
g_debug ("%s", e.message);
dbus_g_method_return_error (context, &e);
break;
}
case TP_CHANNEL_CONTACT_SEARCH_STATE_FAILED:
case TP_CHANNEL_CONTACT_SEARCH_STATE_MORE_AVAILABLE:
g_assert_not_reached ();
}
}
static void
contact_search_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelTypeContactSearchClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_type_contact_search_implement_##x (klass, contact_search_##x)
IMPLEMENT (search);
IMPLEMENT (more);
IMPLEMENT (stop);
#undef IMPLEMENT
}
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/ 0000775 0001750 0001750 00000000000 12470405660 016513 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/glib/echo/connection-manager.h 0000664 0001750 0001750 00000004131 12470405660 022432 0 ustar jr jr /*
* manager.h - header for an example connection manager
* Copyright (C) 2007 Collabora Ltd.
*
* 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.
*/
#ifndef __EXAMPLE_ECHO_CONNECTION_MANAGER_H__
#define __EXAMPLE_ECHO_CONNECTION_MANAGER_H__
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleEchoConnectionManager ExampleEchoConnectionManager;
typedef struct _ExampleEchoConnectionManagerPrivate
ExampleEchoConnectionManagerPrivate;
typedef struct _ExampleEchoConnectionManagerClass
ExampleEchoConnectionManagerClass;
typedef struct _ExampleEchoConnectionManagerClassPrivate
ExampleEchoConnectionManagerClassPrivate;
struct _ExampleEchoConnectionManagerClass {
TpBaseConnectionManagerClass parent_class;
ExampleEchoConnectionManagerClassPrivate *priv;
};
struct _ExampleEchoConnectionManager {
TpBaseConnectionManager parent;
ExampleEchoConnectionManagerPrivate *priv;
};
GType example_echo_connection_manager_get_type (void);
/* TYPE MACROS */
#define EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER \
(example_echo_connection_manager_get_type ())
#define EXAMPLE_ECHO_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER, \
ExampleEchoConnectionManager))
#define EXAMPLE_ECHO_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER, \
ExampleEchoConnectionManagerClass))
#define EXAMPLE_IS_ECHO_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER))
#define EXAMPLE_IS_ECHO_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER))
#define EXAMPLE_ECHO_CONNECTION_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_ECHO_CONNECTION_MANAGER, \
ExampleEchoConnectionManagerClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/conn.h 0000664 0001750 0001750 00000003405 12470405660 017623 0 ustar jr jr /*
* conn.h - header for an example connection
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_ECHO_CONN_H__
#define __EXAMPLE_ECHO_CONN_H__
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleEchoConnection ExampleEchoConnection;
typedef struct _ExampleEchoConnectionClass ExampleEchoConnectionClass;
typedef struct _ExampleEchoConnectionPrivate ExampleEchoConnectionPrivate;
struct _ExampleEchoConnectionClass {
TpBaseConnectionClass parent_class;
};
struct _ExampleEchoConnection {
TpBaseConnection parent;
ExampleEchoConnectionPrivate *priv;
};
GType example_echo_connection_get_type (void);
/* TYPE MACROS */
#define EXAMPLE_TYPE_ECHO_CONNECTION \
(example_echo_connection_get_type ())
#define EXAMPLE_ECHO_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_ECHO_CONNECTION, \
ExampleEchoConnection))
#define EXAMPLE_ECHO_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_ECHO_CONNECTION, \
ExampleEchoConnectionClass))
#define EXAMPLE_IS_ECHO_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_ECHO_CONNECTION))
#define EXAMPLE_IS_ECHO_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_ECHO_CONNECTION))
#define EXAMPLE_ECHO_CONNECTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_ECHO_CONNECTION, \
ExampleEchoConnectionClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/CMakeLists.txt 0000664 0001750 0001750 00000001044 12470405660 021252 0 ustar jr jr if(ENABLE_TP_GLIB_TESTS)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(example_cm_echo_SRCS
chan.c
chan.h
conn.c
conn.h
connection-manager.c
connection-manager.h
im-manager.c
im-manager.h
)
add_library(example-cm-echo STATIC ${example_cm_echo_SRCS})
target_link_libraries(example-cm-echo ${TPGLIB_LIBRARIES})
tpqt_generate_manager_file(${CMAKE_CURRENT_SOURCE_DIR}/manager-file.py example_echo.manager connection-manager.c)
endif(ENABLE_TP_GLIB_TESTS)
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/manager-file.py 0000664 0001750 0001750 00000001004 12470405660 021407 0 ustar jr jr # Input for tools/manager-file.py
MANAGER = 'example_echo'
PARAMS = {
'example' : {
'account': {
'dtype': 's',
'flags': 'required register',
'filter': 'tp_cm_param_filter_string_nonempty',
# 'filter_data': 'NULL',
# 'default': ...,
# 'struct_field': '...',
# 'setter_data': 'NULL',
},
},
}
STRUCTS = {
'example': 'ExampleParams'
}
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/chan.h 0000664 0001750 0001750 00000003504 12470405660 017577 0 ustar jr jr /*
* chan.h - header for an example channel
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_CHAN_H__
#define __EXAMPLE_CHAN_H__
#include
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleEchoChannel ExampleEchoChannel;
typedef struct _ExampleEchoChannelClass ExampleEchoChannelClass;
typedef struct _ExampleEchoChannelPrivate ExampleEchoChannelPrivate;
GType example_echo_channel_get_type (void);
#define EXAMPLE_TYPE_ECHO_CHANNEL \
(example_echo_channel_get_type ())
#define EXAMPLE_ECHO_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_TYPE_ECHO_CHANNEL, \
ExampleEchoChannel))
#define EXAMPLE_ECHO_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), EXAMPLE_TYPE_ECHO_CHANNEL, \
ExampleEchoChannelClass))
#define EXAMPLE_IS_ECHO_CHANNEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXAMPLE_TYPE_ECHO_CHANNEL))
#define EXAMPLE_IS_ECHO_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), EXAMPLE_TYPE_ECHO_CHANNEL))
#define EXAMPLE_ECHO_CHANNEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_ECHO_CHANNEL, \
ExampleEchoChannelClass))
struct _ExampleEchoChannelClass {
GObjectClass parent_class;
TpTextMixinClass text_class;
TpDBusPropertiesMixinClass dbus_properties_class;
};
struct _ExampleEchoChannel {
GObject parent;
TpTextMixin text;
ExampleEchoChannelPrivate *priv;
};
G_END_DECLS
#endif /* #ifndef __EXAMPLE_CHAN_H__ */
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/conn.c 0000664 0001750 0001750 00000012252 12470405660 017616 0 ustar jr jr /*
* conn.c - an example connection
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
#include "conn.h"
#include
#include
#include
#include "im-manager.h"
G_DEFINE_TYPE (ExampleEchoConnection,
example_echo_connection,
TP_TYPE_BASE_CONNECTION)
/* type definition stuff */
enum
{
PROP_ACCOUNT = 1,
N_PROPS
};
struct _ExampleEchoConnectionPrivate
{
gchar *account;
};
static void
example_echo_connection_init (ExampleEchoConnection *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EXAMPLE_TYPE_ECHO_CONNECTION,
ExampleEchoConnectionPrivate);
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *spec)
{
ExampleEchoConnection *self = EXAMPLE_ECHO_CONNECTION (object);
switch (property_id) {
case PROP_ACCOUNT:
g_value_set_string (value, self->priv->account);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *spec)
{
ExampleEchoConnection *self = EXAMPLE_ECHO_CONNECTION (object);
switch (property_id) {
case PROP_ACCOUNT:
g_free (self->priv->account);
self->priv->account = g_utf8_strdown (g_value_get_string (value), -1);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
}
static void
finalize (GObject *object)
{
ExampleEchoConnection *self = EXAMPLE_ECHO_CONNECTION (object);
g_free (self->priv->account);
G_OBJECT_CLASS (example_echo_connection_parent_class)->finalize (object);
}
static gchar *
get_unique_connection_name (TpBaseConnection *conn)
{
ExampleEchoConnection *self = EXAMPLE_ECHO_CONNECTION (conn);
return g_strdup (self->priv->account);
}
static gchar *
example_echo_normalize_contact (TpHandleRepoIface *repo,
const gchar *id,
gpointer context,
GError **error)
{
if (id[0] == '\0')
{
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_HANDLE,
"ID must not be empty");
return NULL;
}
return g_utf8_strdown (id, -1);
}
static void
create_handle_repos (TpBaseConnection *conn,
TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES])
{
repos[TP_HANDLE_TYPE_CONTACT] = tp_dynamic_handle_repo_new
(TP_HANDLE_TYPE_CONTACT, example_echo_normalize_contact, NULL);
}
static GPtrArray *
create_channel_managers (TpBaseConnection *conn)
{
GPtrArray *ret = g_ptr_array_sized_new (1);
g_ptr_array_add (ret, g_object_new (EXAMPLE_TYPE_ECHO_IM_MANAGER,
"connection", conn,
NULL));
return ret;
}
static gboolean
start_connecting (TpBaseConnection *conn,
GError **error)
{
ExampleEchoConnection *self = EXAMPLE_ECHO_CONNECTION (conn);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
TP_HANDLE_TYPE_CONTACT);
/* In a real connection manager we'd ask the underlying implementation to
* start connecting, then go to state CONNECTED when finished, but here
* we can do it immediately. */
conn->self_handle = tp_handle_ensure (contact_repo, self->priv->account,
NULL, NULL);
tp_base_connection_change_status (conn, TP_CONNECTION_STATUS_CONNECTED,
TP_CONNECTION_STATUS_REASON_REQUESTED);
return TRUE;
}
static void
shut_down (TpBaseConnection *conn)
{
/* In a real connection manager we'd ask the underlying implementation to
* start shutting down, then call this function when finished, but here
* we can do it immediately. */
tp_base_connection_finish_shutdown (conn);
}
static void
example_echo_connection_class_init (ExampleEchoConnectionClass *klass)
{
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
NULL };
TpBaseConnectionClass *base_class =
(TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->finalize = finalize;
g_type_class_add_private (klass, sizeof (ExampleEchoConnectionPrivate));
base_class->create_handle_repos = create_handle_repos;
base_class->get_unique_connection_name = get_unique_connection_name;
base_class->create_channel_managers = create_channel_managers;
base_class->start_connecting = start_connecting;
base_class->shut_down = shut_down;
base_class->interfaces_always_present = interfaces_always_present;
param_spec = g_param_spec_string ("account", "Account name",
"The username of this user", NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
}
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/im-manager.h 0000664 0001750 0001750 00000003322 12470405660 020701 0 ustar jr jr /*
* im-manager.h - header for an example channel manager
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
#ifndef __EXAMPLE_ECHO_IM_MANAGER_H__
#define __EXAMPLE_ECHO_IM_MANAGER_H__
#include
G_BEGIN_DECLS
typedef struct _ExampleEchoImManager ExampleEchoImManager;
typedef struct _ExampleEchoImManagerClass ExampleEchoImManagerClass;
typedef struct _ExampleEchoImManagerPrivate ExampleEchoImManagerPrivate;
struct _ExampleEchoImManagerClass {
GObjectClass parent_class;
};
struct _ExampleEchoImManager {
GObject parent;
ExampleEchoImManagerPrivate *priv;
};
GType example_echo_im_manager_get_type (void);
/* TYPE MACROS */
#define EXAMPLE_TYPE_ECHO_IM_MANAGER \
(example_echo_im_manager_get_type ())
#define EXAMPLE_ECHO_IM_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_ECHO_IM_MANAGER, \
ExampleEchoImManager))
#define EXAMPLE_ECHO_IM_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_ECHO_IM_MANAGER, \
ExampleEchoImManagerClass))
#define EXAMPLE_IS_ECHO_IM_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_ECHO_IM_MANAGER))
#define EXAMPLE_IS_ECHO_IM_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_ECHO_IM_MANAGER))
#define EXAMPLE_ECHO_IM_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_ECHO_IM_MANAGER, \
ExampleEchoImManagerClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/chan.c 0000664 0001750 0001750 00000036513 12470405660 017600 0 ustar jr jr /*
* chan.c - an example text channel talking to a particular
* contact. Similar code is used for 1-1 IM channels in many protocols
* (IRC private messages ("/query"), XMPP IM etc.)
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
// We need to use the deprecated TpTextMixin here to test compatibility functionality
#define _TP_IGNORE_DEPRECATIONS
#include "chan.h"
#include
#include
#include
static void text_iface_init (gpointer iface, gpointer data);
static void channel_iface_init (gpointer iface, gpointer data);
static void destroyable_iface_init (gpointer iface, gpointer data);
G_DEFINE_TYPE_WITH_CODE (ExampleEchoChannel,
example_echo_channel,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TEXT, text_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DESTROYABLE,
destroyable_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL))
/* type definition stuff */
enum
{
PROP_OBJECT_PATH = 1,
PROP_CHANNEL_TYPE,
PROP_HANDLE_TYPE,
PROP_HANDLE,
PROP_TARGET_ID,
PROP_REQUESTED,
PROP_INITIATOR_HANDLE,
PROP_INITIATOR_ID,
PROP_CONNECTION,
PROP_INTERFACES,
PROP_CHANNEL_DESTROYED,
PROP_CHANNEL_PROPERTIES,
N_PROPS
};
struct _ExampleEchoChannelPrivate
{
TpBaseConnection *conn;
gchar *object_path;
TpHandle handle;
TpHandle initiator;
/* These are really booleans, but gboolean is signed. Thanks, GLib */
unsigned closed:1;
unsigned disposed:1;
};
static const char * example_echo_channel_interfaces[] = {
TP_IFACE_CHANNEL_INTERFACE_DESTROYABLE,
NULL
};
static void
example_echo_channel_init (ExampleEchoChannel *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EXAMPLE_TYPE_ECHO_CHANNEL,
ExampleEchoChannelPrivate);
}
static GObject *
constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
GObject *object =
G_OBJECT_CLASS (example_echo_channel_parent_class)->constructor (type,
n_props, props);
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (object);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
(self->priv->conn, TP_HANDLE_TYPE_CONTACT);
tp_dbus_daemon_register_object (
tp_base_connection_get_dbus_daemon (self->priv->conn),
self->priv->object_path, self);
tp_text_mixin_init (object, G_STRUCT_OFFSET (ExampleEchoChannel, text),
contact_repo);
tp_text_mixin_set_message_types (object,
TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE,
G_MAXUINT);
return object;
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
g_value_set_string (value, self->priv->object_path);
break;
case PROP_CHANNEL_TYPE:
g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_TEXT);
break;
case PROP_HANDLE_TYPE:
g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
break;
case PROP_HANDLE:
g_value_set_uint (value, self->priv->handle);
break;
case PROP_TARGET_ID:
{
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
self->priv->conn, TP_HANDLE_TYPE_CONTACT);
g_value_set_string (value,
tp_handle_inspect (contact_repo, self->priv->handle));
}
break;
case PROP_REQUESTED:
g_value_set_boolean (value,
(self->priv->initiator == self->priv->conn->self_handle));
break;
case PROP_INITIATOR_HANDLE:
g_value_set_uint (value, self->priv->initiator);
break;
case PROP_INITIATOR_ID:
{
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
self->priv->conn, TP_HANDLE_TYPE_CONTACT);
g_value_set_string (value,
self->priv->initiator == 0
? ""
: tp_handle_inspect (contact_repo, self->priv->initiator));
}
break;
case PROP_CONNECTION:
g_value_set_object (value, self->priv->conn);
break;
case PROP_INTERFACES:
g_value_set_boxed (value, example_echo_channel_interfaces);
break;
case PROP_CHANNEL_DESTROYED:
g_value_set_boolean (value, self->priv->closed);
break;
case PROP_CHANNEL_PROPERTIES:
g_value_take_boxed (value,
tp_dbus_properties_mixin_make_properties_hash (object,
TP_IFACE_CHANNEL, "ChannelType",
TP_IFACE_CHANNEL, "TargetHandleType",
TP_IFACE_CHANNEL, "TargetHandle",
TP_IFACE_CHANNEL, "TargetID",
TP_IFACE_CHANNEL, "InitiatorHandle",
TP_IFACE_CHANNEL, "InitiatorID",
TP_IFACE_CHANNEL, "Requested",
TP_IFACE_CHANNEL, "Interfaces",
NULL));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (object);
switch (property_id)
{
case PROP_OBJECT_PATH:
g_free (self->priv->object_path);
self->priv->object_path = g_value_dup_string (value);
break;
case PROP_HANDLE:
/* we don't ref it here because we don't necessarily have access to the
* contact repo yet - instead we ref it in the constructor.
*/
self->priv->handle = g_value_get_uint (value);
break;
case PROP_INITIATOR_HANDLE:
/* likewise */
self->priv->initiator = g_value_get_uint (value);
break;
case PROP_HANDLE_TYPE:
case PROP_CHANNEL_TYPE:
/* these properties are writable in the interface, but not actually
* meaningfully changable on this channel, so we do nothing */
break;
case PROP_CONNECTION:
self->priv->conn = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
dispose (GObject *object)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (object);
if (self->priv->disposed)
return;
self->priv->disposed = TRUE;
if (!self->priv->closed)
{
self->priv->closed = TRUE;
tp_svc_channel_emit_closed (self);
}
((GObjectClass *) example_echo_channel_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (object);
g_free (self->priv->object_path);
tp_text_mixin_finalize (object);
((GObjectClass *) example_echo_channel_parent_class)->finalize (object);
}
static void
example_echo_channel_class_init (ExampleEchoChannelClass *klass)
{
static TpDBusPropertiesMixinPropImpl channel_props[] = {
{ "TargetHandleType", "handle-type", NULL },
{ "TargetHandle", "handle", NULL },
{ "ChannelType", "channel-type", NULL },
{ "Interfaces", "interfaces", NULL },
{ "TargetID", "target-id", NULL },
{ "Requested", "requested", NULL },
{ "InitiatorHandle", "initiator-handle", NULL },
{ "InitiatorID", "initiator-id", NULL },
{ NULL }
};
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CHANNEL,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
channel_props,
},
{ NULL }
};
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
g_type_class_add_private (klass, sizeof (ExampleEchoChannelPrivate));
object_class->constructor = constructor;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
g_object_class_override_property (object_class, PROP_OBJECT_PATH,
"object-path");
g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
"channel-type");
g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
"handle-type");
g_object_class_override_property (object_class, PROP_HANDLE, "handle");
g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
"channel-destroyed");
g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
"channel-properties");
param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
"Connection object that owns this channel",
TP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
"Additional Channel.Interface.* interfaces",
G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
param_spec = g_param_spec_string ("target-id", "Peer's ID",
"The string obtained by inspecting the target handle",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle",
"The contact who initiated the channel",
0, G_MAXUINT32, 0,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE,
param_spec);
param_spec = g_param_spec_string ("initiator-id", "Initiator's ID",
"The string obtained by inspecting the initiator-handle",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_INITIATOR_ID,
param_spec);
param_spec = g_param_spec_boolean ("requested", "Requested?",
"True if this channel was requested by the local user",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
tp_text_mixin_class_init (object_class,
G_STRUCT_OFFSET (ExampleEchoChannelClass, text_class));
klass->dbus_properties_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (ExampleEchoChannelClass, dbus_properties_class));
}
static void
example_echo_channel_close (ExampleEchoChannel *self)
{
GObject *object = (GObject *) self;
if (!self->priv->closed)
{
TpHandle first_sender;
/* The manager wants to be able to respawn the channel if it has pending
* messages. When respawned, the channel must have the initiator set
* to the contact who sent us those messages (if it isn't already),
* and the messages must be marked as having been rescued so they
* don't get logged twice. */
if (tp_text_mixin_has_pending_messages (object, &first_sender))
{
if (self->priv->initiator != first_sender)
{
self->priv->initiator = first_sender;
}
tp_text_mixin_set_rescued (object);
}
else
{
/* No pending messages, so it's OK to really close */
self->priv->closed = TRUE;
}
tp_svc_channel_emit_closed (self);
}
}
static void
channel_close (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (iface);
example_echo_channel_close (self);
tp_svc_channel_return_from_close (context);
}
static void
channel_get_channel_type (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_channel_type (context,
TP_IFACE_CHANNEL_TYPE_TEXT);
}
static void
channel_get_handle (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (iface);
tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT,
self->priv->handle);
}
static void
channel_get_interfaces (TpSvcChannel *iface,
DBusGMethodInvocation *context)
{
tp_svc_channel_return_from_get_interfaces (context,
example_echo_channel_interfaces);
}
static void
channel_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelClass *klass = iface;
#define IMPLEMENT(x) tp_svc_channel_implement_##x (klass, channel_##x)
IMPLEMENT (close);
IMPLEMENT (get_channel_type);
IMPLEMENT (get_handle);
IMPLEMENT (get_interfaces);
#undef IMPLEMENT
}
static void
text_send (TpSvcChannelTypeText *iface,
guint type,
const gchar *text,
DBusGMethodInvocation *context)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (iface);
time_t timestamp = time (NULL);
gchar *echo;
guint echo_type = type;
/* Send should return just before Sent is emitted. */
tp_svc_channel_type_text_return_from_send (context);
/* Tell the client that the message was submitted for sending */
tp_svc_channel_type_text_emit_sent ((GObject *) self, timestamp, type, text);
/* Pretend that the remote contact has replied. Normally, you'd
* call tp_text_mixin_receive or tp_text_mixin_receive_with_flags
* in response to network events */
switch (type)
{
case TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
echo = g_strdup_printf ("You said: %s", text);
break;
case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION:
echo = g_strdup_printf ("notices that the user %s", text);
break;
case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE:
echo = g_strdup_printf ("You sent a notice: %s", text);
break;
default:
echo = g_strdup_printf ("You sent some weird message type, %u: \"%s\"",
type, text);
echo_type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
}
tp_text_mixin_receive ((GObject *) self, echo_type, self->priv->handle,
timestamp, echo);
g_free (echo);
}
static void
text_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelTypeTextClass *klass = iface;
tp_text_mixin_iface_init (iface, data);
#define IMPLEMENT(x) tp_svc_channel_type_text_implement_##x (klass, text_##x)
IMPLEMENT (send);
#undef IMPLEMENT
}
static void
destroyable_destroy (TpSvcChannelInterfaceDestroyable *iface,
DBusGMethodInvocation *context)
{
ExampleEchoChannel *self = EXAMPLE_ECHO_CHANNEL (iface);
tp_text_mixin_clear ((GObject *) self);
example_echo_channel_close (self);
g_assert (self->priv->closed);
tp_svc_channel_interface_destroyable_return_from_destroy (context);
}
static void
destroyable_iface_init (gpointer iface,
gpointer data)
{
TpSvcChannelInterfaceDestroyableClass *klass = iface;
#define IMPLEMENT(x) \
tp_svc_channel_interface_destroyable_implement_##x (klass, destroyable_##x)
IMPLEMENT (destroy);
#undef IMPLEMENT
}
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/connection-manager.c 0000664 0001750 0001750 00000003715 12470405660 022434 0 ustar jr jr /*
* manager.c - an example connection manager
*
* Copyright (C) 2007 Collabora Ltd.
*
* 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.
*/
#include "connection-manager.h"
#include
#include
#include
#include "conn.h"
G_DEFINE_TYPE (ExampleEchoConnectionManager,
example_echo_connection_manager,
TP_TYPE_BASE_CONNECTION_MANAGER)
/* type definition stuff */
static void
example_echo_connection_manager_init (ExampleEchoConnectionManager *self)
{
}
/* private data */
typedef struct {
gchar *account;
} ExampleParams;
#include "_gen/param-spec-struct.h"
static gpointer
alloc_params (void)
{
return g_slice_new0 (ExampleParams);
}
static void
free_params (gpointer p)
{
ExampleParams *params = p;
g_free (params->account);
g_slice_free (ExampleParams, params);
}
static const TpCMProtocolSpec example_protocols[] = {
{ "example", example_echo_example_params, alloc_params, free_params },
{ NULL, NULL }
};
static TpBaseConnection *
new_connection (TpBaseConnectionManager *self,
const gchar *proto,
TpIntSet *params_present,
gpointer parsed_params,
GError **error)
{
ExampleParams *params = parsed_params;
ExampleEchoConnection *conn = EXAMPLE_ECHO_CONNECTION
(g_object_new (EXAMPLE_TYPE_ECHO_CONNECTION,
"account", params->account,
"protocol", proto,
NULL));
return (TpBaseConnection *) conn;
}
static void
example_echo_connection_manager_class_init (
ExampleEchoConnectionManagerClass *klass)
{
TpBaseConnectionManagerClass *base_class =
(TpBaseConnectionManagerClass *) klass;
base_class->new_connection = new_connection;
base_class->cm_dbus_name = "example_echo";
base_class->protocol_params = example_protocols;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/echo/im-manager.c 0000664 0001750 0001750 00000024632 12470405660 020703 0 ustar jr jr /*
* im-manager.c - an example channel manager for channels talking to a
* particular contact. Similar code is used for 1-1 IM channels in many
* protocols (IRC private messages ("/query"), XMPP IM etc.)
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
*
* 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.
*/
#include "im-manager.h"
#include
#include
#include "chan.h"
static void channel_manager_iface_init (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (ExampleEchoImManager,
example_echo_im_manager,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
channel_manager_iface_init))
/* type definition stuff */
enum
{
PROP_CONNECTION = 1,
N_PROPS
};
struct _ExampleEchoImManagerPrivate
{
TpBaseConnection *conn;
/* GUINT_TO_POINTER (handle) => ExampleEchoChannel */
GHashTable *channels;
gulong status_changed_id;
};
static void
example_echo_im_manager_init (ExampleEchoImManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EXAMPLE_TYPE_ECHO_IM_MANAGER,
ExampleEchoImManagerPrivate);
self->priv->channels = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref);
}
static void example_echo_im_manager_close_all (ExampleEchoImManager *self);
static void
dispose (GObject *object)
{
ExampleEchoImManager *self = EXAMPLE_ECHO_IM_MANAGER (object);
example_echo_im_manager_close_all (self);
g_assert (self->priv->channels == NULL);
((GObjectClass *) example_echo_im_manager_parent_class)->dispose (object);
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ExampleEchoImManager *self = EXAMPLE_ECHO_IM_MANAGER (object);
switch (property_id)
{
case PROP_CONNECTION:
g_value_set_object (value, self->priv->conn);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ExampleEchoImManager *self = EXAMPLE_ECHO_IM_MANAGER (object);
switch (property_id)
{
case PROP_CONNECTION:
/* We don't ref the connection, because it owns a reference to the
* channel manager, and it guarantees that the manager's lifetime is
* less than its lifetime */
self->priv->conn = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
status_changed_cb (TpBaseConnection *conn,
guint status,
guint reason,
ExampleEchoImManager *self)
{
if (status == TP_CONNECTION_STATUS_DISCONNECTED)
example_echo_im_manager_close_all (self);
}
static void
constructed (GObject *object)
{
ExampleEchoImManager *self = EXAMPLE_ECHO_IM_MANAGER (object);
void (*chain_up) (GObject *) =
((GObjectClass *) example_echo_im_manager_parent_class)->constructed;
if (chain_up != NULL)
{
chain_up (object);
}
self->priv->status_changed_id = g_signal_connect (self->priv->conn,
"status-changed", (GCallback) status_changed_cb, self);
}
static void
example_echo_im_manager_class_init (ExampleEchoImManagerClass *klass)
{
GParamSpec *param_spec;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
param_spec = g_param_spec_object ("connection", "Connection object",
"The connection that owns this channel manager",
TP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
g_type_class_add_private (klass, sizeof (ExampleEchoImManagerPrivate));
}
static void
example_echo_im_manager_close_all (ExampleEchoImManager *self)
{
if (self->priv->channels != NULL)
{
GHashTable *tmp = self->priv->channels;
self->priv->channels = NULL;
g_hash_table_destroy (tmp);
}
if (self->priv->status_changed_id != 0)
{
g_signal_handler_disconnect (self->priv->conn,
self->priv->status_changed_id);
self->priv->status_changed_id = 0;
}
}
static void
example_echo_im_manager_foreach_channel (TpChannelManager *iface,
TpExportableChannelFunc callback,
gpointer user_data)
{
ExampleEchoImManager *self = EXAMPLE_ECHO_IM_MANAGER (iface);
GHashTableIter iter;
gpointer handle, channel;
g_hash_table_iter_init (&iter, self->priv->channels);
while (g_hash_table_iter_next (&iter, &handle, &channel))
{
callback (TP_EXPORTABLE_CHANNEL (channel), user_data);
}
}
static void
channel_closed_cb (ExampleEchoChannel *chan,
ExampleEchoImManager *self)
{
tp_channel_manager_emit_channel_closed_for_object (self,
TP_EXPORTABLE_CHANNEL (chan));
if (self->priv->channels != NULL)
{
TpHandle handle;
gboolean really_destroyed;
g_object_get (chan,
"handle", &handle,
"channel-destroyed", &really_destroyed,
NULL);
/* Re-announce the channel if it's not yet ready to go away (pending
* messages) */
if (really_destroyed)
{
g_hash_table_remove (self->priv->channels,
GUINT_TO_POINTER (handle));
}
else
{
tp_channel_manager_emit_new_channel (self,
TP_EXPORTABLE_CHANNEL (chan), NULL);
}
}
}
static void
new_channel (ExampleEchoImManager *self,
TpHandle handle,
TpHandle initiator,
gpointer request_token)
{
ExampleEchoChannel *chan;
gchar *object_path;
GSList *requests = NULL;
object_path = g_strdup_printf ("%s/EchoChannel%u",
self->priv->conn->object_path, handle);
chan = g_object_new (EXAMPLE_TYPE_ECHO_CHANNEL,
"connection", self->priv->conn,
"object-path", object_path,
"handle", handle,
"initiator-handle", initiator,
NULL);
g_free (object_path);
g_signal_connect (chan, "closed", (GCallback) channel_closed_cb, self);
/* self->priv->channels takes ownership of 'chan' */
g_hash_table_insert (self->priv->channels, GUINT_TO_POINTER (handle), chan);
if (request_token != NULL)
requests = g_slist_prepend (requests, request_token);
tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan),
requests);
g_slist_free (requests);
}
static const gchar * const fixed_properties[] = {
TP_PROP_CHANNEL_CHANNEL_TYPE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
NULL
};
static const gchar * const allowed_properties[] = {
TP_PROP_CHANNEL_TARGET_HANDLE,
TP_PROP_CHANNEL_TARGET_ID,
NULL
};
static void
example_echo_im_manager_foreach_channel_class (TpChannelManager *manager,
TpChannelManagerChannelClassFunc func,
gpointer user_data)
{
GHashTable *table = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE,
G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
NULL);
func (manager, table, allowed_properties, user_data);
g_hash_table_destroy (table);
}
static gboolean
example_echo_im_manager_request (ExampleEchoImManager *self,
gpointer request_token,
GHashTable *request_properties,
gboolean require_new)
{
TpHandle handle;
ExampleEchoChannel *chan;
GError *error = NULL;
if (tp_strdiff (tp_asv_get_string (request_properties,
TP_PROP_CHANNEL_CHANNEL_TYPE),
TP_IFACE_CHANNEL_TYPE_TEXT))
{
return FALSE;
}
if (tp_asv_get_uint32 (request_properties,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_CONTACT)
{
return FALSE;
}
handle = tp_asv_get_uint32 (request_properties,
TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
g_assert (handle != 0);
if (tp_channel_manager_asv_has_unknown_properties (request_properties,
fixed_properties, allowed_properties, &error))
{
goto error;
}
chan = g_hash_table_lookup (self->priv->channels, GUINT_TO_POINTER (handle));
if (chan == NULL)
{
new_channel (self, handle, self->priv->conn->self_handle, request_token);
}
else if (require_new)
{
g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
"An echo channel to contact #%u already exists", handle);
goto error;
}
else
{
tp_channel_manager_emit_request_already_satisfied (self,
request_token, TP_EXPORTABLE_CHANNEL (chan));
}
return TRUE;
error:
tp_channel_manager_emit_request_failed (self, request_token,
error->domain, error->code, error->message);
g_error_free (error);
return TRUE;
}
static gboolean
example_echo_im_manager_create_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
return example_echo_im_manager_request (EXAMPLE_ECHO_IM_MANAGER (manager),
request_token, request_properties, TRUE);
}
static gboolean
example_echo_im_manager_ensure_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
return example_echo_im_manager_request (EXAMPLE_ECHO_IM_MANAGER (manager),
request_token, request_properties, FALSE);
}
static void
channel_manager_iface_init (gpointer g_iface,
gpointer iface_data G_GNUC_UNUSED)
{
TpChannelManagerIface *iface = g_iface;
iface->foreach_channel = example_echo_im_manager_foreach_channel;
iface->foreach_channel_class = example_echo_im_manager_foreach_channel_class;
iface->create_channel = example_echo_im_manager_create_channel;
iface->ensure_channel = example_echo_im_manager_ensure_channel;
/* In this channel manager, Request has the same semantics as Ensure */
iface->request_channel = example_echo_im_manager_ensure_channel;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/call/ 0000775 0001750 0001750 00000000000 12470405660 016510 5 ustar jr jr telepathy-qt-0.9.6~git1/tests/lib/glib/call/call-content.h 0000664 0001750 0001750 00000005304 12470405660 021246 0 ustar jr jr /*
* call-content.h - header for an example content
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EXAMPLE_CALL_CONTENT_H
#define EXAMPLE_CALL_CONTENT_H
#include
#include
#include "call-stream.h"
G_BEGIN_DECLS
typedef struct _ExampleCallContent ExampleCallContent;
typedef struct _ExampleCallContentPrivate
ExampleCallContentPrivate;
typedef struct _ExampleCallContentClass
ExampleCallContentClass;
typedef struct _ExampleCallContentClassPrivate
ExampleCallContentClassPrivate;
GType example_call_content_get_type (void);
#define EXAMPLE_TYPE_CALL_CONTENT \
(example_call_content_get_type ())
#define EXAMPLE_CALL_CONTENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_TYPE_CALL_CONTENT, \
ExampleCallContent))
#define EXAMPLE_CALL_CONTENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), EXAMPLE_TYPE_CALL_CONTENT, \
ExampleCallContentClass))
#define EXAMPLE_IS_CALL_CONTENT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXAMPLE_TYPE_CALL_CONTENT))
#define EXAMPLE_IS_CALL_CONTENT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), EXAMPLE_TYPE_CALL_CONTENT))
#define EXAMPLE_CALL_CONTENT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CALL_CONTENT, \
ExampleCallContentClass))
struct _ExampleCallContentClass {
TpBaseMediaCallContentClass parent_class;
ExampleCallContentClassPrivate *priv;
};
struct _ExampleCallContent {
TpBaseMediaCallContent parent;
ExampleCallContentPrivate *priv;
};
/* In this example, each content can only have one stream. */
ExampleCallStream *example_call_content_get_stream (ExampleCallContent *self);
void example_call_content_add_stream (ExampleCallContent *self,
ExampleCallStream *stream);
void example_call_content_remove_stream (ExampleCallContent *self);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/call/cm.c 0000664 0001750 0001750 00000004775 12470405660 017270 0 ustar jr jr /*
* manager.c - an example connection manager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cm.h"
#include
#include
#include
#include "conn.h"
#include "protocol.h"
G_DEFINE_TYPE (ExampleCallConnectionManager,
example_call_connection_manager,
TP_TYPE_BASE_CONNECTION_MANAGER)
struct _ExampleCallConnectionManagerPrivate
{
int dummy;
};
static void
example_call_connection_manager_init (ExampleCallConnectionManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CALL_CONNECTION_MANAGER,
ExampleCallConnectionManagerPrivate);
}
static void
example_call_connection_manager_constructed (GObject *object)
{
ExampleCallConnectionManager *self =
EXAMPLE_CALL_CONNECTION_MANAGER (object);
TpBaseConnectionManager *base = (TpBaseConnectionManager *) self;
void (*constructed) (GObject *) =
((GObjectClass *) example_call_connection_manager_parent_class)->constructed;
TpBaseProtocol *protocol;
if (constructed != NULL)
constructed (object);
protocol = g_object_new (EXAMPLE_TYPE_CALL_PROTOCOL,
"name", "example",
NULL);
tp_base_connection_manager_add_protocol (base, protocol);
g_object_unref (protocol);
}
static void
example_call_connection_manager_class_init (
ExampleCallConnectionManagerClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
TpBaseConnectionManagerClass *base_class =
(TpBaseConnectionManagerClass *) klass;
g_type_class_add_private (klass,
sizeof (ExampleCallConnectionManagerPrivate));
object_class->constructed = example_call_connection_manager_constructed;
base_class->cm_dbus_name = "example_call";
}
telepathy-qt-0.9.6~git1/tests/lib/glib/call/cm.h 0000664 0001750 0001750 00000005261 12470405660 017264 0 ustar jr jr /*
* manager.h - header for an example connection manager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EXAMPLE_CALL_CM_H
#define EXAMPLE_CALL_CM_H
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleCallConnectionManager
ExampleCallConnectionManager;
typedef struct _ExampleCallConnectionManagerPrivate
ExampleCallConnectionManagerPrivate;
typedef struct _ExampleCallConnectionManagerClass
ExampleCallConnectionManagerClass;
typedef struct _ExampleCallConnectionManagerClassPrivate
ExampleCallConnectionManagerClassPrivate;
struct _ExampleCallConnectionManagerClass {
TpBaseConnectionManagerClass parent_class;
ExampleCallConnectionManagerClassPrivate *priv;
};
struct _ExampleCallConnectionManager {
TpBaseConnectionManager parent;
ExampleCallConnectionManagerPrivate *priv;
};
GType example_call_connection_manager_get_type (void);
/* TYPE MACROS */
#define EXAMPLE_TYPE_CALL_CONNECTION_MANAGER \
(example_call_connection_manager_get_type ())
#define EXAMPLE_CALL_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_CALL_CONNECTION_MANAGER, \
ExampleCallConnectionManager))
#define EXAMPLE_CALL_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_CALL_CONNECTION_MANAGER, \
ExampleCallConnectionManagerClass))
#define EXAMPLE_IS_CALL_CONNECTION_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_CALL_CONNECTION_MANAGER))
#define EXAMPLE_IS_CALL_CONNECTION_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_CALL_CONNECTION_MANAGER))
#define EXAMPLE_CALL_CONNECTION_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CALL_CONNECTION_MANAGER, \
ExampleCallConnectionManagerClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/call/call-stream.h 0000664 0001750 0001750 00000005245 12470405660 021073 0 ustar jr jr /*
* call-stream.h - header for an example stream
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EXAMPLE_CALL_STREAM_H
#define EXAMPLE_CALL_STREAM_H
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleCallStream ExampleCallStream;
typedef struct _ExampleCallStreamPrivate
ExampleCallStreamPrivate;
typedef struct _ExampleCallStreamClass
ExampleCallStreamClass;
typedef struct _ExampleCallStreamClassPrivate
ExampleCallStreamClassPrivate;
GType example_call_stream_get_type (void);
#define EXAMPLE_TYPE_CALL_STREAM \
(example_call_stream_get_type ())
#define EXAMPLE_CALL_STREAM(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_TYPE_CALL_STREAM, \
ExampleCallStream))
#define EXAMPLE_CALL_STREAM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), EXAMPLE_TYPE_CALL_STREAM, \
ExampleCallStreamClass))
#define EXAMPLE_IS_CALL_STREAM(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXAMPLE_TYPE_CALL_STREAM))
#define EXAMPLE_IS_CALL_STREAM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), EXAMPLE_TYPE_CALL_STREAM))
#define EXAMPLE_CALL_STREAM_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CALL_STREAM, \
ExampleCallStreamClass))
struct _ExampleCallStreamClass {
TpBaseMediaCallStreamClass parent_class;
ExampleCallStreamClassPrivate *priv;
};
struct _ExampleCallStream {
TpBaseMediaCallStream parent;
ExampleCallStreamPrivate *priv;
};
void example_call_stream_accept_proposed_direction (ExampleCallStream *self);
void example_call_stream_connect (ExampleCallStream *self);
/* This controls receiving emulated network events, so it wouldn't exist in
* a real connection manager */
void example_call_stream_simulate_contact_agreed_to_send (
ExampleCallStream *self);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/call/call-manager.c 0000664 0001750 0001750 00000035676 12470405660 021220 0 ustar jr jr /*
* call-manager.c - an example channel manager for Call channels.
*
* This channel manager emulates a protocol like XMPP Jingle, where you can
* make several simultaneous calls to the same or different contacts.
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "call-manager.h"
#include
#include
#include
#include
#include
#include
#include "call-channel.h"
static void channel_manager_iface_init (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (ExampleCallManager,
example_call_manager,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
channel_manager_iface_init))
/* type definition stuff */
enum
{
PROP_CONNECTION = 1,
PROP_SIMULATION_DELAY,
N_PROPS
};
struct _ExampleCallManagerPrivate
{
TpBaseConnection *conn;
guint simulation_delay;
/* Map from reffed ExampleCallChannel to the same pointer; used as a
* set.
*/
GHashTable *channels;
/* Next channel will be ("CallChannel%u", next_channel_index) */
guint next_channel_index;
gulong status_changed_id;
gulong available_id;
};
static void
example_call_manager_init (ExampleCallManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EXAMPLE_TYPE_CALL_MANAGER,
ExampleCallManagerPrivate);
self->priv->conn = NULL;
self->priv->channels = g_hash_table_new_full (NULL, NULL, g_object_unref,
NULL);
self->priv->status_changed_id = 0;
self->priv->available_id = 0;
}
static void
example_call_manager_close_all (ExampleCallManager *self)
{
if (self->priv->channels != NULL)
{
GHashTable *tmp = self->priv->channels;
GHashTableIter iter;
gpointer v;
self->priv->channels = NULL;
g_hash_table_iter_init (&iter, tmp);
while (g_hash_table_iter_next (&iter, NULL, &v))
tp_base_channel_close (v);
g_hash_table_unref (tmp);
}
if (self->priv->available_id != 0)
{
g_signal_handler_disconnect (self->priv->conn,
self->priv->available_id);
self->priv->available_id = 0;
}
if (self->priv->status_changed_id != 0)
{
g_signal_handler_disconnect (self->priv->conn,
self->priv->status_changed_id);
self->priv->status_changed_id = 0;
}
}
static void
dispose (GObject *object)
{
ExampleCallManager *self = EXAMPLE_CALL_MANAGER (object);
example_call_manager_close_all (self);
g_assert (self->priv->channels == NULL);
((GObjectClass *) example_call_manager_parent_class)->dispose (
object);
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ExampleCallManager *self = EXAMPLE_CALL_MANAGER (object);
switch (property_id)
{
case PROP_CONNECTION:
g_value_set_object (value, self->priv->conn);
break;
case PROP_SIMULATION_DELAY:
g_value_set_uint (value, self->priv->simulation_delay);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ExampleCallManager *self = EXAMPLE_CALL_MANAGER (object);
switch (property_id)
{
case PROP_CONNECTION:
/* We don't ref the connection, because it owns a reference to the
* channel manager, and it guarantees that the manager's lifetime is
* less than its lifetime */
self->priv->conn = g_value_get_object (value);
break;
case PROP_SIMULATION_DELAY:
self->priv->simulation_delay = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
status_changed_cb (TpBaseConnection *conn,
guint status,
guint reason,
ExampleCallManager *self)
{
switch (status)
{
case TP_CONNECTION_STATUS_DISCONNECTED:
{
example_call_manager_close_all (self);
}
break;
default:
break;
}
}
static ExampleCallChannel *new_channel (ExampleCallManager *self,
TpHandle handle, TpHandle initiator, gpointer request_token,
gboolean initial_audio, gboolean initial_video);
static gboolean
simulate_incoming_call_cb (gpointer p)
{
ExampleCallManager *self = p;
TpHandleRepoIface *contact_repo;
TpHandle caller;
/* do nothing if we've been disconnected while waiting for the contact to
* call us */
if (self->priv->available_id == 0)
return FALSE;
/* We're called by someone whose ID on the IM service is "caller" */
contact_repo = tp_base_connection_get_handles (self->priv->conn,
TP_HANDLE_TYPE_CONTACT);
caller = tp_handle_ensure (contact_repo, "caller", NULL, NULL);
new_channel (self, caller, caller, NULL, TRUE, FALSE);
return FALSE;
}
/* Whenever our presence changes from away to available, and whenever our
* presence message changes while remaining available, simulate a call from
* a contact */
static void
available_cb (GObject *conn G_GNUC_UNUSED,
const gchar *message,
ExampleCallManager *self)
{
g_timeout_add_full (G_PRIORITY_DEFAULT, self->priv->simulation_delay,
simulate_incoming_call_cb, g_object_ref (self), g_object_unref);
}
static void
constructed (GObject *object)
{
ExampleCallManager *self = EXAMPLE_CALL_MANAGER (object);
void (*chain_up) (GObject *) =
((GObjectClass *) example_call_manager_parent_class)->constructed;
if (chain_up != NULL)
{
chain_up (object);
}
self->priv->status_changed_id = g_signal_connect (self->priv->conn,
"status-changed", (GCallback) status_changed_cb, self);
self->priv->available_id = g_signal_connect (self->priv->conn,
"available", (GCallback) available_cb, self);
}
static void
example_call_manager_class_init (ExampleCallManagerClass *klass)
{
GParamSpec *param_spec;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
param_spec = g_param_spec_object ("connection", "Connection object",
"The connection that owns this channel manager",
TP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_uint ("simulation-delay", "Simulation delay",
"Delay between simulated network events",
0, G_MAXUINT32, 1000,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SIMULATION_DELAY,
param_spec);
g_type_class_add_private (klass,
sizeof (ExampleCallManagerPrivate));
}
static void
example_call_manager_foreach_channel (TpChannelManager *iface,
TpExportableChannelFunc callback,
gpointer user_data)
{
ExampleCallManager *self = EXAMPLE_CALL_MANAGER (iface);
GHashTableIter iter;
gpointer chan;
g_hash_table_iter_init (&iter, self->priv->channels);
while (g_hash_table_iter_next (&iter, &chan, NULL))
callback (chan, user_data);
}
static void
channel_closed_cb (ExampleCallChannel *chan,
ExampleCallManager *self)
{
tp_channel_manager_emit_channel_closed_for_object (self,
TP_EXPORTABLE_CHANNEL (chan));
if (self->priv->channels != NULL)
g_hash_table_remove (self->priv->channels, chan);
}
static ExampleCallChannel *
new_channel (ExampleCallManager *self,
TpHandle handle,
TpHandle initiator,
gpointer request_token,
gboolean initial_audio,
gboolean initial_video)
{
ExampleCallChannel *chan;
gchar *object_path;
GSList *requests = NULL;
/* FIXME: This could potentially wrap around, but only after 4 billion
* calls, which is probably plenty. */
object_path = g_strdup_printf ("%s/CallChannel%u",
self->priv->conn->object_path, self->priv->next_channel_index++);
chan = g_object_new (EXAMPLE_TYPE_CALL_CHANNEL,
"connection", self->priv->conn,
"object-path", object_path,
"handle", handle,
"initiator-handle", initiator,
"requested", (self->priv->conn->self_handle == initiator),
"simulation-delay", self->priv->simulation_delay,
"initial-audio", initial_audio,
"initial-video", initial_video,
"mutable-contents", TRUE,
NULL);
g_free (object_path);
g_signal_connect (chan, "closed", G_CALLBACK (channel_closed_cb), self);
g_hash_table_insert (self->priv->channels, chan, chan);
if (request_token != NULL)
requests = g_slist_prepend (requests, request_token);
tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan),
requests);
g_slist_free (requests);
return chan;
}
static const gchar * const audio_fixed_properties[] = {
TP_PROP_CHANNEL_CHANNEL_TYPE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO,
NULL
};
static const gchar * const video_fixed_properties[] = {
TP_PROP_CHANNEL_CHANNEL_TYPE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO,
NULL
};
static const gchar * const audio_allowed_properties[] = {
TP_PROP_CHANNEL_TARGET_HANDLE,
TP_PROP_CHANNEL_TARGET_ID,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO,
NULL
};
static const gchar * const video_allowed_properties[] = {
TP_PROP_CHANNEL_TARGET_HANDLE,
TP_PROP_CHANNEL_TARGET_ID,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO,
NULL
};
static void
example_call_manager_type_foreach_channel_class (GType type,
TpChannelManagerTypeChannelClassFunc func,
gpointer user_data)
{
GHashTable *table = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE,
G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_CALL,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, G_TYPE_BOOLEAN, TRUE,
NULL);
func (type, table, audio_allowed_properties, user_data);
g_hash_table_remove (table, TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO);
tp_asv_set_boolean (table, TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO,
TRUE);
func (type, table, video_allowed_properties, user_data);
g_hash_table_unref (table);
}
static gboolean
example_call_manager_request (ExampleCallManager *self,
gpointer request_token,
GHashTable *request_properties,
gboolean require_new)
{
TpHandle handle;
GError *error = NULL;
gboolean initial_audio, initial_video;
if (tp_strdiff (tp_asv_get_string (request_properties,
TP_PROP_CHANNEL_CHANNEL_TYPE),
TP_IFACE_CHANNEL_TYPE_CALL))
{
return FALSE;
}
if (tp_asv_get_uint32 (request_properties,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_CONTACT)
{
return FALSE;
}
handle = tp_asv_get_uint32 (request_properties,
TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
g_assert (handle != 0);
initial_audio = tp_asv_get_boolean (request_properties,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL);
initial_video = tp_asv_get_boolean (request_properties,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, NULL);
if (!initial_audio && !initial_video)
{
g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
"Call channels must initially have either audio or video content");
goto error;
}
/* the set of (fixed | allowed) properties is the same for audio and video,
* so we only need to check with one set */
if (tp_channel_manager_asv_has_unknown_properties (request_properties,
audio_fixed_properties, audio_allowed_properties, &error))
{
goto error;
}
if (handle == self->priv->conn->self_handle)
{
/* In protocols with a concept of multiple "resources" signed in to
* one account (XMPP, and possibly MSN) it is technically possible to
* call yourself - e.g. if you're signed in on two PCs, you can call one
* from the other. For simplicity, this example simulates a protocol
* where this is not the case.
*/
g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
"In this protocol, you can't call yourself");
goto error;
}
if (!require_new)
{
/* see if we're already calling that handle */
GHashTableIter iter;
gpointer chan;
g_hash_table_iter_init (&iter, self->priv->channels);
while (g_hash_table_iter_next (&iter, &chan, NULL))
{
guint its_handle;
g_object_get (chan,
"handle", &its_handle,
NULL);
if (its_handle == handle)
{
tp_channel_manager_emit_request_already_satisfied (self,
request_token, TP_EXPORTABLE_CHANNEL (chan));
return TRUE;
}
}
}
new_channel (self, handle, self->priv->conn->self_handle, request_token,
initial_audio, initial_video);
return TRUE;
error:
tp_channel_manager_emit_request_failed (self, request_token,
error->domain, error->code, error->message);
g_error_free (error);
return TRUE;
}
static gboolean
example_call_manager_create_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
return example_call_manager_request (
EXAMPLE_CALL_MANAGER (manager),
request_token, request_properties, TRUE);
}
static gboolean
example_call_manager_ensure_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
return example_call_manager_request (
EXAMPLE_CALL_MANAGER (manager),
request_token, request_properties, FALSE);
}
static void
channel_manager_iface_init (gpointer g_iface,
gpointer iface_data G_GNUC_UNUSED)
{
TpChannelManagerIface *iface = g_iface;
iface->foreach_channel = example_call_manager_foreach_channel;
iface->type_foreach_channel_class =
example_call_manager_type_foreach_channel_class;
iface->create_channel = example_call_manager_create_channel;
iface->ensure_channel = example_call_manager_ensure_channel;
/* In this channel manager, RequestChannel is not supported; Call is not
* designed to work with the old RequestChannel API. */
iface->request_channel = NULL;
}
telepathy-qt-0.9.6~git1/tests/lib/glib/call/conn.h 0000664 0001750 0001750 00000005122 12470405660 017616 0 ustar jr jr /*
* conn.h - header for an example connection
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 Nokia Corporation
*
* 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.
*/
#ifndef EXAMPLE_CALL_CONN_H
#define EXAMPLE_CALL_CONN_H
#include
#include
#include
#include
G_BEGIN_DECLS
typedef struct _ExampleCallConnection ExampleCallConnection;
typedef struct _ExampleCallConnectionPrivate
ExampleCallConnectionPrivate;
typedef struct _ExampleCallConnectionClass ExampleCallConnectionClass;
typedef struct _ExampleCallConnectionClassPrivate
ExampleCallConnectionClassPrivate;
struct _ExampleCallConnectionClass {
TpBaseConnectionClass parent_class;
TpPresenceMixinClass presence_mixin;
TpContactsMixinClass contacts_mixin;
ExampleCallConnectionClassPrivate *priv;
};
struct _ExampleCallConnection {
TpBaseConnection parent;
TpPresenceMixin presence_mixin;
TpContactsMixin contacts_mixin;
ExampleCallConnectionPrivate *priv;
};
GType example_call_connection_get_type (void);
#define EXAMPLE_TYPE_CALL_CONNECTION \
(example_call_connection_get_type ())
#define EXAMPLE_CALL_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_CALL_CONNECTION, \
ExampleCallConnection))
#define EXAMPLE_CALL_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_CALL_CONNECTION, \
ExampleCallConnectionClass))
#define EXAMPLE_IS_CALL_CONNECTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_CALL_CONNECTION))
#define EXAMPLE_IS_CALL_CONNECTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_CALL_CONNECTION))
#define EXAMPLE_CALL_CONNECTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CALL_CONNECTION, \
ExampleCallConnectionClass))
/* Must be kept in sync with the array presence_statuses in conn.c */
typedef enum {
EXAMPLE_CALL_PRESENCE_OFFLINE = 0,
EXAMPLE_CALL_PRESENCE_UNKNOWN,
EXAMPLE_CALL_PRESENCE_ERROR,
EXAMPLE_CALL_PRESENCE_AWAY,
EXAMPLE_CALL_PRESENCE_AVAILABLE
} ExampleCallPresence;
gchar *example_call_normalize_contact (TpHandleRepoIface *repo,
const gchar *id, gpointer context, GError **error);
const gchar * const *example_call_connection_get_possible_interfaces (void);
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/call/CMakeLists.txt 0000664 0001750 0001750 00000000747 12470405660 021260 0 ustar jr jr if(ENABLE_TP_GLIB_TESTS)
set(example_cm_call_SRCS
call-channel.c
call-channel.h
call-content.c
call-content.h
call-manager.c
call-manager.h
call-stream.c
call-stream.h
cm.c
cm.h
conn.c
conn.h
protocol.c
protocol.h)
add_library(example-cm-call STATIC ${example_cm_call_SRCS})
target_link_libraries(example-cm-call ${TPGLIB_LIBRARIES})
endif(ENABLE_TP_GLIB_TESTS)
telepathy-qt-0.9.6~git1/tests/lib/glib/call/call-manager.h 0000664 0001750 0001750 00000004501 12470405660 021204 0 ustar jr jr /*
* media-manager.h - header for an example channel manager
*
* Copyright © 2007-2009 Collabora Ltd.
* Copyright © 2007-2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EXAMPLE_CALL_MANAGER_H
#define EXAMPLE_CALL_MANAGER_H
#include
G_BEGIN_DECLS
typedef struct _ExampleCallManager ExampleCallManager;
typedef struct _ExampleCallManagerPrivate
ExampleCallManagerPrivate;
typedef struct _ExampleCallManagerClass
ExampleCallManagerClass;
typedef struct _ExampleCallManagerClassPrivate
ExampleCallManagerClassPrivate;
struct _ExampleCallManagerClass {
GObjectClass parent_class;
ExampleCallManagerClassPrivate *priv;
};
struct _ExampleCallManager {
GObject parent;
ExampleCallManagerPrivate *priv;
};
GType example_call_manager_get_type (void);
/* TYPE MACROS */
#define EXAMPLE_TYPE_CALL_MANAGER \
(example_call_manager_get_type ())
#define EXAMPLE_CALL_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EXAMPLE_TYPE_CALL_MANAGER, \
ExampleCallManager))
#define EXAMPLE_CALL_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), EXAMPLE_TYPE_CALL_MANAGER, \
ExampleCallManagerClass))
#define EXAMPLE_IS_CALL_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), EXAMPLE_TYPE_CALL_MANAGER))
#define EXAMPLE_IS_CALL_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), EXAMPLE_TYPE_CALL_MANAGER))
#define EXAMPLE_CALL_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), EXAMPLE_TYPE_CALL_MANAGER, \
ExampleCallManagerClass))
G_END_DECLS
#endif
telepathy-qt-0.9.6~git1/tests/lib/glib/call/call-channel.h 0000664 0001750 0001750 00000004367 12470405660 021214 0 ustar jr jr /*
* call-channel.h - header for an example channel
*
* Copyright © 2007-2009 Collabora Ltd.