diff --git a/libs/README.dbus b/libs/README.dbus new file mode 100644 index 0000000000000000000000000000000000000000..49a25b81efd9ea53eb510935a2c8b1c6a57288c9 --- /dev/null +++ b/libs/README.dbus @@ -0,0 +1,4 @@ +Fetched from (7 sept. 2007): + +svn --username guest --password guest --non-interactive co http://dev.openwengo.org/svn/openwengo/wengophone-ng/branches/wengophone-dbus-api/libs/dbus/ + diff --git a/libs/dbus/AUTHORS b/libs/dbus/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..d9c8833559ba2c6f650242249c6b4bb98138c7bd --- /dev/null +++ b/libs/dbus/AUTHORS @@ -0,0 +1 @@ +Paolo Durante <shackan@gmail.com> diff --git a/libs/dbus/COPYING b/libs/dbus/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..5ab7695ab8cabe0c5c8a814bb0ab1e8066578fbb --- /dev/null +++ b/libs/dbus/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libs/dbus/ChangeLog b/libs/dbus/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libs/dbus/INSTALL b/libs/dbus/INSTALL new file mode 100644 index 0000000000000000000000000000000000000000..23e5f25d0e5f85798dcfb368ecb2f04f59777f61 --- /dev/null +++ b/libs/dbus/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/libs/dbus/Makefile.am b/libs/dbus/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..29bb7c9bb72b0e73a77594019c38280345c20cf2 --- /dev/null +++ b/libs/dbus/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = src tools data doc examples + +EXTRA_DIST = autogen.sh libdbus-c++.spec libdbus-c++.spec.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = dbus-c++-1.pc + +MAINTAINERCLEANFILES = \ + configure \ + Makefile.in \ + aclocal.m4 \ + compile \ + config.guess \ + config.sub \ + depcomp \ + install-sh \ + ltmain.sh \ + mdate-sh \ + missing \ + mkinstalldirs \ + libdbus-c++.spec + diff --git a/libs/dbus/NEWS b/libs/dbus/NEWS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libs/dbus/README b/libs/dbus/README new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libs/dbus/SConscript b/libs/dbus/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..d7b235898951800d2de2cb1470266aa63daad1df --- /dev/null +++ b/libs/dbus/SConscript @@ -0,0 +1,85 @@ +# +# library +# + +env = WengoGetEnvironment() + +env.ParseConfig('pkg-config --cflags --libs dbus-1') + +libs = [ + 'expat' +] +lib_path = [] +include_path = [ + 'include' +] +defines = { + 'DBUS_API_SUBJECT_TO_CHANGE':1, + 'DEBUG':1 +} +headers = [] +sources = [ + 'src/connection.cpp', + 'src/debug.cpp', + 'src/dispatcher.cpp', + 'src/error.cpp', + 'src/eventloop.cpp', + 'src/interface.cpp', + 'src/introspection.cpp', + 'src/property.cpp', + 'src/message.cpp', + 'src/object.cpp', + 'src/pendingcall.cpp', + 'src/server.cpp', + 'src/types.cpp', + 'src/xml.cpp' +] + +env.WengoAddDefines(defines) +env.WengoAddIncludePath(include_path) +env.WengoUseLibraries(libs) +env.WengoStaticLibrary('dbus-c++', sources) + +# +# tools +# + +tools_env = WengoGetEnvironment() + +tools_libs = [ + 'dbus-c++' +] +tools_defines = { + 'DBUS_API_SUBJECT_TO_CHANGE':1, +} +introspect_sources = [ + 'tools/introspect.cpp', +] + +xml2cpp_sources = [ + 'tools/xml2cpp.cpp' +] + +#tools_env.Append(LINKFLAGS = '-z origin') +#tools_env.Append(RPATH = env.Literal('\\$$ORIGIN\.')) + +tools_env.WengoAddDefines(tools_defines) +tools_env.WengoAddIncludePath(include_path) +tools_env.WengoUseLibraries(tools_libs) + +dbusxx_introspect = tools_env.WengoProgram('dbusxx-introspect', introspect_sources) +dbusxx_xml2cpp = tools_env.WengoProgram('dbusxx-xml2cpp', xml2cpp_sources) + +# +# xml translator +# + +def dbusxx_xml2cpp_emitter(target, source, env): + env.Depends(target, dbusxx_xml2cpp) + return (target, source) + +dbusxx_xml2cpp_builder = Builder(action = dbusxx_xml2cpp[0].abspath + ' $SOURCE --adaptor=$TARGET', + emitter = dbusxx_xml2cpp_emitter, + suffix = '.h', src_suffix = '.xml') + +Export('dbusxx_xml2cpp_builder') diff --git a/libs/dbus/TODO b/libs/dbus/TODO new file mode 100644 index 0000000000000000000000000000000000000000..f975a80a45241239e7a50bbb859bdc26de54d1c2 --- /dev/null +++ b/libs/dbus/TODO @@ -0,0 +1,8 @@ +* Implement asynchronous method calls (hint: start from DBus::PendingCall) +* ...and patch the codegen to generate stubs for them +* Implement continuations in a saner way +* Find time for some hardcore valgrinding +* Make DBus::Server free an incoming connection when it's disconnected, not when freeing the server +* More examples +* Inline (Doxygen-style) documentation +* Native protocol implementation (as an alternative to libdbus) diff --git a/libs/dbus/autogen.sh b/libs/dbus/autogen.sh new file mode 100755 index 0000000000000000000000000000000000000000..4af86e25d4b4dde140668ab04805c9f0c3a8018e --- /dev/null +++ b/libs/dbus/autogen.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +function autocmd() +{ + echo "Running ${1}..." + $* || { + echo "Error running ${1}" + exit 1 + } +} + +autocmd libtoolize --force --copy +autocmd aclocal +autocmd autoheader +autocmd automake --add-missing --force-missing --copy -Wall +autocmd autoconf + +echo "Autogen done, now you can ./configure" diff --git a/libs/dbus/configure.ac b/libs/dbus/configure.ac new file mode 100644 index 0000000000000000000000000000000000000000..230564bc25e37e7fc811773930701c0ab7ac18c2 --- /dev/null +++ b/libs/dbus/configure.ac @@ -0,0 +1,193 @@ +# Autojunk script for libdbus-c++ + +AC_PREREQ(2.59) +AC_INIT([libdbus-c++], 0.5.0, [shackan@gmail.com]) + +AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) +AM_CONFIG_HEADER([include/dbus-c++/config.h]) + +AC_CANONICAL_HOST + +AC_SUBST(PACKAGE_VERSION) + + +# Set configuration options + +AC_ARG_ENABLE(debug, + AS_HELP_STRING([--enable-debug], + [enable debugging support]), + [enable_debug=$enableval], + [enable_debug=no] +) + +AC_ARG_ENABLE(glib, + AS_HELP_STRING([--enable-glib], + [enable glib integration]), + [enable_glib=$enableval], + [enable_glib=no] +) + +AC_ARG_ENABLE(doxygen-docs, + AS_HELP_STRING([--enable-doxygen-docs], + [build DOXYGEN documentation (requires Doxygen)]), + [enable_doxygen_docs=$enableval], + [enable_doxygen_docs=no] +) + +# Check for programs + +AC_LANG_CPLUSPLUS + +AC_PROG_CC +AC_PROG_CXX + +CXX_FOR_BUILD=${CXX_FOR_BUILD-${CXX}} +AC_SUBST(CXX_FOR_BUILD) + +AM_PROG_LIBTOOL + +PKG_PROG_PKG_CONFIG + + +AC_MSG_CHECKING([whether $CXX supports symbol visibility]) + +vtest=`$CXX --help --verbose 2>&1 | grep fvisibility` + +if test -n "$vtest"; then + AC_MSG_RESULT(yes) + + AC_DEFINE(GCC_HASCLASSVISIBILITY, 1, [to enable hidden symbols]) + CXXFLAGS="-fvisibility=hidden" +else + AC_MSG_RESULT(no) +fi + + +# Check for dependencies + +DBUS_REQUIRED_VERSION=0.60 +PKG_CHECK_MODULES(dbus, [dbus-1 >= $DBUS_REQUIRED_VERSION],, + AC_MSG_ERROR([You need the DBus libraries (version 0.6 or better)] + [http://www.freedesktop.org/wiki/Software_2fdbus]) +) +AC_SUBST(dbus_CFLAGS) +AC_SUBST(dbus_LIBS) + +DBUS_API_STABLE_VERSION=1.0.0 +PKG_CHECK_EXISTS([dbus-1 < $DBUS_API_STABLE_VERSION], + [AC_DEFINE(DBUS_API_SUBJECT_TO_CHANGE, , [unstable DBus])] +) + +DBUS_THREADS_INIT_DEFAULT_VERSION=0.93 +PKG_CHECK_EXISTS([dbus-1 >= $DBUS_THREADS_INIT_DEFAULT_VERSION], + [AC_DEFINE(DBUS_HAS_THREADS_INIT_DEFAULT, , [dbus_threads_init_default (needs DBus >= 0.93)])] +) + +DBUS_RECURSIVE_MUTEX_VERSION=0.95 +PKG_CHECK_EXISTS([dbus-1 >= $DBUS_RECURSIVE_MUTEX_VERSION], + [AC_DEFINE(DBUS_HAS_RECURSIVE_MUTEX, , [DBus supports recursive mutexes (needs DBus >= 0.95)])] +) + + +if test "$enable_glib" = "yes" ; then +PKG_CHECK_MODULES([glib], glib-2.0) +AC_SUBST(glib_CFLAGS) +AC_SUBST(glib_LIBS) +AM_CONDITIONAL(ENABLE_GLIB, test 1 = 1) +PKG_CHECK_MODULES([gtkmm], gtkmm-2.4, + AM_CONDITIONAL(HAVE_GTKMM, test 1 = 1), + AM_CONDITIONAL(HAVE_GTKMM, test 0 = 1) +) +AC_SUBST(gtkmm_CFLAGS) +AC_SUBST(gtkmm_LIBS) +else +AM_CONDITIONAL(ENABLE_GLIB, test 0 = 1) +AM_CONDITIONAL(HAVE_GTKMM, test 0 = 1) +fi + +AC_CHECK_LIB([expat], XML_ParserCreate_MM, + [AC_CHECK_HEADERS(expat.h, have_expat=true, have_expat=false)], + have_expat=false) + +if ! $have_expat; then + AC_MSG_ERROR([You need the eXpat xml parser] + [http://expat.sourceforge.net/]) +fi + +xml_CFLAGS= +xml_LIBS=-lexpat + +AC_SUBST(xml_CFLAGS) +AC_SUBST(xml_LIBS) + +AC_CHECK_LIB([pthread], pthread_create, + [AC_CHECK_HEADERS(pthread.h, have_pthread=true, have_pthread=false)], + have_pthread=false) + +AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "true") + +if test "$enable_debug" = "yes" ; then + CXXFLAGS="$CXXFLAGS -Wall -ggdb -O0 -DDEBUG" +else + CXXFLAGS="$CXXFLAGS -Wall -O3" +fi + + +# Doxygen Documentation + +AC_PATH_PROG(DOXYGEN, doxygen, no) + +AC_MSG_CHECKING([whether to build Doxygen documentation]) + +if test "$DOXYGEN" = "no" ; then + have_doxygen=no +else + have_doxygen=yes +fi + +if test "$enable_doxygen_docs" = "auto" ; then + enable_doxygen_docs=no + + AC_MSG_RESULT(no) +fi + +if test "$enable_doxygen_docs" = "yes" ; then + if test "$have_doxygen" = "no"; then + AC_MSG_ERROR([Building Doxygen docs explicitly required, but Doxygen not found]) + fi + + AC_MSG_RESULT(yes) +fi + +AM_CONDITIONAL(DBUS_DOXYGEN_DOCS_ENABLED, test "$enable_doxygen_docs" = "yes") + +# For the tools/, we need libdbus-c++ for the "build" architecture as well + +AM_CONDITIONAL(CROSS_COMPILING, test "$cross_compiling" = "yes") + +AC_ARG_WITH(build-libdbus-cxx, + AS_HELP_STRING([--with-build-libdbus-cxx], + [For cross compilation: path to libdbus-cxx which was compiled for the 'build' system.]), + [ BUILD_LIBDBUS_CXX_DIR=${withval} ], + [ BUILD_LIBDBUS_CXX_DIR="\$(top_builddir)" ] +) +AC_SUBST(BUILD_LIBDBUS_CXX_DIR) + + +# Save processed files + +AC_OUTPUT( + Makefile + src/Makefile + tools/Makefile + data/Makefile + doc/Makefile + doc/Doxyfile + examples/Makefile + examples/properties/Makefile + examples/echo/Makefile + examples/hal/Makefile + examples/glib/Makefile + dbus-c++-1.pc + libdbus-c++.spec +) diff --git a/libs/dbus/data/Makefile.am b/libs/dbus/data/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..23df86ec8db8fe4cc2cfd00328f5edc0d1097fae --- /dev/null +++ b/libs/dbus/data/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = org.freedesktop.DBus.xml + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/data/org.freedesktop.DBus.xml b/libs/dbus/data/org.freedesktop.DBus.xml new file mode 100644 index 0000000000000000000000000000000000000000..27afd0aa200085a6ec238252e755c146544cdad9 --- /dev/null +++ b/libs/dbus/data/org.freedesktop.DBus.xml @@ -0,0 +1,74 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.DBus.Introspectable"> + <method name="Introspect"> + <arg name="data" direction="out" type="s"/> + </method> + </interface> + <interface name="org.freedesktop.DBus"> + <method name="RequestName"> + <arg direction="in" type="s"/> + <arg direction="in" type="u"/> + <arg direction="out" type="u"/> + </method> + <method name="ReleaseName"> + <arg direction="in" type="s"/> + <arg direction="out" type="u"/> + </method> + <method name="StartServiceByName"> + <arg direction="in" type="s"/> + <arg direction="in" type="u"/> + <arg direction="out" type="u"/> + </method> + <method name="Hello"> + <arg direction="out" type="s"/> + </method> + <method name="NameHasOwner"> + <arg direction="in" type="s"/> + <arg direction="out" type="b"/> + </method> + <method name="ListNames"> + <arg direction="out" type="as"/> + </method> + <method name="AddMatch"> + <arg direction="in" type="s"/> + </method> + <method name="RemoveMatch"> + <arg direction="in" type="s"/> + </method> + <method name="GetNameOwner"> + <arg direction="in" type="s"/> + <arg direction="out" type="s"/> + </method> + <method name="ListQueuedOwners"> + <arg direction="in" type="s"/> + <arg direction="out" type="as"/> + </method> + <method name="GetConnectionUnixUser"> + <arg direction="in" type="s"/> + <arg direction="out" type="u"/> + </method> + <method name="GetConnectionUnixProcessID"> + <arg direction="in" type="s"/> + <arg direction="out" type="u"/> + </method> + <method name="GetConnectionSELinuxSecurityContext"> + <arg direction="in" type="s"/> + <arg direction="out" type="ay"/> + </method> + <method name="ReloadConfig"> + </method> + <signal name="NameOwnerChanged"> + <arg type="s"/> + <arg type="s"/> + <arg type="s"/> + </signal> + <signal name="NameLost"> + <arg type="s"/> + </signal> + <signal name="NameAcquired"> + <arg type="s"/> + </signal> + </interface> +</node> diff --git a/libs/dbus/dbus-c++-1.pc.in b/libs/dbus/dbus-c++-1.pc.in new file mode 100644 index 0000000000000000000000000000000000000000..bc5860a95594e9bd30af8687b7c1e162f6fd79bb --- /dev/null +++ b/libs/dbus/dbus-c++-1.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: dbus-c++ +Description: Native C++ bindings for D-Bus. +Requires: dbus-1 +Version: @VERSION@ +Libs: -L${libdir} -ldbus-c++-1 +Cflags: -I${includedir}/dbus-c++-1 -DDBUS_API_SUBJECT_TO_CHANGE diff --git a/libs/dbus/doc/Doxyfile.in b/libs/dbus/doc/Doxyfile.in new file mode 100644 index 0000000000000000000000000000000000000000..a2b3d4415fe2026b0f0e520d88934377bda6ff9a --- /dev/null +++ b/libs/dbus/doc/Doxyfile.in @@ -0,0 +1,251 @@ +# Doxyfile 1.4.6 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = @PACKAGE@ +PROJECT_NUMBER = @VERSION@ +OUTPUT_DIRECTORY = @top_srcdir@/doc/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = YES +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @top_srcdir@/src/ @top_srcdir@/include/ +FILE_PATTERNS = *.cpp \ + *.h +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = Makefile.* \ + ChangeLog \ + CHANGES \ + CHANGES.* \ + README \ + README.* \ + *.png \ + AUTHORS \ + DESIGN \ + DESIGN.* \ + *.desktop \ + DESKTOP* \ + COMMENTS \ + HOWTO \ + magic \ + NOTES \ + TODO \ + THANKS +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 640 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/libs/dbus/doc/Makefile.am b/libs/dbus/doc/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..39fd9b9deb140ecfadc9dde627dc835de95fb335 --- /dev/null +++ b/libs/dbus/doc/Makefile.am @@ -0,0 +1,15 @@ +if DBUS_DOXYGEN_DOCS_ENABLED + +EXTRA_DIST = Doxyfile.in + +noinst_PROGRAMS = index.html + +index_html_SOURCES = Doxyfile + +index.html: Doxyfile + doxygen Doxyfile + +endif + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/doc/html/Makefile.am b/libs/dbus/doc/html/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..8eb67f86574b1821e66ddf261e6c7de2eaa46546 --- /dev/null +++ b/libs/dbus/doc/html/Makefile.am @@ -0,0 +1,4 @@ +CLEANFILES = *.html *.css *.png *.gif + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/examples/Makefile.am b/libs/dbus/examples/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..b346604bad07e6aabfc20c1e3a581325446085f1 --- /dev/null +++ b/libs/dbus/examples/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = properties echo hal glib + +MAINTAINERCLEANFILES = \ + Makefile.in + diff --git a/libs/dbus/examples/echo/Makefile.am b/libs/dbus/examples/echo/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..d3d8e56c99292e6b84bbfd690babe9f705aa59db --- /dev/null +++ b/libs/dbus/examples/echo/Makefile.am @@ -0,0 +1,30 @@ +EXTRA_DIST = README echo-introspect.xml + +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_PROGRAMS = echo-server + +echo_server_SOURCES = echo-server-glue.h echo-server.h echo-server.cpp +echo_server_LDADD = $(top_builddir)/src/libdbus-c++-1.la + +echo-server-glue.h: echo-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --adaptor=$@ + +if HAVE_PTHREAD +noinst_PROGRAMS += echo-client-mt +endif + +echo_client_mt_SOURCES = echo-client-glue.h echo-client.h echo-client.cpp +echo_client_mt_LDADD = $(top_builddir)/src/libdbus-c++-1.la -lpthread + +echo-client-glue.h: echo-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --proxy=$@ + +BUILT_SOURCES = echo-server-glue.h echo-client-glue.h +CLEANFILES = $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/examples/echo/README b/libs/dbus/examples/echo/README new file mode 100644 index 0000000000000000000000000000000000000000..74e1d6d16c59858237e98e5186000951397d95d5 --- /dev/null +++ b/libs/dbus/examples/echo/README @@ -0,0 +1,23 @@ +This is probably the most simple D-Bus program you could conceive + +To test, run `DBUSXX_VERBOSE=1 ./echo-server` and try the following commands: + +dbus-send --dest=org.freedesktop.DBus.Examples.Echo --type=method_call --print-reply /org/freedesktop/DBus/Examples/Echo org.freedesktop.DBus.EchoDemo.Random + +dbus-send --dest=org.freedesktop.DBus.Examples.Echo --type=method_call --print-reply /org/freedesktop/DBus/Examples/Echo org.freedesktop.DBus.EchoDemo.Hello string:"world" + +dbus-send --dest=org.freedesktop.DBus.Examples.Echo --type=method_call --print-reply /org/freedesktop/DBus/Examples/Echo org.freedesktop.DBus.EchoDemo.Sum array:int32:10,100,250 + +dbus-send --dest=org.freedesktop.DBus.Examples.Echo --type=method_call --print-reply /org/freedesktop/DBus/Examples/Echo org.freedesktop.DBus.EchoDemo.Info + +or, using python instead + +$ python +import dbus +bus = dbus.SessionBus() +object = bus.get_object('org.freedesktop.DBus.Examples.Echo','/org/freedesktop/DBus/Examples/Echo') +echo = dbus.Interface(object, dbus_interface='org.freedesktop.DBus.EchoDemo') +echo.Random() +echo.Hello("world") +echo.Sum([123, 234, 95, 520]) +echo.Info() diff --git a/libs/dbus/examples/echo/echo-client.cpp b/libs/dbus/examples/echo/echo-client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11553659326c6ba466fa90fd6108e75886fb20b6 --- /dev/null +++ b/libs/dbus/examples/echo/echo-client.cpp @@ -0,0 +1,94 @@ +#include "echo-client.h" +#include <iostream> +#include <pthread.h> +#include <signal.h> + +#ifdef HAVE_CONFIG_H +#include <dbus-c++/config.h> +#endif + +using namespace std; + +static const char* ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo"; +static const char* ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; + +EchoClient::EchoClient( DBus::Connection& connection, const char* path, const char* name ) +: DBus::ObjectProxy(connection, path, name) +{ +} + +void EchoClient::Echoed( const DBus::Variant& value ) +{ + cout << "!"; +} + +/* + * For some strange reason, libdbus frequently dies with an OOM + */ + +static const int THREADS = 16; + +static bool spin = true; + +void* greeter_thread( void* arg ) +{ + DBus::Connection* conn = reinterpret_cast<DBus::Connection*>(arg); + + EchoClient client(*conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); + + char idstr[16]; + + snprintf(idstr, sizeof(idstr), "%lu", pthread_self()); + + for(int i = 0; i < 100 && spin; ++i) + { + cout << client.Hello(idstr) << endl; + } + + cout << idstr << " done " << endl; + + return NULL; +} + +DBus::BusDispatcher dispatcher; + +void niam( int sig ) +{ + spin = false; + + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + +#ifdef DBUS_HAS_THREADS_INIT_DEFAULT + DBus::_init_threading(); +#else + cerr << "Thread support is not enabled! your D-Bus version is too old" << endl; +#endif + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + + pthread_t threads[THREADS]; + + for(int i = 0; i < THREADS; ++i) + { + pthread_create(threads+i, NULL, greeter_thread, &conn); + } + + dispatcher.enter(); + + cout << "terminating" << endl; + + for(int i = 0; i < THREADS; ++i) + { + pthread_join(threads[i], NULL); + } + + return 0; +} diff --git a/libs/dbus/examples/echo/echo-client.h b/libs/dbus/examples/echo/echo-client.h new file mode 100644 index 0000000000000000000000000000000000000000..0f88e8005f5556fd5dcc1197332a72b865c65aa5 --- /dev/null +++ b/libs/dbus/examples/echo/echo-client.h @@ -0,0 +1,19 @@ +#ifndef __DEMO_ECHO_CLIENT_H +#define __DEMO_ECHO_CLIENT_H + +#include <dbus-c++/dbus.h> +#include "echo-client-glue.h" + +class EchoClient +: public org::freedesktop::DBus::EchoDemo, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy +{ +public: + + EchoClient( DBus::Connection& connection, const char* path, const char* name ); + + void Echoed( const DBus::Variant& value ); +}; + +#endif//__DEMO_ECHO_CLIENT_H diff --git a/libs/dbus/examples/echo/echo-introspect.xml b/libs/dbus/examples/echo/echo-introspect.xml new file mode 100644 index 0000000000000000000000000000000000000000..7d415abdd4c17c9bd653bb9d619fc9dff22f5264 --- /dev/null +++ b/libs/dbus/examples/echo/echo-introspect.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" ?> +<node name="/org/freedesktop/DBus/Examples/Echo"> + <interface name="org.freedesktop.DBus.EchoDemo"> + <method name="Random"> + <arg type="i" name="version" direction="out"/> + </method> + <method name="Hello"> + <arg type="s" name="name" direction="in"/> + <arg type="s" name="greeting" direction="out"/> + </method> + <method name="Echo"> + <arg type="v" name="input" direction="in"/> + <arg type="v" name="output" direction="out"/> + </method> + <method name="Cat"> + <arg type="s" name="file" direction="in"/> + <arg type="ay" name="stream" direction="out"/> + </method> + <method name="Sum"> + <arg type="ai" name="ints" direction="in"/> + <arg type="i" names="sum" direction="out"/> + </method> + <signal name="Echoed"> + <arg type="v" name="value"/> + </signal> + <method name="Info"> + <arg type="a{ss}" name="info" direction="out"/> + </method> + </interface> +</node> diff --git a/libs/dbus/examples/echo/echo-server.cpp b/libs/dbus/examples/echo/echo-server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..251e1a20b23819d38f0cf658928e808cbb4258c3 --- /dev/null +++ b/libs/dbus/examples/echo/echo-server.cpp @@ -0,0 +1,91 @@ +#include "echo-server.h" +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <stdio.h> + +static const char* ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo"; +static const char* ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; + +EchoServer::EchoServer( DBus::Connection& connection ) +: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH) +{ +} + +DBus::Int32 EchoServer::Random() +{ + return rand(); +} + +DBus::String EchoServer::Hello( const DBus::String& name ) +{ + return "Hello " + name + "!"; +} + +DBus::Variant EchoServer::Echo( const DBus::Variant& value ) +{ + this->Echoed(value); + + return value; +} + +std::vector< DBus::Byte > EchoServer::Cat( const DBus::String & file ) +{ + FILE* handle = fopen(file.c_str(), "rb"); + + if(!handle) throw DBus::Error("org.freedesktop.DBus.EchoDemo.ErrorFileNotFound", "file not found"); + + DBus::Byte buff[1024]; + + size_t nread = fread(buff, 1, sizeof(buff), handle); + + fclose(handle); + + return std::vector< DBus::Byte > (buff, buff + nread); +} + +DBus::Int32 EchoServer::Sum( const std::vector<DBus::Int32>& ints ) +{ + DBus::Int32 sum = 0; + + for(size_t i = 0; i < ints.size(); ++i) sum += ints[i]; + + return sum; +} + +std::map< DBus::String, DBus::String > EchoServer::Info() +{ + std::map< DBus::String, DBus::String > info; + char hostname[HOST_NAME_MAX]; + + gethostname(hostname, sizeof(hostname)); + info["hostname"] = hostname; + info["username"] = getlogin(); + + return info; +} + + +DBus::BusDispatcher dispatcher; + +void niam( int sig ) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + conn.request_name(ECHO_SERVER_NAME); + + EchoServer server(conn); + + dispatcher.enter(); + + return 0; +} diff --git a/libs/dbus/examples/echo/echo-server.h b/libs/dbus/examples/echo/echo-server.h new file mode 100644 index 0000000000000000000000000000000000000000..989d84c9d632c22c09a97c3c6f45c558632ef9b8 --- /dev/null +++ b/libs/dbus/examples/echo/echo-server.h @@ -0,0 +1,29 @@ +#ifndef __DEMO_ECHO_SERVER_H +#define __DEMO_ECHO_SERVER_H + +#include <dbus-c++/dbus.h> +#include "echo-server-glue.h" + +class EchoServer +: public org::freedesktop::DBus::EchoDemo, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor +{ +public: + + EchoServer( DBus::Connection& connection ); + + DBus::Int32 Random(); + + DBus::String Hello( const DBus::String & name ); + + DBus::Variant Echo( const DBus::Variant & value ); + + std::vector< DBus::Byte > Cat( const DBus::String & file ); + + DBus::Int32 Sum( const std::vector<DBus::Int32> & ints ); + + std::map< DBus::String, DBus::String > Info(); +}; + +#endif//__DEMO_ECHO_SERVER_H diff --git a/libs/dbus/examples/glib/Makefile.am b/libs/dbus/examples/glib/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..849c46847775644ed92028048e8ee65b64dc6472 --- /dev/null +++ b/libs/dbus/examples/glib/Makefile.am @@ -0,0 +1,22 @@ +EXTRA_DIST = + +AM_CPPFLAGS = -I$(top_srcdir)/include $(gtkmm_CFLAGS) -I$(top_srcdir)/tools + +if HAVE_GTKMM +noinst_PROGRAMS = dbus-browser +endif + +dbus_browser_SOURCES = dbus-glue.h dbus-browser.h dbus-browser.cpp $(top_srcdir)/tools/xml.cpp +dbus_browser_LDADD = $(top_builddir)/src/libdbus-c++-1.la $(gtkmm_LIBS) + +dbus-glue.h: $(top_srcdir)/data/org.freedesktop.DBus.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --proxy=$@ + +BUILT_SOURCES = dbus-glue.h +CLEANFILES = $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/examples/glib/dbus-browser.cpp b/libs/dbus/examples/glib/dbus-browser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cd74d7084cf99be0c964d49a725cde45ccdf6c2b --- /dev/null +++ b/libs/dbus/examples/glib/dbus-browser.cpp @@ -0,0 +1,136 @@ +#include "dbus-browser.h" + +#include <xml.h> +#include <iostream> + +using namespace std; + +static const char* DBUS_SERVER_NAME = "org.freedesktop.DBus"; +static const char* DBUS_SERVER_PATH = "/org/freedesktop/DBus"; + +DBusBrowser::DBusBrowser( ::DBus::Connection& conn ) +: ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME) +{ + set_title("D-Bus Browser"); + set_border_width(5); + set_default_size(400, 500); + + typedef std::vector< ::DBus::String > Names; + + Names names = ListNames(); + + for(Names::iterator it = names.begin(); it != names.end(); ++it) + { + _cb_busnames.append_text(*it); + } + + _cb_busnames.signal_changed().connect( sigc::mem_fun(*this, &DBusBrowser::on_select_busname) ); + + _tm_inspect = Gtk::TreeStore::create(_records); + _tv_inspect.set_model(_tm_inspect); + _tv_inspect.append_column("Node", _records.name); + + _sc_tree.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + _sc_tree.add(_tv_inspect); + + _vbox.pack_start(_cb_busnames, Gtk::PACK_SHRINK); + _vbox.pack_start(_sc_tree); + + add(_vbox); + + show_all_children(); +} + +void DBusBrowser::NameOwnerChanged( + const ::DBus::String& name, const ::DBus::String& old_owner, const ::DBus::String& new_owner ) +{ + cout << name << ": " << old_owner << " -> " << new_owner << endl; +} + +void DBusBrowser::NameLost( const ::DBus::String& name ) +{ + cout << name << " lost" << endl; +} + +void DBusBrowser::NameAcquired( const ::DBus::String& name ) +{ + cout << name << " acquired" << endl; +} + +void DBusBrowser::on_select_busname() +{ + Glib::ustring busname = _cb_busnames.get_active_text(); + if(busname.empty()) return; + + _tm_inspect->clear(); + _inspect_append(NULL, "", busname); +} + +void DBusBrowser::_inspect_append( Gtk::TreeModel::Row* row, const std::string& buspath, const std::string& busname ) +{ + DBusInspector inspector(conn(), buspath.empty() ? "/" : buspath.c_str(), busname.c_str()); + + ::DBus::Xml::Document doc(inspector.Introspect()); + ::DBus::Xml::Node& root = *(doc.root); + + ::DBus::Xml::Nodes ifaces = root["interface"]; + + for(::DBus::Xml::Nodes::iterator ii = ifaces.begin(); ii != ifaces.end(); ++ii) + { + ::DBus::Xml::Node& iface = **ii; + + Gtk::TreeModel::Row i_row = row + ? *(_tm_inspect->append(row->children())) + : *(_tm_inspect->append()); + i_row[_records.name] = "interface: " + iface.get("name"); + + ::DBus::Xml::Nodes methods = iface["method"]; + + for(::DBus::Xml::Nodes::iterator im = methods.begin(); im != methods.end(); ++im) + { + Gtk::TreeModel::Row m_row = *(_tm_inspect->append(i_row.children())); + m_row[_records.name] = "method: " + (*im)->get("name"); + } + + ::DBus::Xml::Nodes signals = iface["signal"]; + + for(::DBus::Xml::Nodes::iterator is = signals.begin(); is != signals.end(); ++is) + { + Gtk::TreeModel::Row s_row = *(_tm_inspect->append(i_row.children())); + s_row[_records.name] = "signal: " + (*is)->get("name"); + } + } + + ::DBus::Xml::Nodes nodes = root["node"]; + + for(::DBus::Xml::Nodes::iterator in = nodes.begin(); in != nodes.end(); ++in) + { + std::string name = (*in)->get("name"); + + Gtk::TreeModel::Row n_row = row + ? *(_tm_inspect->append(row->children())) + : *(_tm_inspect->append()); + n_row[_records.name] = name; + + _inspect_append(&n_row, buspath + "/" + name, busname); + } +} + +DBus::Glib::BusDispatcher dispatcher; + +int main(int argc, char* argv[]) +{ + Gtk::Main kit(argc, argv); + + DBus::default_dispatcher = &dispatcher; + + dispatcher.attach(NULL); + + DBus::Connection conn = DBus::Connection::SessionBus(); + + DBusBrowser browser(conn); + + Gtk::Main::run(browser); + + return 0; +} diff --git a/libs/dbus/examples/glib/dbus-browser.h b/libs/dbus/examples/glib/dbus-browser.h new file mode 100644 index 0000000000000000000000000000000000000000..10c9b3d128cf7680f6a1235603c6c63005cb1891 --- /dev/null +++ b/libs/dbus/examples/glib/dbus-browser.h @@ -0,0 +1,62 @@ +#ifndef __DEMO_DBUS_BROWSER_H +#define __DEMO_DBUS_BROWSER_H + +#include <dbus-c++/dbus.h> +#include <dbus-c++/glib-integration.h> +#include <gtkmm.h> + +#include "dbus-glue.h" + +class DBusInspector +: public DBus::IntrospectableProxy, + public DBus::ObjectProxy +{ +public: + + DBusInspector( DBus::Connection& conn, const char* path, const char* service ) + : DBus::ObjectProxy(conn, path, service) + {} +}; + +class DBusBrowser +: public org::freedesktop::DBus, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy, + public Gtk::Window +{ +public: + + DBusBrowser( ::DBus::Connection& ); + +private: + + void NameOwnerChanged( const ::DBus::String&, const ::DBus::String&, const ::DBus::String& ); + + void NameLost( const ::DBus::String& ); + + void NameAcquired( const ::DBus::String& ); + + void on_select_busname(); + + void _inspect_append( Gtk::TreeModel::Row*, const std::string&, const std::string& ); + +private: + + class InspectRecord : public Gtk::TreeModel::ColumnRecord + { + public: + + InspectRecord() { add(name); } + + Gtk::TreeModelColumn<Glib::ustring> name; + }; + + Gtk::VBox _vbox; + Gtk::ScrolledWindow _sc_tree; + Gtk::ComboBoxText _cb_busnames; + Gtk::TreeView _tv_inspect; + Glib::RefPtr<Gtk::TreeStore> _tm_inspect; + InspectRecord _records; +}; + +#endif//__DEMO_DBUS_BROWSER_H diff --git a/libs/dbus/examples/hal/Makefile.am b/libs/dbus/examples/hal/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..ed3d5c504bb031f0df3f0fbfb5ff9d3f2bd931c1 --- /dev/null +++ b/libs/dbus/examples/hal/Makefile.am @@ -0,0 +1,9 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_PROGRAMS = hal-listen + +hal_listen_SOURCES = hal-listen.h hal-listen.cpp +hal_listen_LDADD = $(top_builddir)/src/libdbus-c++-1.la + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/examples/hal/hal-listen.cpp b/libs/dbus/examples/hal/hal-listen.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d36eb2ab843fc1d9605e03b0f1e60823df581ced --- /dev/null +++ b/libs/dbus/examples/hal/hal-listen.cpp @@ -0,0 +1,125 @@ +#include "hal-listen.h" + +#include <signal.h> +#include <iostream> + +HalManagerProxy::HalManagerProxy( DBus::Connection& connection ) +: DBus::InterfaceProxy("org.freedesktop.Hal.Manager"), + DBus::ObjectProxy(connection, "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal") +{ + connect_signal(HalManagerProxy, DeviceAdded, DeviceAddedCb); + connect_signal(HalManagerProxy, DeviceRemoved, DeviceRemovedCb); + + std::vector< DBus::String > devices = GetAllDevices(); + + std::vector< DBus::String >::iterator it; + for(it = devices.begin(); it != devices.end(); ++it) + { + DBus::Path udi = *it; + + std::cout << "found device " << udi << std::endl; + + _devices[udi] = new HalDeviceProxy(connection, udi); + } +} + +std::vector< DBus::String > HalManagerProxy::GetAllDevices() +{ + std::vector< DBus::String > udis; + DBus::CallMessage call; + + call.member("GetAllDevices"); + + DBus::Message reply = invoke_method(call); + DBus::MessageIter it = reply.reader(); + + it >> udis; + return udis; +} + +void HalManagerProxy::DeviceAddedCb( const DBus::SignalMessage& sig ) +{ + DBus::MessageIter it = sig.reader(); + DBus::String devname; + + it >> devname; + + DBus::Path udi(devname); + + _devices[devname] = new HalDeviceProxy(conn(), udi); + std::cout << "added device " << udi << std::endl; +} + +void HalManagerProxy::DeviceRemovedCb( const DBus::SignalMessage& sig ) +{ + DBus::MessageIter it = sig.reader(); + DBus::String devname; + + it >> devname; + + std::cout << "removed device " << devname << std::endl; + + _devices.erase(devname); +} + +HalDeviceProxy::HalDeviceProxy( DBus::Connection& connection, DBus::Path& udi ) +: DBus::InterfaceProxy("org.freedesktop.Hal.Device"), + DBus::ObjectProxy(connection, udi, "org.freedesktop.Hal") +{ + connect_signal(HalDeviceProxy, PropertyModified, PropertyModifiedCb); + connect_signal(HalDeviceProxy, Condition, ConditionCb); +} + +void HalDeviceProxy::PropertyModifiedCb( const DBus::SignalMessage& sig ) +{ + typedef DBus::Struct< DBus::String, DBus::Bool, DBus::Bool > HalProperty; + + DBus::MessageIter it = sig.reader(); + DBus::Int32 number; + + it >> number; + + DBus::MessageIter arr = it.recurse(); + + for(int i = 0; i < number; ++i, ++arr) + { + HalProperty hp; + + arr >> hp; + + std::cout << "modified property " << hp._1 << " in " << path() << std::endl; + } +} + +void HalDeviceProxy::ConditionCb( const DBus::SignalMessage& sig ) +{ + DBus::MessageIter it = sig.reader(); + DBus::String condition; + + it >> condition; + + std::cout << "encountered condition " << condition << " in " << path() << std::endl; +} + +DBus::BusDispatcher dispatcher; + +void niam( int sig ) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SystemBus(); + + HalManagerProxy hal(conn); + + dispatcher.enter(); + + return 0; +} diff --git a/libs/dbus/examples/hal/hal-listen.h b/libs/dbus/examples/hal/hal-listen.h new file mode 100644 index 0000000000000000000000000000000000000000..8401fbfad48e9838d50249a58acc9f61d3e9e6aa --- /dev/null +++ b/libs/dbus/examples/hal/hal-listen.h @@ -0,0 +1,44 @@ +#ifndef __DEMO_HAL_LISTEN_H +#define __DEMO_HAL_LISTEN_H + +#include <dbus-c++/dbus.h> +#include <vector> +#include <map> + +class HalDeviceProxy; + +class HalManagerProxy +: public DBus::InterfaceProxy, + public DBus::ObjectProxy +{ +public: + + HalManagerProxy( DBus::Connection& connection ); + + std::vector< DBus::String > GetAllDevices(); + +private: + + void DeviceAddedCb( const DBus::SignalMessage& sig ); + + void DeviceRemovedCb( const DBus::SignalMessage& sig ); + + std::map< DBus::String, DBus::RefPtr< HalDeviceProxy > > _devices; +}; + +class HalDeviceProxy +: public DBus::InterfaceProxy, + public DBus::ObjectProxy +{ +public: + + HalDeviceProxy( DBus::Connection& connection, DBus::Path& udi ); + +private: + + void PropertyModifiedCb( const DBus::SignalMessage& sig ); + + void ConditionCb( const DBus::SignalMessage& sig ); +}; + +#endif//__DEMO_HAL_LISTEN_H diff --git a/libs/dbus/examples/properties/Makefile.am b/libs/dbus/examples/properties/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..c0c9565b28b746655433eb2fa76b44ca7ba095af --- /dev/null +++ b/libs/dbus/examples/properties/Makefile.am @@ -0,0 +1,20 @@ +EXTRA_DIST = README props-introspect.xml + +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_PROGRAMS = props-server + +props_server_SOURCES = props-glue.h props-server.h props-server.cpp +props_server_LDADD = $(top_builddir)/src/libdbus-c++-1.la + +props-glue.h: props-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --adaptor=$@ + +BUILT_SOURCES = props-glue.h +CLEANFILES = $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/examples/properties/README b/libs/dbus/examples/properties/README new file mode 100644 index 0000000000000000000000000000000000000000..2e7f3d7b049b9c5e84bcd1f08fe82ccafffdecfa --- /dev/null +++ b/libs/dbus/examples/properties/README @@ -0,0 +1,18 @@ +This very simple example shows how to export properties (from objects implementing the org.freedesktop.DBus.Properties interface) + +To test, run `DBUSXX_VERBOSE=1 ./props-server` and try the following commands: + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Get string:"org.freedesktop.DBus.PropsDemo" string:"Version" + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Set string:"org.freedesktop.DBus.PropsDemo" string:"Version" int32:2 + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Set string:"org.freedesktop.DBus.PropsDemo" string:"Message" variant:string:"Hello D-Bus" + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Set string:"org.freedesktop.DBus.PropsDemo" string:"Message" variant:int32:200 + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Get string:"org.freedesktop.DBus.PropsDemo" string:"Message" + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Get string:"org.freedesktop.DBus.PropsDemo" string:"Something" + +dbus-send --dest=org.freedesktop.DBus.Examples.Properties --type=method_call --print-reply /org/freedesktop/DBus/Examples/Properties org.freedesktop.DBus.Properties.Get string:"org.freedesktop.DBus.PropsDemo" int32:100 + diff --git a/libs/dbus/examples/properties/props-introspect.xml b/libs/dbus/examples/properties/props-introspect.xml new file mode 100644 index 0000000000000000000000000000000000000000..1ce7e72892136043d1b2ca6e03df1f096a337d05 --- /dev/null +++ b/libs/dbus/examples/properties/props-introspect.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<node name="/org/freedesktop/DBus/Examples/Properties"> + <interface name="org.freedesktop.DBus.PropsDemo"> + <property name="Version" type="i" access="read"/> + <property name="Message" type="s" access="readwrite"/> + <signal name="MessageChanged"> + <arg name="message" type="s"/> + </signal> + </interface> +</node> diff --git a/libs/dbus/examples/properties/props-server.cpp b/libs/dbus/examples/properties/props-server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a4495f7de934c1af0e25efb47136b791cd48c90 --- /dev/null +++ b/libs/dbus/examples/properties/props-server.cpp @@ -0,0 +1,46 @@ +#include "props-server.h" +#include <signal.h> + +static const char* PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties"; +static const char* PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; + +PropsServer::PropsServer( DBus::Connection& connection ) +: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH) +{ + Version = 1; + Message = "default message"; +} + +void PropsServer::on_set_property + ( DBus::InterfaceAdaptor& interface, const DBus::String& property, const DBus::Variant& value ) +{ + if(property == "Message") + { + DBus::String msg = value; + this->MessageChanged(msg); + } +} + +DBus::BusDispatcher dispatcher; + +void niam( int sig ) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + conn.request_name(PROPS_SERVER_NAME); + + PropsServer server(conn); + + dispatcher.enter(); + + return 0; +} diff --git a/libs/dbus/examples/properties/props-server.h b/libs/dbus/examples/properties/props-server.h new file mode 100644 index 0000000000000000000000000000000000000000..93d13eeddad32bae5fbe4dbea498ff8bf3e58838 --- /dev/null +++ b/libs/dbus/examples/properties/props-server.h @@ -0,0 +1,21 @@ +#ifndef __DEMO_PROPS_SERVER_H +#define __DEMO_PROPS_SERVER_H + +#include <dbus-c++/dbus.h> +#include "props-glue.h" + +class PropsServer +: public org::freedesktop::DBus::PropsDemo, + public DBus::IntrospectableAdaptor, + public DBus::PropertiesAdaptor, + public DBus::ObjectAdaptor +{ +public: + + PropsServer( DBus::Connection& connection ); + + void on_set_property + ( DBus::InterfaceAdaptor& interface, const DBus::String& property, const DBus::Variant& value ); +}; + +#endif//__DEMO_PROPS_SERVER_H diff --git a/libs/dbus/include/dbus-c++/api.h b/libs/dbus/include/dbus-c++/api.h new file mode 100644 index 0000000000000000000000000000000000000000..c87495664194b78a5b6d69c90c7c81e8197bd820 --- /dev/null +++ b/libs/dbus/include/dbus-c++/api.h @@ -0,0 +1,42 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_API_H +#define __DBUSXX_API_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef GCC_HASCLASSVISIBILITY +# define DXXAPILOCAL __attribute__ ((visibility("hidden"))) +# define DXXAPIPUBLIC __attribute__ ((visibility("default"))) +#else +# define DXXAPILOCAL +# define DXXAPIPUBLIC +#endif + +#define DXXAPI DXXAPIPUBLIC + +#endif//__DBUSXX_API_H diff --git a/libs/dbus/include/dbus-c++/config.h.in b/libs/dbus/include/dbus-c++/config.h.in new file mode 100644 index 0000000000000000000000000000000000000000..f803e5dde35090e8ba837143213fc255bea902d4 --- /dev/null +++ b/libs/dbus/include/dbus-c++/config.h.in @@ -0,0 +1,73 @@ +/* include/dbus-c++/config.h.in. Generated from configure.ac by autoheader. */ + +/* unstable DBus */ +#undef DBUS_API_SUBJECT_TO_CHANGE + +/* DBus supports recursive mutexes (needs DBus >= 0.95) */ +#undef DBUS_HAS_RECURSIVE_MUTEX + +/* dbus_threads_init_default (needs DBus >= 0.93) */ +#undef DBUS_HAS_THREADS_INIT_DEFAULT + +/* to enable hidden symbols */ +#undef GCC_HASCLASSVISIBILITY + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <expat.h> header file. */ +#undef HAVE_EXPAT_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <pthread.h> header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/libs/dbus/include/dbus-c++/connection.h b/libs/dbus/include/dbus-c++/connection.h new file mode 100644 index 0000000000000000000000000000000000000000..5a5272272d9fb589bff1f9c0cece9d1e7c52fc3b --- /dev/null +++ b/libs/dbus/include/dbus-c++/connection.h @@ -0,0 +1,126 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_CONNECTION_H +#define __DBUSXX_CONNECTION_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <list> + +#include "api.h" +#include "types.h" +#include "util.h" +#include "message.h" +#include "pendingcall.h" + +namespace DBus { + +class Connection; + +typedef Slot<bool, const Message&> MessageSlot; + +typedef std::list<Connection> ConnectionList; + +class ObjectAdaptor; +class Dispatcher; + +class DXXAPI Connection +{ +public: + + static Connection SystemBus(); + + static Connection SessionBus(); + + static Connection ActivationBus(); + + struct Private; + + typedef std::list<Private*> PrivatePList; + + Connection( Private* ); + + Connection( const char* address, bool priv = true ); + + Connection( const Connection& c ); + + virtual ~Connection(); + + Dispatcher* setup( Dispatcher* ); + + bool operator == ( const Connection& ) const; + + void add_match( const char* rule ); + + void remove_match( const char* rule ); + + bool add_filter( MessageSlot& ); + + void remove_filter( MessageSlot& ); + + bool unique_name( const char* n ); + + const char* unique_name() const; + + bool register_bus(); + + bool connected() const; + + void disconnect(); + + void exit_on_disconnect( bool exit ); + + void flush(); + + bool send( const Message&, unsigned int* serial = NULL ); + + Message send_blocking( Message& msg, int timeout ); + + PendingCall send_async( Message& msg, int timeout ); + + void request_name( const char* name, int flags = 0 ); + + bool has_name( const char* name ); + + bool start_service( const char* name, unsigned long flags ); + + const std::vector<std::string>& names(); + +private: + + DXXAPILOCAL void init(); + +private: + + RefPtrI<Private> _pvt; + +friend class ObjectAdaptor; // needed in order to register object paths for a connection +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_CONNECTION_H diff --git a/libs/dbus/include/dbus-c++/dbus.h b/libs/dbus/include/dbus-c++/dbus.h new file mode 100644 index 0000000000000000000000000000000000000000..45de4c307be0b8d9ce93560edafdcf944c1ccbb3 --- /dev/null +++ b/libs/dbus/include/dbus-c++/dbus.h @@ -0,0 +1,49 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_DBUS_H +#define __DBUSXX_DBUS_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "types.h" +#include "interface.h" +#include "object.h" +#include "property.h" +#include "connection.h" +#include "server.h" +#include "error.h" +#include "message.h" +#include "debug.h" +#include "pendingcall.h" +#include "server.h" +#include "util.h" +#include "dispatcher.h" +#include "eventloop.h" +#include "eventloop-integration.h" +#include "introspection.h" + +#endif//__DBUSXX_DBUS_H diff --git a/libs/dbus/include/dbus-c++/debug.h b/libs/dbus/include/dbus-c++/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..457ea5ad473c8a240f316b0b7ab13787516512e2 --- /dev/null +++ b/libs/dbus/include/dbus-c++/debug.h @@ -0,0 +1,42 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_DEBUG_H +#define __DBUSXX_DEBUG_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" + +namespace DBus { + +typedef void (*LogFunction)(const char* format, ...); + +extern DXXAPI LogFunction debug_log; + +} /* namespace DBus */ + +#endif diff --git a/libs/dbus/include/dbus-c++/dispatcher.h b/libs/dbus/include/dbus-c++/dispatcher.h new file mode 100644 index 0000000000000000000000000000000000000000..329c234052058368125a5edd2298c9f66d75844a --- /dev/null +++ b/libs/dbus/include/dbus-c++/dispatcher.h @@ -0,0 +1,260 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_DISPATCHER_H +#define __DBUSXX_DISPATCHER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "connection.h" +#include "eventloop.h" + +namespace DBus { + +class DXXAPI Timeout +{ +public: + + class Internal; + + Timeout( Internal* i ); + + virtual ~Timeout(){} + + int interval() const; + + bool enabled() const; + + bool handle(); + + virtual void toggle() = 0; + +private: + + DXXAPILOCAL Timeout( const Timeout& ); + +private: + + Internal* _int; +}; + +class DXXAPI Watch +{ +public: + + class Internal; + + Watch( Internal* i ); + + virtual ~Watch(){} + + int descriptor() const; + + int flags() const; + + bool enabled() const; + + bool handle( int flags ); + + virtual void toggle() = 0; + +private: + + DXXAPILOCAL Watch( const Watch& ); + +private: + + Internal* _int; +}; + +class DXXAPI Dispatcher +{ +public: + + virtual ~Dispatcher() + {} + + void queue_connection( Connection::Private* ); + + void dispatch_pending(); + + virtual void enter() = 0; + + virtual void leave() = 0; + + virtual Timeout* add_timeout( Timeout::Internal* ) = 0; + + virtual void rem_timeout( Timeout* ) = 0; + + virtual Watch* add_watch( Watch::Internal* ) = 0; + + virtual void rem_watch( Watch* ) = 0; + + struct Private; + +private: + + DefaultMutex _mutex_p; + Connection::PrivatePList _pending_queue; +}; + +extern DXXAPI Dispatcher* default_dispatcher; + +/* classes for multithreading support +*/ + +class DXXAPI Mutex +{ +public: + + virtual ~Mutex() {} + + virtual void lock() = 0; + + virtual void unlock() = 0; + + struct Internal; + +protected: + + Internal* _int; +}; + +class DXXAPI CondVar +{ +public: + + virtual ~CondVar() {} + + virtual void wait( Mutex* ) = 0; + + virtual bool wait_timeout( Mutex*, int timeout ) = 0; + + virtual void wake_one() = 0; + + virtual void wake_all() = 0; + + struct Internal; + +protected: + + Internal* _int; +}; + +#ifndef DBUS_HAS_RECURSIVE_MUTEX +typedef Mutex* (*MutexNewFn)(); +typedef bool (*MutexFreeFn)( Mutex* mx ); +typedef bool (*MutexLockFn)( Mutex* mx ); +typedef void (*MutexUnlockFn)( Mutex* mx ); +#else +typedef Mutex* (*MutexNewFn)(); +typedef void (*MutexFreeFn)( Mutex* mx ); +typedef void (*MutexLockFn)( Mutex* mx ); +typedef void (*MutexUnlockFn)( Mutex* mx ); +#endif//DBUS_HAS_RECURSIVE_MUTEX + +typedef CondVar* (*CondVarNewFn)(); +typedef void (*CondVarFreeFn)( CondVar* cv ); +typedef void (*CondVarWaitFn)( CondVar* cv, Mutex* mx ); +typedef bool (*CondVarWaitTimeoutFn)( CondVar* cv, Mutex* mx, int timeout ); +typedef void (*CondVarWakeOneFn)( CondVar* cv ); +typedef void (*CondVarWakeAllFn)( CondVar* cv ); + +#ifdef DBUS_HAS_THREADS_INIT_DEFAULT +void DXXAPI _init_threading(); +#endif//DBUS_HAS_THREADS_INIT_DEFAULT + +void DXXAPI _init_threading( + MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn, + CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn +); + +template<class Mx, class Cv> +struct Threading +{ + static void init() + { + _init_threading( + mutex_new, mutex_free, mutex_lock, mutex_unlock, + condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all + ); + } + + static Mutex* mutex_new() + { + return new Mx; + } + + static void mutex_free( Mutex* mx ) + { + delete mx; + } + + static void mutex_lock( Mutex* mx ) + { + mx->lock(); + } + + static void mutex_unlock( Mutex* mx ) + { + mx->unlock(); + } + + static CondVar* condvar_new() + { + return new Cv; + } + + static void condvar_free( CondVar* cv ) + { + delete cv; + } + + static void condvar_wait( CondVar* cv, Mutex* mx ) + { + cv->wait(mx); + } + + static bool condvar_wait_timeout( CondVar* cv, Mutex* mx, int timeout ) + { + return cv->wait_timeout(mx, timeout); + } + + static void condvar_wake_one( CondVar* cv ) + { + cv->wake_one(); + } + + static void condvar_wake_all( CondVar* cv ) + { + cv->wake_all(); + } +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_DISPATCHER_H diff --git a/libs/dbus/include/dbus-c++/error.h b/libs/dbus/include/dbus-c++/error.h new file mode 100644 index 0000000000000000000000000000000000000000..d30d7c21387dda9cf9dabe846a26fff9ebea5f46 --- /dev/null +++ b/libs/dbus/include/dbus-c++/error.h @@ -0,0 +1,289 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_ERROR_H +#define __DBUSXX_ERROR_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "util.h" + +#include <exception> + +namespace DBus { + +class Message; +class InternalError; + +class DXXAPI Error : public std::exception +{ +public: + + Error(); + + Error( InternalError& ); + + Error( const char* name, const char* message ); + + Error( Message& ); + + ~Error() throw(); + + const char* what() const throw(); + + const char* name() const; + + const char* message() const; + + void set( const char* name, const char* message ); + // parameters MUST be static strings + + bool is_set() const; + + operator bool() const + { + return is_set(); + } + +private: + + RefPtrI<InternalError> _int; +}; + +struct DXXAPI ErrorFailed : public Error +{ + ErrorFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Failed", message) + {} +}; + +struct DXXAPI ErrorNoMemory : public Error +{ + ErrorNoMemory( const char* message ) + : Error("org.freedesktop.DBus.Error.NoMemory", message) + {} +}; + +struct DXXAPI ErrorServiceUnknown : public Error +{ + ErrorServiceUnknown( const char* message ) + : Error("org.freedesktop.DBus.Error.ServiceUnknown", message) + {} +}; + +struct DXXAPI ErrorNameHasNoOwner : public Error +{ + ErrorNameHasNoOwner( const char* message ) + : Error("org.freedesktop.DBus.Error.NameHasNoOwner", message) + {} +}; + +struct DXXAPI ErrorNoReply : public Error +{ + ErrorNoReply( const char* message ) + : Error("org.freedesktop.DBus.Error.NoReply", message) + {} +}; + +struct DXXAPI ErrorIOError : public Error +{ + ErrorIOError( const char* message ) + : Error("org.freedesktop.DBus.Error.IOError", message) + {} +}; + +struct DXXAPI ErrorBadAddress : public Error +{ + ErrorBadAddress( const char* message ) + : Error("org.freedesktop.DBus.Error.BadAddress", message) + {} +}; + +struct DXXAPI ErrorNotSupported : public Error +{ + ErrorNotSupported( const char* message ) + : Error("org.freedesktop.DBus.Error.NotSupported", message) + {} +}; + +struct DXXAPI ErrorLimitsExceeded : public Error +{ + ErrorLimitsExceeded( const char* message ) + : Error("org.freedesktop.DBus.Error.LimitsExceeded", message) + {} +}; + +struct DXXAPI ErrorAccessDenied : public Error +{ + ErrorAccessDenied( const char* message ) + : Error("org.freedesktop.DBus.Error.AccessDenied", message) + {} +}; + +struct DXXAPI ErrorAuthFailed : public Error +{ + ErrorAuthFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.AuthFailed", message) + {} +}; + +struct DXXAPI ErrorNoServer : public Error +{ + ErrorNoServer( const char* message ) + : Error("org.freedesktop.DBus.Error.NoServer", message) + {} +}; + +struct DXXAPI ErrorTimeout : public Error +{ + ErrorTimeout( const char* message ) + : Error("org.freedesktop.DBus.Error.Timeout", message) + {} +}; + +struct DXXAPI ErrorNoNetwork : public Error +{ + ErrorNoNetwork( const char* message ) + : Error("org.freedesktop.DBus.Error.NoNetwork", message) + {} +}; + +struct DXXAPI ErrorAddressInUse : public Error +{ + ErrorAddressInUse( const char* message ) + : Error("org.freedesktop.DBus.Error.AddressInUse", message) + {} +}; + +struct DXXAPI ErrorDisconnected : public Error +{ + ErrorDisconnected( const char* message ) + : Error("org.freedesktop.DBus.Error.Disconnected", message) + {} +}; + +struct DXXAPI ErrorInvalidArgs : public Error +{ + ErrorInvalidArgs( const char* message ) + : Error("org.freedesktop.DBus.Error.InvalidArgs", message) + {} +}; + +struct DXXAPI ErrorFileNotFound : public Error +{ + ErrorFileNotFound( const char* message ) + : Error("org.freedesktop.DBus.Error.FileNotFound", message) + {} +}; + +struct DXXAPI ErrorUnknownMethod : public Error +{ + ErrorUnknownMethod( const char* message ) + : Error("org.freedesktop.DBus.Error.UnknownMethod", message) + {} +}; + +struct DXXAPI ErrorTimedOut : public Error +{ + ErrorTimedOut( const char* message ) + : Error("org.freedesktop.DBus.Error.TimedOut", message) + {} +}; + +struct DXXAPI ErrorMatchRuleNotFound : public Error +{ + ErrorMatchRuleNotFound( const char* message ) + : Error("org.freedesktop.DBus.Error.MatchRuleNotFound", message) + {} +}; + +struct DXXAPI ErrorMatchRuleInvalid : public Error +{ + ErrorMatchRuleInvalid( const char* message ) + : Error("org.freedesktop.DBus.Error.MatchRuleInvalid", message) + {} +}; + +struct DXXAPI ErrorSpawnExecFailed : public Error +{ + ErrorSpawnExecFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ExecFailed", message) + {} +}; + +struct DXXAPI ErrorSpawnForkFailed : public Error +{ + ErrorSpawnForkFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ForkFailed", message) + {} +}; + +struct DXXAPI ErrorSpawnChildExited : public Error +{ + ErrorSpawnChildExited( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ChildExited", message) + {} +}; + +struct DXXAPI ErrorSpawnChildSignaled : public Error +{ + ErrorSpawnChildSignaled( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ChildSignaled", message) + {} +}; + +struct DXXAPI ErrorSpawnFailed : public Error +{ + ErrorSpawnFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.Failed", message) + {} +}; + +struct DXXAPI ErrorInvalidSignature : public Error +{ + ErrorInvalidSignature( const char* message ) + : Error("org.freedesktop.DBus.Error.InvalidSignature", message) + {} +}; + +struct DXXAPI ErrorUnixProcessIdUnknown : public Error +{ + ErrorUnixProcessIdUnknown( const char* message ) + : Error("org.freedesktop.DBus.Error.UnixProcessIdUnknown", message) + {} +}; + +struct DXXAPI ErrorSELinuxSecurityContextUnknown : public Error +{ + ErrorSELinuxSecurityContextUnknown( const char* message ) + : Error("org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", message) + {} +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_ERROR_H diff --git a/libs/dbus/include/dbus-c++/eventloop-integration.h b/libs/dbus/include/dbus-c++/eventloop-integration.h new file mode 100644 index 0000000000000000000000000000000000000000..1f5ae5ead5bd3be2f8efd43d9aad03ce5ad70adf --- /dev/null +++ b/libs/dbus/include/dbus-c++/eventloop-integration.h @@ -0,0 +1,98 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_EVENTLOOP_INTEGRATION_H +#define __DBUSXX_EVENTLOOP_INTEGRATION_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "dispatcher.h" +#include "util.h" +#include "eventloop.h" + +namespace DBus { + +/* + * Glue between the event loop and the DBus library + */ + +class BusDispatcher; + +class DXXAPI BusTimeout : public Timeout, public DefaultTimeout +{ + BusTimeout( Timeout::Internal*, BusDispatcher* ); + + void toggle(); + +friend class BusDispatcher; +}; + +class DXXAPI BusWatch : public Watch, public DefaultWatch +{ + BusWatch( Watch::Internal*, BusDispatcher* ); + + void toggle(); + +friend class BusDispatcher; +}; + +class DXXAPI BusDispatcher : public Dispatcher, public DefaultMainLoop +{ +public: + + BusDispatcher() : _running(false) + {} + + ~BusDispatcher() + {} + + virtual void enter(); + + virtual void leave(); + + virtual void do_iteration(); + + virtual Timeout* add_timeout( Timeout::Internal* ); + + virtual void rem_timeout( Timeout* ); + + virtual Watch* add_watch( Watch::Internal* ); + + virtual void rem_watch( Watch* ); + + void watch_ready( DefaultWatch& ); + + void timeout_expired( DefaultTimeout& ); + +private: + + bool _running; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_EVENTLOOP_INTEGRATION_H diff --git a/libs/dbus/include/dbus-c++/eventloop.h b/libs/dbus/include/dbus-c++/eventloop.h new file mode 100644 index 0000000000000000000000000000000000000000..fcf116400c0e3d5316532375234aaa6511cfa25d --- /dev/null +++ b/libs/dbus/include/dbus-c++/eventloop.h @@ -0,0 +1,181 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_EVENTLOOP_H +#define __DBUSXX_EVENTLOOP_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif + +#include <list> + +#include "api.h" +#include "util.h" + +namespace DBus { + +/* + * these Default* classes implement a very simple event loop which + * is used here as the default main loop, if you want to hook + * a different one use the Bus* classes in eventloop-integration.h + * or the Glib::Bus* classes as a reference + */ + +class DefaultMainLoop; + +class DXXAPI DefaultTimeout +{ +public: + + DefaultTimeout( int interval, bool repeat, DefaultMainLoop* ); + + virtual ~DefaultTimeout(); + + bool enabled(){ return _enabled; } + void enabled(bool e){ _enabled = e; } + + int interval(){ return _interval; } + void interval(int i){ _interval = i; } + + bool repeat(){ return _repeat; } + void repeat(bool r){ _repeat = r; } + + void* data(){ return _data; } + void data(void* d){ _data = d; } + + Slot<void, DefaultTimeout&> expired; + +private: + + bool _enabled; + + int _interval; + bool _repeat; + + double _expiration; + + void* _data; + + DefaultMainLoop* _disp; + +friend class DefaultMainLoop; +}; + +typedef std::list< DefaultTimeout* > DefaultTimeouts; + +class DXXAPI DefaultWatch +{ +public: + + DefaultWatch( int fd, int flags, DefaultMainLoop* ); + + virtual ~DefaultWatch(); + + bool enabled(){ return _enabled; } + void enabled(bool e){ _enabled = e; } + + int descriptor(){ return _fd; } + + int flags(){ return _flags; } + void flags( int f ){ _flags = f; } + + int state(){ return _state; } + + void* data(){ return _data; } + void data(void* d){ _data = d; } + + Slot<void, DefaultWatch&> ready; + +private: + + bool _enabled; + + int _fd; + int _flags; + int _state; + + void* _data; + + DefaultMainLoop* _disp; + +friend class DefaultMainLoop; +}; + +typedef std::list< DefaultWatch* > DefaultWatches; + +class DXXAPI DefaultMutex +{ +public: + + DefaultMutex(); + + ~DefaultMutex(); + + void lock(); + + void unlock(); + +private: + +#if defined HAVE_PTHREAD + + pthread_mutex _mutex; + +#elif defined HAVE_WIN32 + +//TODO: use a critical section + +#endif +}; + +class DXXAPI DefaultMainLoop +{ +public: + + DefaultMainLoop(); + + virtual ~DefaultMainLoop(); + + virtual void dispatch(); + +private: + + DefaultMutex _mutex_t; + DefaultTimeouts _timeouts; + + DefaultMutex _mutex_w; + DefaultWatches _watches; + +friend class DefaultTimeout; +friend class DefaultWatch; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_EVENTLOOP_H diff --git a/libs/dbus/include/dbus-c++/glib-integration.h b/libs/dbus/include/dbus-c++/glib-integration.h new file mode 100644 index 0000000000000000000000000000000000000000..723c7d8d02061085ef71fe086b63473f84f2a0df --- /dev/null +++ b/libs/dbus/include/dbus-c++/glib-integration.h @@ -0,0 +1,119 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_GLIB_INTEGRATION_H +#define __DBUSXX_GLIB_INTEGRATION_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib.h> + +#include "api.h" +#include "eventloop.h" + +namespace DBus { + +namespace Glib { + +class BusDispatcher; + +class DXXAPI BusTimeout : public Timeout +{ +private: + + BusTimeout( Timeout::Internal*, GMainContext* ); + + ~BusTimeout(); + + void toggle(); + + static gboolean timeout_handler( gpointer ); + + void _enable(); + + void _disable(); + +private: + + GSource* _source; + GMainContext* _ctx; + +friend class BusDispatcher; +}; + +class DXXAPI BusWatch : public Watch +{ +private: + + BusWatch( Watch::Internal*, GMainContext* ); + + ~BusWatch(); + + void toggle(); + + static gboolean watch_handler( gpointer ); + + void _enable(); + + void _disable(); + +private: + + GSource* _source; + GMainContext* _ctx; + +friend class BusDispatcher; +}; + +class DXXAPI BusDispatcher : public Dispatcher +{ +public: + BusDispatcher() : _ctx(NULL) {} + + void attach( GMainContext* ); + + void enter() {} + + void leave() {} + + Timeout* add_timeout( Timeout::Internal* ); + + void rem_timeout( Timeout* ); + + Watch* add_watch( Watch::Internal* ); + + void rem_watch( Watch* ); + +private: + + GMainContext* _ctx; +}; + +} /* namespace Glib */ + +} /* namespace DBus */ + +#endif//__DBUSXX_GLIB_INTEGRATION_H diff --git a/libs/dbus/include/dbus-c++/interface.h b/libs/dbus/include/dbus-c++/interface.h new file mode 100644 index 0000000000000000000000000000000000000000..a59785aefff3953ad3f06c32c140ec99b2e5eafe --- /dev/null +++ b/libs/dbus/include/dbus-c++/interface.h @@ -0,0 +1,195 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_INTERFACE_H +#define __DBUSXX_INTERFACE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string> +#include <map> +#include "api.h" +#include "util.h" +#include "types.h" + +#include "message.h" + +namespace DBus { + +//todo: this should belong to to properties.h +struct DXXAPI PropertyData +{ + bool read; + bool write; + std::string sig; + Variant value; +}; + +typedef std::map<std::string, PropertyData> PropertyTable; + +class IntrospectedInterface; + +class ObjectAdaptor; +class InterfaceAdaptor; +class SignalMessage; + +typedef std::map<std::string, InterfaceAdaptor*> InterfaceAdaptorTable; + +class DXXAPI AdaptorBase +{ +public: + + virtual const ObjectAdaptor* object() const = 0 ; + +protected: + + InterfaceAdaptor* find_interface( const std::string& name ); + + virtual ~AdaptorBase() + {} + + virtual void _emit_signal( SignalMessage& ) = 0; + + InterfaceAdaptorTable _interfaces; +}; + +/* +*/ + +class ObjectProxy; +class InterfaceProxy; +class CallMessage; + +typedef std::map<std::string, InterfaceProxy*> InterfaceProxyTable; + +class DXXAPI ProxyBase +{ +public: + + virtual const ObjectProxy* object() const = 0 ; + +protected: + + InterfaceProxy* find_interface( const std::string& name ); + + virtual ~ProxyBase() + {} + + virtual Message _invoke_method( CallMessage& ) = 0; + + InterfaceProxyTable _interfaces; +}; + +class DXXAPI Interface +{ +public: + + Interface( const std::string& name ); + + virtual ~Interface(); + + inline const std::string& name() const; + +private: + + std::string _name; +}; + +/* +*/ + +const std::string& Interface::name() const +{ + return _name; +} + +/* +*/ + +typedef std::map< std::string, Slot<Message, const CallMessage&> > MethodTable; + +class DXXAPI InterfaceAdaptor : public Interface, public virtual AdaptorBase +{ +public: + + InterfaceAdaptor( const std::string& name ); + + Message dispatch_method( const CallMessage& ); + + void emit_signal( const SignalMessage& ); + + Variant* get_property( const std::string& name ); + + void set_property( const std::string& name, Variant& value ); + + virtual IntrospectedInterface* const introspect() const + { + return NULL; + } + +protected: + + MethodTable _methods; + PropertyTable _properties; +}; + +/* +*/ + +typedef std::map< std::string, Slot<void, const SignalMessage&> > SignalTable; + +class DXXAPI InterfaceProxy : public Interface, public virtual ProxyBase +{ +public: + + InterfaceProxy( const std::string& name ); + + Message invoke_method( const CallMessage& ); + + bool dispatch_signal( const SignalMessage& ); + +protected: + + SignalTable _signals; +}; + +# define register_method(interface, method, callback) \ + InterfaceAdaptor::_methods[ #method ] = \ + new ::DBus::Callback< interface, ::DBus::Message, const ::DBus::CallMessage& >(this, & interface :: callback ); + +# define bind_property(variable, type, can_read, can_write) \ + InterfaceAdaptor::_properties[ #variable ].read = can_read; \ + InterfaceAdaptor::_properties[ #variable ].write = can_write; \ + InterfaceAdaptor::_properties[ #variable ].sig = type; \ + variable.bind( InterfaceAdaptor::_properties[ #variable ] ); + +# define connect_signal(interface, signal, callback) \ + InterfaceProxy::_signals[ #signal ] = \ + new ::DBus::Callback< interface, void, const ::DBus::SignalMessage& >(this, & interface :: callback ); + +} /* namespace DBus */ + +#endif//__DBUSXX_INTERFACE_H diff --git a/libs/dbus/include/dbus-c++/introspection.h b/libs/dbus/include/dbus-c++/introspection.h new file mode 100644 index 0000000000000000000000000000000000000000..00a33b01547ec3ca933189881774555ac58af121 --- /dev/null +++ b/libs/dbus/include/dbus-c++/introspection.h @@ -0,0 +1,90 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_INTROSPECTION_H +#define __DBUSXX_INTROSPECTION_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "interface.h" + +namespace DBus { + +struct DXXAPI IntrospectedArgument +{ + const char* name; + const char* type; + const bool in; +}; + +struct DXXAPI IntrospectedMethod +{ + const char* name; + const IntrospectedArgument* args; +}; + +struct DXXAPI IntrospectedProperty +{ + const char* name; + const char* type; + const bool read; + const bool write; +}; + +struct DXXAPI IntrospectedInterface +{ + const char* name; + const IntrospectedMethod* methods; + const IntrospectedMethod* signals; + const IntrospectedProperty* properties; +}; + +class DXXAPI IntrospectableAdaptor : public InterfaceAdaptor +{ +public: + + IntrospectableAdaptor(); + + Message Introspect( const CallMessage& ); + +protected: + + IntrospectedInterface* const introspect() const; +}; + +class DXXAPI IntrospectableProxy : public InterfaceProxy +{ +public: + + IntrospectableProxy(); + + std::string Introspect(); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_INTROSPECTION_H diff --git a/libs/dbus/include/dbus-c++/message.h b/libs/dbus/include/dbus-c++/message.h new file mode 100644 index 0000000000000000000000000000000000000000..a287ab873d1a9c2baaa1128972786c5d1c85905a --- /dev/null +++ b/libs/dbus/include/dbus-c++/message.h @@ -0,0 +1,312 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_MESSAGE_H +#define __DBUSXX_MESSAGE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string> +#include <map> + +#include "api.h" +#include "util.h" + +namespace DBus { + +class Message; +class ErrorMessage; +class SignalMessage; +class ReturnMessage; +class Error; +class Connection; + +class DXXAPI MessageIter +{ +public: + + MessageIter() {} + + int type(); + + bool at_end(); + + bool has_next(); + + MessageIter& operator ++(); + + MessageIter operator ++(int); + + bool append_byte( unsigned char byte ); + + unsigned char get_byte(); + + bool append_bool( bool b ); + + bool get_bool(); + + bool append_int16( signed short i ); + + signed short get_int16(); + + bool append_uint16( unsigned short u ); + + unsigned short get_uint16(); + + bool append_int32( signed int i ); + + signed int get_int32(); + + bool append_uint32( unsigned int u ); + + unsigned int get_uint32(); + + bool append_int64( signed long long i ); + + signed long long get_int64(); + + bool append_uint64( unsigned long long i ); + + unsigned long long get_uint64(); + + bool append_double( double d ); + + double get_double(); + + bool append_string( const char* chars ); + + const char* get_string(); + + bool append_path( const char* chars ); + + const char* get_path(); + + bool append_signature( const char* chars ); + + const char* get_signature(); + + char* signature() const; //returned string must be manually free()'d + + MessageIter recurse(); + + bool append_array( char type, const void* ptr, size_t length ); + + int array_type(); + + int get_array( void* ptr ); + + bool is_array(); + + bool is_dict(); + + MessageIter new_array( const char* sig ); + + MessageIter new_variant( const char* sig ); + + MessageIter new_struct(); + + MessageIter new_dict_entry(); + + void close_container( MessageIter& container ); + + void copy_data( MessageIter& to ); + + Message& msg() const + { + return *_msg; + } + +private: + + DXXAPILOCAL MessageIter(Message& msg) : _msg(&msg) {} + + DXXAPILOCAL bool append_basic( int type_id, void* value ); + + DXXAPILOCAL void get_basic( int type_id, void* ptr ); + +private: + + /* I'm sorry, but don't want to include dbus.h in the public api + */ + unsigned char _iter[sizeof(void*)*3+sizeof(int)*11]; + + Message* _msg; + +friend class Message; +}; + +class DXXAPI Message +{ +public: + + struct Private; + + Message( Private*, bool incref = true ); + + Message( const Message& m ); + + ~Message(); + + Message& operator = ( const Message& m ); + + Message copy(); + + int type() const; + + int serial() const; + + int reply_serial() const; + + bool reply_serial( int ); + + const char* sender() const; + + bool sender( const char* s ); + + const char* destination() const; + + bool destination( const char* s ); + + bool is_error() const; + + bool is_signal( const char* interface, const char* member ) const; + + MessageIter reader() const; + + MessageIter writer(); + + bool append( int first_type, ... ); + + void terminate(); + +protected: + + Message(); + +protected: + + RefPtrI<Private> _pvt; + +/* classes who need to read `_pvt` directly +*/ +friend class ErrorMessage; +friend class ReturnMessage; +friend class MessageIter; +friend class Error; +friend class Connection; +}; + +/* +*/ + +class DXXAPI ErrorMessage : public Message +{ +public: + + ErrorMessage(); + + ErrorMessage( const Message&, const char* name, const char* message ); + + const char* name() const; + + bool name( const char* n ); + + bool operator == ( const ErrorMessage& ) const; +}; + +/* +*/ + +class DXXAPI SignalMessage : public Message +{ +public: + + SignalMessage( const char* name ); + + SignalMessage( const char* path, const char* interface, const char* name ); + + const char* interface() const; + + bool interface( const char* i ); + + const char* member() const; + + bool member( const char* m ); + + const char* path() const; + + char** path_split() const; + + bool path( const char* p ); + + bool operator == ( const SignalMessage& ) const; +}; + +/* +*/ + +class DXXAPI CallMessage : public Message +{ +public: + + CallMessage(); + + CallMessage( const char* dest, const char* path, const char* iface, const char* method ); + + const char* interface() const; + + bool interface( const char* i ); + + const char* member() const; + + bool member( const char* m ); + + const char* path() const; + + char** path_split() const; + + bool path( const char* p ); + + const char* signature() const; + + bool operator == ( const CallMessage& ) const; +}; + +/* +*/ + +class DXXAPI ReturnMessage : public Message +{ +public: + + ReturnMessage( const CallMessage& callee ); + + const char* signature() const; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_MESSAGE_H diff --git a/libs/dbus/include/dbus-c++/object.h b/libs/dbus/include/dbus-c++/object.h new file mode 100644 index 0000000000000000000000000000000000000000..7c3240bb959695c41e156faf8de96adeab5c0728 --- /dev/null +++ b/libs/dbus/include/dbus-c++/object.h @@ -0,0 +1,223 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_OBJECT_H +#define __DBUSXX_OBJECT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string> +#include <list> + +#include "api.h" +#include "interface.h" +#include "connection.h" +#include "message.h" +#include "types.h" + +namespace DBus { + +class DXXAPI Object +{ +protected: + + Object( Connection& conn, const Path& path, const char* service ); + +public: + + virtual ~Object(); + + inline const DBus::Path& path() const; + + inline const std::string& service() const; + + inline Connection& conn(); + +private: + + DXXAPILOCAL virtual bool handle_message( const Message& ) = 0; + DXXAPILOCAL virtual void register_obj() = 0; + DXXAPILOCAL virtual void unregister_obj() = 0; + +private: + + Connection _conn; + DBus::Path _path; + std::string _service; +}; + +/* +*/ + +Connection& Object::conn() +{ + return _conn; +} + +const DBus::Path& Object::path() const +{ + return _path; +} + +const std::string& Object::service() const +{ + return _service; +} + +/* +*/ + +class DXXAPI Tag +{ +public: + + virtual ~Tag() + {} +}; + +/* +*/ + +class ObjectAdaptor; + +typedef std::list<ObjectAdaptor*> ObjectAdaptorPList; + +class DXXAPI ObjectAdaptor : public Object, public virtual AdaptorBase +{ +public: + + static ObjectAdaptor* from_path( const Path& path ); + + static ObjectAdaptorPList from_path_prefix( const std::string& prefix ); + + struct Private; + + ObjectAdaptor( Connection& conn, const Path& path ); + + ~ObjectAdaptor(); + + inline const ObjectAdaptor* object() const; + +protected: + + class DXXAPI Continuation + { + public: + + inline MessageIter& writer(); + + inline Tag* tag(); + + private: + + Continuation( Connection& conn, const CallMessage& call, const Tag* tag ); + + Connection _conn; + CallMessage _call; + MessageIter _writer; + ReturnMessage _return; + const Tag* _tag; + + friend class ObjectAdaptor; + }; + + void return_later( const Tag* tag ); + + void return_now( Continuation* ret ); + + void return_error( Continuation* ret, const Error error ); + + Continuation* find_continuation( const Tag* tag ); + +private: + + void _emit_signal( SignalMessage& ); + + bool handle_message( const Message& ); + + void register_obj(); + void unregister_obj(); + + typedef std::map<const Tag*, Continuation*> ContinuationMap; + ContinuationMap _continuations; + +friend struct Private; +}; + +const ObjectAdaptor* ObjectAdaptor::object() const +{ + return this; +} + +Tag* ObjectAdaptor::Continuation::tag() +{ + return const_cast<Tag*>(_tag); +} + +MessageIter& ObjectAdaptor::Continuation::writer() +{ + return _writer; +} + +/* +*/ + +class ObjectProxy; + +typedef std::list<ObjectProxy*> ObjectProxyPList; + +class DXXAPI ObjectProxy : public Object, public virtual ProxyBase +{ +public: + + ObjectProxy( Connection& conn, const Path& path, const char* service = "" ); + + ~ObjectProxy(); + + inline const ObjectProxy* object() const; + +private: + + Message _invoke_method( CallMessage& ); + + bool handle_message( const Message& ); + + void register_obj(); + void unregister_obj(); + +private: + + MessageSlot _filtered; +}; + +const ObjectProxy* ObjectProxy::object() const +{ + return this; +} + +} /* namespace DBus */ + +#endif//__DBUSXX_OBJECT_H diff --git a/libs/dbus/include/dbus-c++/pendingcall.h b/libs/dbus/include/dbus-c++/pendingcall.h new file mode 100644 index 0000000000000000000000000000000000000000..d7c64b801ea4335d7eb03b82ba3b70f1764c2412 --- /dev/null +++ b/libs/dbus/include/dbus-c++/pendingcall.h @@ -0,0 +1,78 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_PENDING_CALL_H +#define __DBUSXX_PENDING_CALL_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "util.h" +#include "message.h" + +namespace DBus { + +class Connection; + +class DXXAPI PendingCall +{ +public: + + struct Private; + + PendingCall( Private* ); + + PendingCall( const PendingCall& ); + + virtual ~PendingCall(); + + PendingCall& operator = ( const PendingCall& ); + + bool completed(); + + void cancel(); + + void block(); + + void data( void* ); + + void* data(); + + Slot<void, PendingCall&>& slot(); + + Message steal_reply(); + +private: + + RefPtrI<Private> _pvt; + +friend struct Private; +friend class Connection; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_PENDING_CALL_H diff --git a/libs/dbus/include/dbus-c++/property.h b/libs/dbus/include/dbus-c++/property.h new file mode 100644 index 0000000000000000000000000000000000000000..28e1846106eb3040789c7e488b27ea4be9879b30 --- /dev/null +++ b/libs/dbus/include/dbus-c++/property.h @@ -0,0 +1,106 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_PROPERTY_H +#define __DBUSXX_PROPERTY_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "types.h" +#include "interface.h" + +namespace DBus { + +template <typename T> +class PropertyAdaptor +{ +public: + + PropertyAdaptor() : _data(0) + {} + + void bind( PropertyData& data ) + { + _data = &data; + } + + T operator() (void) const + { + return (T)_data->value; + } + + PropertyAdaptor& operator = ( const T& t ) + { + _data->value.clear(); + MessageIter wi = _data->value.writer(); + wi << t; + return *this; + } + +private: + + PropertyData* _data; +}; + +struct IntrospectedInterface; + +class DXXAPI PropertiesAdaptor : public InterfaceAdaptor +{ +public: + + PropertiesAdaptor(); + + Message Get( const CallMessage& ); + + Message Set( const CallMessage& ); + +protected: + + virtual void on_get_property( InterfaceAdaptor& interface, const String& property, Variant& value ) + {} + + virtual void on_set_property( InterfaceAdaptor& interface, const String& property, const Variant& value ) + {} + + IntrospectedInterface* const introspect() const; +}; + +class DXXAPI PropertiesProxy : public InterfaceProxy +{ +public: + + PropertiesProxy(); + + Variant Get( const String& interface, const String& property ); + + void Set( const String& interface, const String& property, const Variant& value ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_PROPERTY_H + diff --git a/libs/dbus/include/dbus-c++/refptr_impl.h b/libs/dbus/include/dbus-c++/refptr_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..bf42f40d890ec1e380519e1d88d1215b4a3aca40 --- /dev/null +++ b/libs/dbus/include/dbus-c++/refptr_impl.h @@ -0,0 +1,50 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_REFPTR_IMPL_H +#define __DBUSXX_REFPTR_IMPL_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "util.h" + +namespace DBus { + +template <class T> +RefPtrI<T>::RefPtrI( T* ptr ) +: __ptr(ptr) +{} + +template <class T> +RefPtrI<T>::~RefPtrI() +{ + if(__cnt.one()) delete __ptr; +} + +} /* namespace DBus */ + +#endif//__DBUSXX_REFPTR_IMPL_H diff --git a/libs/dbus/include/dbus-c++/server.h b/libs/dbus/include/dbus-c++/server.h new file mode 100644 index 0000000000000000000000000000000000000000..4597610810c08c69e31322a395e3bfde18078d3e --- /dev/null +++ b/libs/dbus/include/dbus-c++/server.h @@ -0,0 +1,78 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_SERVER_H +#define __DBUSXX_SERVER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <list> + +#include "api.h" +#include "error.h" +#include "connection.h" +#include "util.h" +#include "dispatcher.h" + +namespace DBus { + +class Server; + +typedef std::list<Server> ServerList; + +class DXXAPI Server +{ +public: + + Server( const char* address ); + + Dispatcher* setup( Dispatcher* ); + + virtual ~Server(); + + bool listening() const; + + bool operator == ( const Server& ) const; + + void disconnect(); + + struct Private; + +protected: + + Server( const Server& s ) + {} + + virtual void on_new_connection( Connection& c ) = 0; + +private: + + RefPtrI<Private> _pvt; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_SERVER_H diff --git a/libs/dbus/include/dbus-c++/types.h b/libs/dbus/include/dbus-c++/types.h new file mode 100644 index 0000000000000000000000000000000000000000..f90f980f5f492918989035ba4fe2f56cfce8b7e0 --- /dev/null +++ b/libs/dbus/include/dbus-c++/types.h @@ -0,0 +1,514 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_TYPES_H +#define __DBUSXX_TYPES_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string> +#include <vector> +#include <map> + +#include "api.h" +#include "util.h" +#include "message.h" +#include "error.h" + +namespace DBus { + +typedef unsigned char Byte; +typedef bool Bool; +typedef signed short Int16; +typedef unsigned short UInt16; +typedef signed int Int32; +typedef unsigned int UInt32; +typedef signed long long Int64; +typedef unsigned long long UInt64; +typedef double Double; +typedef std::string String; + +struct DXXAPI Path : public std::string +{ + Path() {} + Path( const std::string& s ) : std::string(s) {} + Path( const char* c ) : std::string(c) {} + Path& operator = ( std::string& s ) + { + std::string::operator = (s); + return *this; + } +}; + +struct DXXAPI Signature : public std::string +{ + Signature() {} + Signature( const std::string& s ) : std::string(s) {} + Signature( const char* c ) : std::string(c) {} + Signature& operator = ( std::string& s ) + { + std::string::operator = (s); + return *this; + } +}; + +struct DXXAPI Invalid {}; + +class DXXAPI Variant +{ +public: + + Variant(); + + Variant( MessageIter& it ); + + Variant& operator = ( const Variant& v ); + + const Signature signature() const; + + void clear(); + + MessageIter reader() const + { + return _msg.reader(); + } + + MessageIter writer() + { + return _msg.writer(); + } + + template <typename T> + operator T() const + { + T cast; + MessageIter ri = _msg.reader(); + ri >> cast; + return cast; + } + +private: + + Message _msg; +}; + +template < + typename T1, + typename T2 = Invalid, + typename T3 = Invalid, + typename T4 = Invalid, + typename T5 = Invalid, + typename T6 = Invalid, + typename T7 = Invalid, + typename T8 = Invalid // who needs more than eight? +> +struct Struct +{ + T1 _1; T2 _2; T3 _3; T4 _4; T5 _5; T6 _6; T7 _7; T8 _8; +}; + +template<typename K, typename V> +inline bool dict_has_key( const std::map<K,V>& map, const K& key ) +{ + return map.find(key) != map.end(); +} + +template <typename T> +struct type +{ + static std::string sig() + { + throw ErrorInvalidArgs("unknown type"); + return ""; + } +}; + +template <> struct type<Variant> { static std::string sig(){ return "v"; } }; +template <> struct type<Byte> { static std::string sig(){ return "y"; } }; +template <> struct type<Bool> { static std::string sig(){ return "b"; } }; +template <> struct type<Int16> { static std::string sig(){ return "n"; } }; +template <> struct type<UInt16> { static std::string sig(){ return "q"; } }; +template <> struct type<Int32> { static std::string sig(){ return "i"; } }; +template <> struct type<UInt32> { static std::string sig(){ return "u"; } }; +template <> struct type<Int64> { static std::string sig(){ return "x"; } }; +template <> struct type<UInt64> { static std::string sig(){ return "t"; } }; +template <> struct type<Double> { static std::string sig(){ return "d"; } }; +template <> struct type<String> { static std::string sig(){ return "s"; } }; +template <> struct type<Path> { static std::string sig(){ return "o"; } }; +template <> struct type<Signature> { static std::string sig(){ return "g"; } }; +template <> struct type<Invalid> { static std::string sig(){ return ""; } }; + +template <typename E> +struct type< std::vector<E> > +{ static std::string sig(){ return "a" + type<E>::sig(); } }; + +template <typename K, typename V> +struct type< std::map<K,V> > +{ static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } }; + +template < + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8 // who needs more than eight? +> +struct type< Struct<T1,T2,T3,T4,T5,T6,T7,T8> > +{ + static std::string sig() + { + return "(" + + type<T1>::sig() + + type<T2>::sig() + + type<T3>::sig() + + type<T4>::sig() + + type<T5>::sig() + + type<T6>::sig() + + type<T7>::sig() + + type<T8>::sig() + + ")"; + } +}; + +} /* namespace DBus */ + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Invalid& ) +{ + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Byte& val ) +{ + iter.append_byte(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Bool& val ) +{ + iter.append_bool(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Int16& val ) +{ + iter.append_int16(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::UInt16& val ) +{ + iter.append_uint16(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Int32& val ) +{ + iter.append_int32(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::UInt32& val ) +{ + iter.append_uint32(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Int64& val ) +{ + iter.append_int64(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::UInt64& val ) +{ + iter.append_uint64(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Double& val ) +{ + iter.append_double(val); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::String& val ) +{ + iter.append_string(val.c_str()); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Path& val ) +{ + iter.append_path(val.c_str()); + return iter; +} + +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Signature& val ) +{ + iter.append_signature(val.c_str()); + return iter; +} + +template<typename E> +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const std::vector<E>& val ) +{ + const std::string sig = DBus::type<E>::sig(); + DBus::MessageIter ait = iter.new_array(sig.c_str()); + + typename std::vector<E>::const_iterator vit; + for(vit = val.begin(); vit != val.end(); ++vit) + { + ait << *vit; + } + + iter.close_container(ait); + return iter; +} + +template<> +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const std::vector<DBus::Byte>& val ) +{ + DBus::MessageIter ait = iter.new_array("y"); + ait.append_array('y', &val.front(), val.size()); + iter.close_container(ait); + return iter; +} + +template<typename K, typename V> +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const std::map<K,V>& val ) +{ + const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}"; + DBus::MessageIter ait = iter.new_array(sig.c_str()); + + typename std::map<K,V>::const_iterator mit; + for(mit = val.begin(); mit != val.end(); ++mit) + { + DBus::MessageIter eit = ait.new_dict_entry(); + + eit << mit->first << mit->second; + + ait.close_container(eit); + } + + iter.close_container(ait); + return iter; +} + +template < + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8 +> +inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val ) +{ +/* const std::string sig = + DBus::type<T1>::sig() + DBus::type<T2>::sig() + DBus::type<T3>::sig() + DBus::type<T4>::sig() + + DBus::type<T5>::sig() + DBus::type<T6>::sig() + DBus::type<T7>::sig() + DBus::type<T8>::sig(); +*/ + DBus::MessageIter sit = iter.new_struct(/*sig.c_str()*/); + + sit << val._1 << val._2 << val._3 << val._4 << val._5 << val._6 << val._7 << val._8; + + iter.close_container(sit); + + return iter; +} + +extern DXXAPI DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Variant& val ); + +/* + */ + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Invalid& ) +{ + return iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Byte& val ) +{ + val = iter.get_byte(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Bool& val ) +{ + val = iter.get_bool(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Int16& val ) +{ + val = iter.get_int16(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::UInt16& val ) +{ + val = iter.get_uint16(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Int32& val ) +{ + val = iter.get_int32(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::UInt32& val ) +{ + val = iter.get_uint32(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Int64& val ) +{ + val = iter.get_int64(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::UInt64& val ) +{ + val = iter.get_uint64(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Double& val ) +{ + val = iter.get_double(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::String& val ) +{ + val = iter.get_string(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Path& val ) +{ + val = iter.get_path(); + return ++iter; +} + +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Signature& val ) +{ + val = iter.get_signature(); + return ++iter; +} + +template<typename E> +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, std::vector<E>& val ) +{ + if(!iter.is_array()) + throw DBus::ErrorInvalidArgs("array expected"); + + DBus::MessageIter ait = iter.recurse(); + + while(!ait.at_end()) + { + E elem; + + ait >> elem; + + val.push_back(elem); + } + return ++iter; +} + +template<> +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, std::vector<DBus::Byte>& val ) +{ + if(!iter.is_array()) + throw DBus::ErrorInvalidArgs("array expected"); + + if(iter.array_type() != 'y') + throw DBus::ErrorInvalidArgs("byte-array expected"); + + DBus::MessageIter ait = iter.recurse(); + + DBus::Byte* array; + size_t length = ait.get_array(&array); + + val.insert(val.end(), array, array+length); + + return ++iter; +} + +template<typename K, typename V> +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, std::map<K,V>& val ) +{ + if(!iter.is_dict()) + throw DBus::ErrorInvalidArgs("dictionary value expected"); + + DBus::MessageIter mit = iter.recurse(); + + while(!mit.at_end()) + { + K key; V value; + + DBus::MessageIter eit = mit.recurse(); + + eit >> key >> value; + + val[key] = value; + + ++mit; + } + + return ++iter; +} + +template < + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8 +> +inline DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val) +{ + DBus::MessageIter sit = iter.recurse(); + + sit >> val._1 >> val._2 >> val._3 >> val._4 >> val._5 >> val._6 >> val._7 >> val._8; + + return ++iter; +} + +extern DXXAPI DBus::MessageIter& operator >> ( DBus::MessageIter& iter, DBus::Variant& val ); + +#endif//__DBUSXX_TYPES_H + diff --git a/libs/dbus/include/dbus-c++/util.h b/libs/dbus/include/dbus-c++/util.h new file mode 100644 index 0000000000000000000000000000000000000000..a22f26719c431be9aa9755b347247ef66bb74c72 --- /dev/null +++ b/libs/dbus/include/dbus-c++/util.h @@ -0,0 +1,277 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_UTIL_H +#define __DBUSXX_UTIL_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "api.h" +#include "debug.h" + +namespace DBus { + +/* + * Very simple reference counting + */ + +class DXXAPI RefCnt +{ +public: + + RefCnt() + { + __ref = new int; + (*__ref) = 1; + } + + RefCnt( const RefCnt& rc ) + { + __ref = rc.__ref; + ref(); + } + + virtual ~RefCnt() + { + unref(); + } + + RefCnt& operator = ( const RefCnt& ref ) + { + ref.ref(); + unref(); + __ref = ref.__ref; + return *this; + } + + bool noref() const + { + return (*__ref) == 0; + } + + bool one() const + { + return (*__ref) == 1; + } + +private: + + DXXAPILOCAL void ref() const + { + ++ (*__ref); + } + DXXAPILOCAL void unref() const + { + -- (*__ref); + + if( (*__ref) < 0 ) + { + debug_log("%p: refcount dropped below zero!", __ref); + } + + if( noref() ) + { + delete __ref; + } + } + +private: + + int *__ref; +}; + +/* + * Reference counting pointers (emulate boost::shared_ptr) + */ + +template <class T> +class RefPtrI // RefPtr to incomplete type +{ +public: + + RefPtrI( T* ptr = 0 ); + + ~RefPtrI(); + + RefPtrI& operator = ( const RefPtrI& ref ) + { + if( this != &ref ) + { + if(__cnt.one()) delete __ptr; + + __ptr = ref.__ptr; + __cnt = ref.__cnt; + } + return *this; + } + + T& operator *() const + { + return *__ptr; + } + + T* operator ->() const + { + if(__cnt.noref()) return 0; + + return __ptr; + } + + T* get() const + { + if(__cnt.noref()) return 0; + + return __ptr; + } + +private: + + T* __ptr; + RefCnt __cnt; +}; + +template <class T> +class RefPtr +{ +public: + + RefPtr( T* ptr = 0) + : __ptr(ptr) + {} + + ~RefPtr() + { + if(__cnt.one()) delete __ptr; + } + + RefPtr& operator = ( const RefPtr& ref ) + { + if( this != &ref ) + { + if(__cnt.one()) delete __ptr; + + __ptr = ref.__ptr; + __cnt = ref.__cnt; + } + return *this; + } + + T& operator *() const + { + return *__ptr; + } + + T* operator ->() const + { + if(__cnt.noref()) return 0; + + return __ptr; + } + + T* get() const + { + if(__cnt.noref()) return 0; + + return __ptr; + } + +private: + + T* __ptr; + RefCnt __cnt; +}; + +/* + * Typed callback template + */ + +template <class R, class P> +class Callback_Base +{ +public: + + virtual R call( P param ) const = 0; + + virtual ~Callback_Base() + {} +}; + +template <class R, class P> +class Slot +{ +public: + + Slot& operator = ( Callback_Base<R,P>* s ) + { + _cb = s; + + return *this; + } + + R operator()( P param ) const + { + /*if(_cb.get())*/ return _cb->call(param); + } + + R call( P param ) const + { + /*if(_cb.get())*/ return _cb->call(param); + } + + bool empty() + { + return _cb.get() == 0; + } + +private: + + RefPtr< Callback_Base<R,P> > _cb; +}; + +template <class C, class R, class P> +class Callback : public Callback_Base<R,P> +{ +public: + + typedef R (C::*M)(P); + + Callback( C* c, M m ) + : _c(c), _m(m) + {} + + R call( P param ) const + { + /*if(_c)*/ return (_c->*_m)(param); + } + +private: + + C* _c; M _m; +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_UTIL_H diff --git a/libs/dbus/libdbus-c++.spec.in b/libs/dbus/libdbus-c++.spec.in new file mode 100644 index 0000000000000000000000000000000000000000..264e02f23bebf974e676610721d4d16601e529fc --- /dev/null +++ b/libs/dbus/libdbus-c++.spec.in @@ -0,0 +1,62 @@ + + + + +Summary: C++ Interface for DBus +Name: libdbus-c++ +Version: @PACKAGE_VERSION@ +Release: 70001 +URL: http://dev.openwengo.org/trac/openwengo/trac.fcgi/browser/wengophone-ng/branches/wengophone-dbus-api/libs/dbus/src +Source0: %{name}-%{version}.tar.gz +License: LGPL +Group: Libraries +BuildRoot: %{_tmppath}/%{name}-root +Prefix: /usr + +%description + +Ability to reflect dbus methods and signals into a more natural C++ object system. + +%package devel +Requires: libdbus-c++ = %{version} +Group: Development/Libraries +Summary: Header files for libdbus-c++ + +%description devel +Header files for libdbus-c++ + + +%prep +%setup -q + +%build +./configure --prefix=/usr +make -j 4 + +%install +make prefix=$RPM_BUILD_ROOT%{prefix} install + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(755,root,root) +%{prefix}/lib/libdbus-c++*.so* + + + +%files devel +%defattr(-,root,root) +%{prefix}/bin/dbusxx-xml2cpp +%{prefix}/bin/dbusxx-introspect +%{prefix}/lib/libdbus-c*.a +%{prefix}/include/dbus-c++-1 +%{prefix}/lib/pkgconfig/*.pc + +%changelog +* Thu Feb 8 2007 Ben Martin +- initial spec file diff --git a/libs/dbus/src/Makefile.am b/libs/dbus/src/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..b74bb66aea044ddf413c7f70ee39524059712b14 --- /dev/null +++ b/libs/dbus/src/Makefile.am @@ -0,0 +1,43 @@ +AM_CPPFLAGS = \ + $(dbus_CFLAGS) \ + $(glib_CFLAGS) \ + -I$(top_srcdir)/include + +if ENABLE_GLIB +GLIB_H = $(HEADER_DIR)/glib-integration.h +GLIB_CPP = glib-integration.cpp +endif + +HEADER_DIR = $(top_srcdir)/include/dbus-c++ +HEADER_FILES = \ + $(HEADER_DIR)/config.h \ + $(HEADER_DIR)/dbus.h \ + $(HEADER_DIR)/types.h \ + $(HEADER_DIR)/connection.h \ + $(HEADER_DIR)/property.h \ + $(HEADER_DIR)/debug.h \ + $(HEADER_DIR)/error.h \ + $(HEADER_DIR)/interface.h \ + $(HEADER_DIR)/message.h \ + $(HEADER_DIR)/dispatcher.h \ + $(HEADER_DIR)/object.h \ + $(HEADER_DIR)/pendingcall.h \ + $(HEADER_DIR)/server.h \ + $(HEADER_DIR)/debug.h \ + $(HEADER_DIR)/util.h \ + $(HEADER_DIR)/refptr_impl.h \ + $(HEADER_DIR)/introspection.h \ + $(HEADER_DIR)/api.h \ + $(HEADER_DIR)/eventloop.h \ + $(HEADER_DIR)/eventloop-integration.h \ + $(GLIB_H) + +lib_includedir=$(includedir)/dbus-c++-1/dbus-c++/ +lib_include_HEADERS = $(HEADER_FILES) + +lib_LTLIBRARIES = libdbus-c++-1.la +libdbus_c___1_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h eventloop.cpp eventloop-integration.cpp $(GLIB_CPP) +libdbus_c___1_la_LIBADD = $(dbus_LIBS) $(glib_LIBS) $(pthread_LIBS) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/src/connection.cpp b/libs/dbus/src/connection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf43a99f1123d563722ea4e6b3899c06db252590 --- /dev/null +++ b/libs/dbus/src/connection.cpp @@ -0,0 +1,413 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/debug.h> +#include <dbus-c++/connection.h> + +#include <dbus/dbus.h> +#include <string> + +#include "internalerror.h" + +#include "connection_p.h" +#include "dispatcher_p.h" +#include "server_p.h" +#include "message_p.h" +#include "pendingcall_p.h" + +using namespace DBus; + +Connection::Private::Private( DBusConnection* c, Server::Private* s ) +: conn(c) , dispatcher(0), server(s) +{ + init(); +} + +Connection::Private::Private( DBusBusType type ) +{ + InternalError e; + + conn = dbus_bus_get_private(type, e); + + if(e) throw Error(e); + + init(); +} + +Connection::Private::~Private() +{ + debug_log("terminating connection 0x%08x", conn); + + detach_server(); + + if(dbus_connection_get_is_connected(conn)) + { + std::vector<std::string>::iterator i = names.begin(); + + while(i != names.end()) + { + debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str()); + dbus_bus_release_name(conn, i->c_str(), NULL); + ++i; + } + dbus_connection_close(conn); + } + dbus_connection_unref(conn); +} + +void Connection::Private::init() +{ + dbus_connection_ref(conn); + dbus_connection_ref(conn); //todo: the library has to own another reference + + disconn_filter = new Callback<Connection::Private, bool, const Message&>( + this, &Connection::Private::disconn_filter_function + ); + + dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); + + dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0); + dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true?? +} + +void Connection::Private::detach_server() +{ +/* Server::Private* tmp = server; + + server = NULL; + + if(tmp) + { + ConnectionList::iterator i; + + for(i = tmp->connections.begin(); i != tmp->connections.end(); ++i) + { + if(i->_pvt.get() == this) + { + tmp->connections.erase(i); + break; + } + } + }*/ +} + +bool Connection::Private::do_dispatch() +{ + debug_log("dispatching on %p", conn); + + if(!dbus_connection_get_is_connected(conn)) + { + debug_log("connection terminated"); + + detach_server(); + + return true; + } + + return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS; +} + +void Connection::Private::dispatch_status_stub( DBusConnection* dc, DBusDispatchStatus status, void* data ) +{ + Private* p = static_cast<Private*>(data); + + switch(status) + { + case DBUS_DISPATCH_DATA_REMAINS: + debug_log("some dispatching to do on %p", dc); + p->dispatcher->queue_connection(p); + break; + + case DBUS_DISPATCH_COMPLETE: + debug_log("all dispatching done on %p", dc); + break; + + case DBUS_DISPATCH_NEED_MEMORY: //uh oh... + debug_log("connection %p needs memory", dc); + break; + } +} + +DBusHandlerResult Connection::Private::message_filter_stub( DBusConnection* conn, DBusMessage* dmsg, void* data ) +{ + MessageSlot* slot = static_cast<MessageSlot*>(data); + + Message msg = Message(new Message::Private(dmsg)); + + return slot && !slot->empty() && slot->call(msg) + ? DBUS_HANDLER_RESULT_HANDLED + : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +bool Connection::Private::disconn_filter_function( const Message& msg ) +{ + if(msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected")) + { + debug_log("%p disconnected by local bus", conn); + dbus_connection_close(conn); + + return true; + } + return false; +} + +Connection Connection::SystemBus() +{ + return Connection(new Private(DBUS_BUS_SYSTEM)); +} + +Connection Connection::SessionBus() +{ + return Connection(new Private(DBUS_BUS_SESSION)); +} + +Connection Connection::ActivationBus() +{ + return Connection(new Private(DBUS_BUS_STARTER)); +} + +Connection::Connection( const char* address, bool priv ) +{ + InternalError e; + DBusConnection* conn = priv + ? dbus_connection_open_private(address, e) + : dbus_connection_open(address, e); + + if(e) throw Error(e); + + _pvt = new Private(conn); + + setup(default_dispatcher); + + debug_log("connected to %s", address); +} + +Connection::Connection( Connection::Private* p ) +: _pvt(p) +{ + setup(default_dispatcher); +} + +Connection::Connection( const Connection& c ) +: _pvt(c._pvt) +{ + dbus_connection_ref(_pvt->conn); +} + +Connection::~Connection() +{ + dbus_connection_unref(_pvt->conn); +} + +Dispatcher* Connection::setup( Dispatcher* dispatcher ) +{ + debug_log("registering stubs for connection %p", _pvt->conn); + + if(!dispatcher) dispatcher = default_dispatcher; + + if(!dispatcher) throw ErrorFailed("no default dispatcher set for new connection"); + + Dispatcher* prev = _pvt->dispatcher; + + _pvt->dispatcher = dispatcher; + + dispatcher->queue_connection(_pvt.get()); + + dbus_connection_set_watch_functions( + _pvt->conn, + Dispatcher::Private::on_add_watch, + Dispatcher::Private::on_rem_watch, + Dispatcher::Private::on_toggle_watch, + dispatcher, + 0 + ); + + dbus_connection_set_timeout_functions( + _pvt->conn, + Dispatcher::Private::on_add_timeout, + Dispatcher::Private::on_rem_timeout, + Dispatcher::Private::on_toggle_timeout, + dispatcher, + 0 + ); + + return prev; +} + +bool Connection::operator == ( const Connection& c ) const +{ + return _pvt->conn == c._pvt->conn; +} + +bool Connection::register_bus() +{ + InternalError e; + + bool r = dbus_bus_register(_pvt->conn, e); + + if(e) throw (e); + + return r; +} + +bool Connection::connected() const +{ + return dbus_connection_get_is_connected(_pvt->conn); +} + +void Connection::disconnect() +{ +// dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x + dbus_connection_close(_pvt->conn); +} + +void Connection::exit_on_disconnect( bool exit ) +{ + dbus_connection_set_exit_on_disconnect(_pvt->conn, exit); +} + +bool Connection::unique_name( const char* n ) +{ + return dbus_bus_set_unique_name(_pvt->conn, n); +} + +const char* Connection::unique_name() const +{ + return dbus_bus_get_unique_name(_pvt->conn); +} + +void Connection::flush() +{ + dbus_connection_flush(_pvt->conn); +} + +void Connection::add_match( const char* rule ) +{ + InternalError e; + + dbus_bus_add_match(_pvt->conn, rule, e); + + debug_log("%s: added match rule %s", unique_name(), rule); + + if(e) throw Error(e); +} + +void Connection::remove_match( const char* rule ) +{ + InternalError e; + + dbus_bus_remove_match(_pvt->conn, rule, e); + + debug_log("%s: removed match rule %s", unique_name(), rule); + + if(e) throw Error(e); +} + +bool Connection::add_filter( MessageSlot& s ) +{ + debug_log("%s: adding filter", unique_name()); + return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL); +} + +void Connection::remove_filter( MessageSlot& s ) +{ + debug_log("%s: removing filter", unique_name()); + dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s); +} + +bool Connection::send( const Message& msg, unsigned int* serial ) +{ + return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial); +} + +Message Connection::send_blocking( Message& msg, int timeout ) +{ + DBusMessage* reply; + InternalError e; + + reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e); + + if(e) throw Error(e); + + return Message(new Message::Private(reply), false); +} + +PendingCall Connection::send_async( Message& msg, int timeout ) +{ + DBusPendingCall* pending; + + if(!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout)) + { + throw ErrorNoMemory("Unable to start asynchronous call"); + } + return PendingCall(new PendingCall::Private(pending)); +} + +void Connection::request_name( const char* name, int flags ) +{ + InternalError e; + + debug_log("%s: registering bus name %s", unique_name(), name); + + dbus_bus_request_name(_pvt->conn, name, flags, e); //we deliberately don't check return value + + if(e) throw Error(e); + +// this->remove_match("destination"); + + if(name) + { + _pvt->names.push_back(name); + std::string match = "destination='" + _pvt->names.back() + "'"; + add_match(match.c_str()); + } +} + +bool Connection::has_name( const char* name ) +{ + InternalError e; + + bool b = dbus_bus_name_has_owner(_pvt->conn, name, e); + + if(e) throw Error(e); + + return b; +} + +const std::vector<std::string>& Connection::names() +{ + return _pvt->names; +} + +bool Connection::start_service( const char* name, unsigned long flags ) +{ + InternalError e; + + bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e); + + if(e) throw Error(e); + + return b; +} + diff --git a/libs/dbus/src/connection_p.h b/libs/dbus/src/connection_p.h new file mode 100644 index 0000000000000000000000000000000000000000..eec96e38eaf33a466ab4a0ff54595c9df0af3371 --- /dev/null +++ b/libs/dbus/src/connection_p.h @@ -0,0 +1,73 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_CONNECTION_P_H +#define __DBUSXX_CONNECTION_P_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/connection.h> +#include <dbus-c++/server.h> +#include <dbus-c++/dispatcher.h> +#include <dbus-c++/refptr_impl.h> + +#include <dbus/dbus.h> + +#include <string> + +namespace DBus { + +struct DXXAPILOCAL Connection::Private +{ + DBusConnection* conn; + + std::vector<std::string> names; + + Dispatcher* dispatcher; + bool do_dispatch(); + + MessageSlot disconn_filter; + bool disconn_filter_function( const Message& ); + + Server::Private* server; + void detach_server(); + + Private( DBusConnection*, Server::Private* = NULL ); + + Private( DBusBusType ); + + ~Private(); + + void init(); + + static void dispatch_status_stub( DBusConnection*, DBusDispatchStatus, void* ); + + static DBusHandlerResult message_filter_stub( DBusConnection*, DBusMessage*, void* ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_CONNECTION_P_H diff --git a/libs/dbus/src/debug.cpp b/libs/dbus/src/debug.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69d2d08c9bb025251d99adb53a82fae86919aa86 --- /dev/null +++ b/libs/dbus/src/debug.cpp @@ -0,0 +1,53 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/debug.h> + +#include <stdarg.h> +#include <cstdio> +#include <stdlib.h> + +static void _debug_log_default(const char* format, ...) +{ +#ifdef DEBUG + + static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0; + + if(debug_env) + { + va_list args; + va_start(args, format); + + fprintf(stderr, "dbus-c++: "); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + + va_end(args); + } + +#endif//DEBUG +} + +DBus::LogFunction DBus::debug_log = _debug_log_default; + diff --git a/libs/dbus/src/dispatcher.cpp b/libs/dbus/src/dispatcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bed88f85f0a3e8d2bf2476af14e33e6ae06e7206 --- /dev/null +++ b/libs/dbus/src/dispatcher.cpp @@ -0,0 +1,245 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/dispatcher.h> + +#include <dbus/dbus.h> + +#include "dispatcher_p.h" +#include "server_p.h" +#include "connection_p.h" + +DBus::Dispatcher* DBus::default_dispatcher = NULL; + +using namespace DBus; + +Timeout::Timeout( Timeout::Internal* i ) +: _int(i) +{ + dbus_timeout_set_data((DBusTimeout*)i, this, NULL); +} + +int Timeout::interval() const +{ + return dbus_timeout_get_interval((DBusTimeout*)_int); +} + +bool Timeout::enabled() const +{ + return dbus_timeout_get_enabled((DBusTimeout*)_int); +} + +bool Timeout::handle() +{ + return dbus_timeout_handle((DBusTimeout*)_int); +} + +/* +*/ + +Watch::Watch( Watch::Internal* i ) +: _int(i) +{ + dbus_watch_set_data((DBusWatch*)i, this, NULL); +} + +int Watch::descriptor() const +{ + return dbus_watch_get_fd((DBusWatch*)_int); +} + +int Watch::flags() const +{ + return dbus_watch_get_flags((DBusWatch*)_int); +} + +bool Watch::enabled() const +{ + return dbus_watch_get_enabled((DBusWatch*)_int); +} + +bool Watch::handle( int flags ) +{ + return dbus_watch_handle((DBusWatch*)_int, flags); +} + +/* +*/ + +dbus_bool_t Dispatcher::Private::on_add_watch( DBusWatch* watch, void* data ) +{ + Dispatcher* d = static_cast<Dispatcher*>(data); + + Watch::Internal* w = reinterpret_cast<Watch::Internal*>(watch); + + d->add_watch(w); + + return true; +} + +void Dispatcher::Private::on_rem_watch( DBusWatch* watch, void* data ) +{ + Dispatcher* d = static_cast<Dispatcher*>(data); + + Watch* w = static_cast<Watch*>(dbus_watch_get_data(watch)); + + d->rem_watch(w); +} + +void Dispatcher::Private::on_toggle_watch( DBusWatch* watch, void* data ) +{ + Watch* w = static_cast<Watch*>(dbus_watch_get_data(watch)); + + w->toggle(); +} + +dbus_bool_t Dispatcher::Private::on_add_timeout( DBusTimeout* timeout, void* data ) +{ + Dispatcher* d = static_cast<Dispatcher*>(data); + + Timeout::Internal* t = reinterpret_cast<Timeout::Internal*>(timeout); + + d->add_timeout(t); + + return true; +} + +void Dispatcher::Private::on_rem_timeout( DBusTimeout* timeout, void* data ) +{ + Dispatcher* d = static_cast<Dispatcher*>(data); + + Timeout* t = static_cast<Timeout*>(dbus_timeout_get_data(timeout)); + + d->rem_timeout(t); +} + +void Dispatcher::Private::on_toggle_timeout( DBusTimeout* timeout, void* data ) +{ + Timeout* t = static_cast<Timeout*>(dbus_timeout_get_data(timeout)); + + t->toggle(); +} + +void Dispatcher::queue_connection( Connection::Private* cp ) +{ + _mutex_p.lock(); + _pending_queue.push_back(cp); + _mutex_p.unlock(); +} + +void Dispatcher::dispatch_pending() +{ + _mutex_p.lock(); + + while(_pending_queue.size() > 0) + { + Connection::PrivatePList::iterator i, j; + + i = _pending_queue.begin(); + + while(i != _pending_queue.end()) + { + j = i; + + ++j; + + if((*i)->do_dispatch()) + _pending_queue.erase(i); + + i = j; + } + } + _mutex_p.unlock(); +} + +#ifdef DBUS_HAS_THREADS_INIT_DEFAULT +void DBus::_init_threading() +{ + dbus_threads_init_default(); +} +#endif//DBUS_HAS_THREADS_INIT_DEFAULT + +void DBus::_init_threading( + MutexNewFn m1, + MutexFreeFn m2, + MutexLockFn m3, + MutexUnlockFn m4, + CondVarNewFn c1, + CondVarFreeFn c2, + CondVarWaitFn c3, + CondVarWaitTimeoutFn c4, + CondVarWakeOneFn c5, + CondVarWakeAllFn c6 +) +{ +#ifndef DBUS_HAS_RECURSIVE_MUTEX + DBusThreadFunctions functions = { + DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | + DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | + DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | + DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, + (DBusMutexNewFunction) m1, + (DBusMutexFreeFunction) m2, + (DBusMutexLockFunction) m3, + (DBusMutexUnlockFunction) m4, + (DBusCondVarNewFunction) c1, + (DBusCondVarFreeFunction) c2, + (DBusCondVarWaitFunction) c3, + (DBusCondVarWaitTimeoutFunction) c4, + (DBusCondVarWakeOneFunction) c5, + (DBusCondVarWakeAllFunction) c6 + }; +#else + DBusThreadFunctions functions = { + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK | + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK | + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK | + DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| + DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, + 0, 0, 0, 0, + (DBusCondVarNewFunction) c1, + (DBusCondVarFreeFunction) c2, + (DBusCondVarWaitFunction) c3, + (DBusCondVarWaitTimeoutFunction) c4, + (DBusCondVarWakeOneFunction) c5, + (DBusCondVarWakeAllFunction) c6, + (DBusRecursiveMutexNewFunction) m1, + (DBusRecursiveMutexFreeFunction) m2, + (DBusRecursiveMutexLockFunction) m3, + (DBusRecursiveMutexUnlockFunction) m4 + }; +#endif//DBUS_HAS_RECURSIVE_MUTEX + dbus_threads_init(&functions); +} diff --git a/libs/dbus/src/dispatcher_p.h b/libs/dbus/src/dispatcher_p.h new file mode 100644 index 0000000000000000000000000000000000000000..be2dea7db7681389437671b9f2769db3d13c97e0 --- /dev/null +++ b/libs/dbus/src/dispatcher_p.h @@ -0,0 +1,57 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_DISPATCHER_P_H +#define __DBUSXX_DISPATCHER_P_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/dispatcher.h> + +#include <dbus/dbus.h> + +#include "internalerror.h" + +namespace DBus { + +struct DXXAPILOCAL Dispatcher::Private +{ + static dbus_bool_t on_add_watch( DBusWatch* watch, void* data ); + + static void on_rem_watch( DBusWatch* watch, void* data ); + + static void on_toggle_watch( DBusWatch* watch, void* data ); + + static dbus_bool_t on_add_timeout( DBusTimeout* timeout, void* data ); + + static void on_rem_timeout( DBusTimeout* timeout, void* data ); + + static void on_toggle_timeout( DBusTimeout* timeout, void* data ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_DISPATCHER_P_H diff --git a/libs/dbus/src/error.cpp b/libs/dbus/src/error.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92251176a01283012d1188f4d907268ad2ab13cb --- /dev/null +++ b/libs/dbus/src/error.cpp @@ -0,0 +1,86 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/message.h> +#include <dbus-c++/error.h> + +#include <dbus/dbus.h> + +#include "message_p.h" +#include "internalerror.h" + +using namespace DBus; + +/* +*/ + +Error::Error() +: _int(new InternalError) +{} + +Error::Error(InternalError& i) +: _int(new InternalError(i)) +{} + +Error::Error( const char* name, const char* message ) +: _int(new InternalError) +{ + set(name, message); +} + +Error::Error( Message& m ) +: _int(new InternalError) +{ + dbus_set_error_from_message(&(_int->error), m._pvt->msg); +} + +Error::~Error() throw() +{ +} + +const char* Error::name() const +{ + return _int->error.name; +} + +const char* Error::message() const +{ + return _int->error.message; +} + +bool Error::is_set() const +{ + return *(_int); +} + +void Error::set( const char* name, const char* message ) +{ + dbus_set_error_const(&(_int->error), name, message); +} + +const char* Error::what() const throw() +{ + return _int->error.message; +} + diff --git a/libs/dbus/src/eventloop-integration.cpp b/libs/dbus/src/eventloop-integration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9a4b125b62303222df750efa41c86c6e9872497 --- /dev/null +++ b/libs/dbus/src/eventloop-integration.cpp @@ -0,0 +1,163 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/eventloop-integration.h> +#include <dbus-c++/debug.h> + +#include <sys/poll.h> + +#include <dbus/dbus.h> + +using namespace DBus; + +BusTimeout::BusTimeout( Timeout::Internal* ti, BusDispatcher* bd ) +: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd) +{ + DefaultTimeout::enabled(Timeout::enabled()); +} + +void BusTimeout::toggle() +{ + debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); + + DefaultTimeout::enabled(Timeout::enabled()); +} + +BusWatch::BusWatch( Watch::Internal* wi, BusDispatcher* bd ) +: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd) +{ + int flags = POLLHUP | POLLERR; + + if(Watch::flags() & DBUS_WATCH_READABLE) + flags |= POLLIN; + if(Watch::flags() & DBUS_WATCH_WRITABLE) + flags |= POLLOUT; + + DefaultWatch::flags(flags); + DefaultWatch::enabled(Watch::enabled()); +} + +void BusWatch::toggle() +{ + debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); + + DefaultWatch::enabled(Watch::enabled()); +} + +void BusDispatcher::enter() +{ + debug_log("entering dispatcher %p", this); + + _running = true; + + while(_running) + { + do_iteration(); + } + + debug_log("leaving dispatcher %p", this); +} + +void BusDispatcher::leave() +{ + _running = false; +} + +void BusDispatcher::do_iteration() +{ + dispatch_pending(); + dispatch(); +} + +Timeout* BusDispatcher::add_timeout( Timeout::Internal* ti ) +{ + BusTimeout* bt = new BusTimeout(ti, this); + + bt->expired = new Callback<BusDispatcher, void, DefaultTimeout&>(this, &BusDispatcher::timeout_expired); + bt->data(bt); + + debug_log("added timeout %p (%s)", bt, ((Timeout*)bt)->enabled() ? "on":"off"); + + return bt; +} + +void BusDispatcher::rem_timeout( Timeout* t ) +{ + debug_log("removed timeout %p", t); + + delete t; +} + +Watch* BusDispatcher::add_watch( Watch::Internal* wi ) +{ + BusWatch* bw = new BusWatch(wi, this); + + bw->ready = new Callback<BusDispatcher, void, DefaultWatch&>(this, &BusDispatcher::watch_ready); + bw->data(bw); + + debug_log("added watch %p (%s) fd=%d flags=%d", + bw, ((Watch*)bw)->enabled() ? "on":"off", ((Watch*)bw)->descriptor(), ((Watch*)bw)->flags() + ); + + return bw; +} + +void BusDispatcher::rem_watch( Watch* w ) +{ + debug_log("removed watch %p", w); + + delete w; +} + +void BusDispatcher::timeout_expired( DefaultTimeout& et ) +{ + debug_log("timeout %p expired", &et); + + BusTimeout* timeout = reinterpret_cast<BusTimeout*>(et.data()); + + timeout->handle(); +} + +void BusDispatcher::watch_ready( DefaultWatch& ew ) +{ + BusWatch* watch = reinterpret_cast<BusWatch*>(ew.data()); + + debug_log("watch %p ready, flags=%d state=%d", + watch, ((Watch*)watch)->flags(), watch->state() + ); + + int flags = 0; + + if(watch->state() & POLLIN) + flags |= DBUS_WATCH_READABLE; + if(watch->state() & POLLOUT) + flags |= DBUS_WATCH_WRITABLE; + if(watch->state() & POLLHUP) + flags |= DBUS_WATCH_HANGUP; + if(watch->state() & POLLERR) + flags |= DBUS_WATCH_ERROR; + + watch->handle(flags); +} + diff --git a/libs/dbus/src/eventloop.cpp b/libs/dbus/src/eventloop.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32a1044d7c5b4f77913bcc7ef4291f5532bc01d0 --- /dev/null +++ b/libs/dbus/src/eventloop.cpp @@ -0,0 +1,243 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/eventloop.h> +#include <dbus-c++/debug.h> + +#include <sys/poll.h> +#include <sys/time.h> + +#include <dbus/dbus.h> + +using namespace DBus; + +static double millis( timeval tv ) +{ + return (tv.tv_sec*1000.0 + tv.tv_usec/1000.0); +} + +DefaultTimeout::DefaultTimeout( int interval, bool repeat, DefaultMainLoop* ed ) +: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed) +{ + timeval now; + gettimeofday(&now, NULL); + + _expiration = millis(now) + interval; + + _disp->_mutex_t.lock(); + _disp->_timeouts.push_back(this); + _disp->_mutex_t.unlock(); +} + +DefaultTimeout::~DefaultTimeout() +{ + _disp->_mutex_t.lock(); + _disp->_timeouts.remove(this); + _disp->_mutex_t.unlock(); +} + +DefaultWatch::DefaultWatch( int fd, int flags, DefaultMainLoop* ed ) +: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed) +{ + _disp->_mutex_w.lock(); + _disp->_watches.push_back(this); + _disp->_mutex_w.unlock(); +} + +DefaultWatch::~DefaultWatch() +{ + _disp->_mutex_w.lock(); + _disp->_watches.remove(this); + _disp->_mutex_w.unlock(); +} + +DefaultMutex::DefaultMutex() +{ +#if defined HAVE_PTHREAD + + pthread_mutex_init(&_mutex, NULL); + +#elif defined HAVE_WIN32 +#endif +} + +DefaultMutex::~DefaultMutex() +{ +#if defined HAVE_PTHREAD + + pthread_mutex_destroy(&_mutex); + +#elif defined HAVE_WIN32 +#endif +} + +void DefaultMutex::lock() +{ +#if defined HAVE_PTHREAD + + pthread_mutex_lock(&_mutex); + +#elif defined HAVE_WIN32 +#endif +} + +void DefaultMutex::unlock() +{ +#if defined HAVE_PTHREAD + + pthread_mutex_unlock(&_mutex); + +#elif defined HAVE_WIN32 +#endif +} + +DefaultMainLoop::DefaultMainLoop() +{ +} + +DefaultMainLoop::~DefaultMainLoop() +{ + _mutex_w.lock(); + + DefaultWatches::iterator wi = _watches.begin(); + while(wi != _watches.end()) + { + DefaultWatches::iterator wmp = wi; + ++wmp; + delete (*wi); + wi = wmp; + } + _mutex_w.unlock(); + + _mutex_t.lock(); + + DefaultTimeouts::iterator ti = _timeouts.begin(); + while(ti != _timeouts.end()) + { + DefaultTimeouts::iterator tmp = ti; + ++tmp; + delete (*ti); + ti = tmp; + } + _mutex_t.unlock(); +} + +void DefaultMainLoop::dispatch() +{ + _mutex_w.lock(); + + int nfd = _watches.size(); + + pollfd fds[nfd]; + + DefaultWatches::iterator wi = _watches.begin(); + + for(nfd = 0; wi != _watches.end(); ++wi) + { + if((*wi)->enabled()) + { + fds[nfd].fd = (*wi)->descriptor(); + fds[nfd].events = (*wi)->flags(); + fds[nfd].revents = 0; + + ++nfd; + } + } + _mutex_w.unlock(); + + int wait_min = 10000; + + DefaultTimeouts::iterator ti; + + _mutex_t.lock(); + + for(ti = _timeouts.begin(); ti != _timeouts.end(); ++ti) + { + if((*ti)->enabled() && (*ti)->interval() < wait_min) + wait_min = (*ti)->interval(); + } + + _mutex_t.unlock(); + + poll(fds, nfd, wait_min); + + timeval now; + gettimeofday(&now, NULL); + + double now_millis = millis(now); + + _mutex_t.lock(); + + ti = _timeouts.begin(); + + while(ti != _timeouts.end()) + { + DefaultTimeouts::iterator tmp = ti; + ++tmp; + + if((*ti)->enabled() && now_millis >= (*ti)->_expiration) + { + (*ti)->expired(*(*ti)); + + if((*ti)->_repeat) + { + (*ti)->_expiration = now_millis + (*ti)->_interval; + } + + } + + ti = tmp; + } + + _mutex_t.unlock(); + + _mutex_w.lock(); + + for(int j = 0; j < nfd; ++j) + { + DefaultWatches::iterator wi; + + for(wi = _watches.begin(); wi != _watches.end();) + { + DefaultWatches::iterator tmp = wi; + ++tmp; + + if((*wi)->enabled() && (*wi)->_fd == fds[j].fd) + { + if(fds[j].revents) + { + (*wi)->_state = fds[j].revents; + + (*wi)->ready(*(*wi)); + + fds[j].revents = 0; + } + } + + wi = tmp; + } + } + _mutex_w.unlock(); +} + diff --git a/libs/dbus/src/glib-integration.cpp b/libs/dbus/src/glib-integration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42c31ea6ed874f57f3fe20e5f6a438d1f367b0aa --- /dev/null +++ b/libs/dbus/src/glib-integration.cpp @@ -0,0 +1,218 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/glib-integration.h> + +#include <dbus/dbus.h> // for DBUS_WATCH_* + +using namespace DBus; + +Glib::BusTimeout::BusTimeout( Timeout::Internal* ti, GMainContext* ctx ) +: Timeout(ti), _ctx(ctx) +{ + _enable(); +} + +Glib::BusTimeout::~BusTimeout() +{ + _disable(); +} + +void Glib::BusTimeout::toggle() +{ + debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); + + if(Timeout::enabled()) _enable(); + else _disable(); +} + +gboolean Glib::BusTimeout::timeout_handler( gpointer data ) +{ + Glib::BusTimeout* t = reinterpret_cast<Glib::BusTimeout*>(data); + + t->handle(); + + return TRUE; +} + +void Glib::BusTimeout::_enable() +{ + _source = g_timeout_source_new(Timeout::interval()); + g_source_set_callback(_source, timeout_handler, this, NULL); + g_source_attach(_source, _ctx); +} + +void Glib::BusTimeout::_disable() +{ + g_source_destroy(_source); +} + +struct BusSource +{ + GSource source; + GPollFD poll; +}; + +static gboolean watch_prepare( GSource *source, gint *timeout ) +{ +// debug_log("glib: watch_prepare"); + + *timeout = -1; + return FALSE; +} + +static gboolean watch_check( GSource *source ) +{ +// debug_log("glib: watch_check"); + + BusSource* io = (BusSource*)source; + return io->poll.revents ? TRUE : FALSE; +} + +static gboolean watch_dispatch( GSource *source, GSourceFunc callback, gpointer data ) +{ + debug_log("glib: watch_dispatch"); + + gboolean cb = callback(data); + DBus::default_dispatcher->dispatch_pending(); //TODO: won't work in case of multiple dispatchers + return cb; +} + +static GSourceFuncs watch_funcs = { + watch_prepare, + watch_check, + watch_dispatch, + NULL +}; + +Glib::BusWatch::BusWatch( Watch::Internal* wi, GMainContext* ctx ) +: Watch(wi), _ctx(ctx) +{ + _enable(); +} + +Glib::BusWatch::~BusWatch() +{ + _disable(); +} + +void Glib::BusWatch::toggle() +{ + debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); + + if(Watch::enabled()) _enable(); + else _disable(); +} + +gboolean Glib::BusWatch::watch_handler( gpointer data ) +{ + Glib::BusWatch* w = reinterpret_cast<Glib::BusWatch*>(data); + + BusSource* io = (BusSource*)(w->_source); + + int flags = 0; + if(io->poll.revents & G_IO_IN) + flags |= DBUS_WATCH_READABLE; + if(io->poll.revents & G_IO_OUT) + flags |= DBUS_WATCH_WRITABLE; + if(io->poll.revents & G_IO_ERR) + flags |= DBUS_WATCH_ERROR; + if(io->poll.revents & G_IO_HUP) + flags |= DBUS_WATCH_HANGUP; + + w->handle(flags); + + return TRUE; +} + +void Glib::BusWatch::_enable() +{ + _source = g_source_new(&watch_funcs, sizeof(BusSource)); + g_source_set_callback(_source, watch_handler, this, NULL); + + int flags = Watch::flags(); + int condition = 0; + + if(flags & DBUS_WATCH_READABLE) + condition |= G_IO_IN; +// if(flags & DBUS_WATCH_WRITABLE) +// condition |= G_IO_OUT; + if(flags & DBUS_WATCH_ERROR) + condition |= G_IO_ERR; + if(flags & DBUS_WATCH_HANGUP) + condition |= G_IO_HUP; + + GPollFD* poll = &(((BusSource*)_source)->poll); + poll->fd = Watch::descriptor(); + poll->events = condition; + poll->revents = 0; + + g_source_add_poll(_source, poll); + g_source_attach(_source, _ctx); +} + +void Glib::BusWatch::_disable() +{ + GPollFD* poll = &(((BusSource*)_source)->poll); + g_source_remove_poll(_source, poll); + g_source_destroy(_source); +} + +void Glib::BusDispatcher::attach( GMainContext* ctx ) +{ + _ctx = ctx ? ctx : g_main_context_default(); +} + +Timeout* Glib::BusDispatcher::add_timeout( Timeout::Internal* wi ) +{ + Timeout* t = new Glib::BusTimeout(wi, _ctx); + + debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on":"off"); + + return t; +} + +void Glib::BusDispatcher::rem_timeout( Timeout* t ) +{ + debug_log("glib: removed timeout %p", t); + + delete t; +} + +Watch* Glib::BusDispatcher::add_watch( Watch::Internal* wi ) +{ + Watch* w = new Glib::BusWatch(wi, _ctx); + + debug_log("glib: added watch %p (%s) fd=%d flags=%d", + w, w->enabled() ? "on":"off", w->descriptor(), w->flags() + ); + return w; +} + +void Glib::BusDispatcher::rem_watch( Watch* w ) +{ + debug_log("glib: removed watch %p", w); + + delete w; +} diff --git a/libs/dbus/src/interface.cpp b/libs/dbus/src/interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9615973d5813ad05041429e7fc400b506549ee2b --- /dev/null +++ b/libs/dbus/src/interface.cpp @@ -0,0 +1,148 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/debug.h> +#include <dbus-c++/interface.h> + +#include "internalerror.h" + +using namespace DBus; + +Interface::Interface( const std::string& name ) +: _name(name) +{} + +Interface::~Interface() +{} + +InterfaceAdaptor* AdaptorBase::find_interface( const std::string& name ) +{ + InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name); + + return ii != _interfaces.end() ? ii->second : NULL; +} + +InterfaceAdaptor::InterfaceAdaptor( const std::string& name ) +: Interface(name) +{ + debug_log("adding interface %s", name.c_str()); + + _interfaces[name] = this; +} + +Message InterfaceAdaptor::dispatch_method( const CallMessage& msg ) +{ + const char* name = msg.member(); + + MethodTable::iterator mi = _methods.find(name); + if( mi != _methods.end() ) + { + return mi->second.call( msg ); + } + else + { + return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name); + } +} + +void InterfaceAdaptor::emit_signal( const SignalMessage& sig ) +{ + SignalMessage& sig2 = const_cast<SignalMessage&>(sig); + + sig2.interface( name().c_str() ); + _emit_signal(sig2); +} + +Variant* InterfaceAdaptor::get_property( const std::string& name ) +{ + PropertyTable::iterator pti = _properties.find(name); + + if( pti != _properties.end() ) + { + if( !pti->second.read ) + throw ErrorAccessDenied("property is not readable"); + + return &(pti->second.value); + } + return NULL; +} + +void InterfaceAdaptor::set_property( const std::string& name, Variant& value ) +{ + PropertyTable::iterator pti = _properties.find(name); + + if( pti != _properties.end() ) + { + if( !pti->second.write ) + throw ErrorAccessDenied("property is not writeable"); + + Signature sig = value.signature(); + + if( pti->second.sig != sig ) + throw ErrorInvalidSignature("property expects a different type"); + + pti->second.value = value; + return; + } + throw ErrorFailed("requested property not found"); +} + +InterfaceProxy* ProxyBase::find_interface( const std::string& name ) +{ + InterfaceProxyTable::const_iterator ii = _interfaces.find(name); + + return ii != _interfaces.end() ? ii->second : NULL; +} + +InterfaceProxy::InterfaceProxy( const std::string& name ) +: Interface(name) +{ + debug_log("adding interface %s", name.c_str()); + + _interfaces[name] = this; +} + +bool InterfaceProxy::dispatch_signal( const SignalMessage& msg ) +{ + const char* name = msg.member(); + + SignalTable::iterator si = _signals.find(name); + if( si != _signals.end() ) + { + si->second.call( msg ); + return true; + } + else + { + return false; + } +} + +Message InterfaceProxy::invoke_method( const CallMessage& call ) +{ + CallMessage& call2 = const_cast<CallMessage&>(call); + + call2.interface( name().c_str() ); + return _invoke_method(call2); +} diff --git a/libs/dbus/src/internalerror.h b/libs/dbus/src/internalerror.h new file mode 100644 index 0000000000000000000000000000000000000000..0f287e12f192d876d0197453706d64becd9af7ac --- /dev/null +++ b/libs/dbus/src/internalerror.h @@ -0,0 +1,77 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_INTERNALERROR_H +#define __DBUSXX_INTERNALERROR_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/error.h> + +#include <dbus/dbus.h> + +namespace DBus { + +struct DXXAPI InternalError +{ + DBusError error; + + InternalError() + { + dbus_error_init(&error); + } + + explicit InternalError( DBusError* e ) + { + dbus_error_init(&error); + dbus_move_error(e, &error); + } + + InternalError(const InternalError& ie) + { + dbus_error_init(&error); + dbus_move_error(const_cast<DBusError*>(&(ie.error)), &error); + } + + ~InternalError() + { + dbus_error_free(&error); + } + + operator DBusError*() + { + return &error; + } + + operator bool() + { + return dbus_error_is_set(&error); + } +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_INTERNALERROR_H diff --git a/libs/dbus/src/introspection.cpp b/libs/dbus/src/introspection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7fc7b38c3daf70ea811860f50987ed5509482c43 --- /dev/null +++ b/libs/dbus/src/introspection.cpp @@ -0,0 +1,179 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/introspection.h> +#include <dbus-c++/object.h> +#include <dbus-c++/message.h> + +#include <dbus/dbus.h> + +#include <sstream> + +using namespace DBus; + +static const char* introspectable_name = "org.freedesktop.DBus.Introspectable"; + +IntrospectableAdaptor::IntrospectableAdaptor() +: InterfaceAdaptor(introspectable_name) +{ + register_method(IntrospectableAdaptor, Introspect, Introspect); +} + +Message IntrospectableAdaptor::Introspect( const CallMessage& call ) +{ + debug_log("requested introspection data"); + + std::ostringstream xml; + + xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE; + + const std::string path = object()->path(); + + xml << "<node name=\"" << path << "\">"; + + InterfaceAdaptorTable::const_iterator iti; + + for(iti = _interfaces.begin(); iti != _interfaces.end(); ++iti) + { + debug_log("introspecting interface %s", iti->first.c_str()); + + IntrospectedInterface* const intro = iti->second->introspect(); + if(intro) + { + xml << "<interface name=\"" << intro->name << "\">"; + + for(const IntrospectedProperty* p = intro->properties; p->name; ++p) + { + std::string access; + + if(p->read) access += "read"; + if(p->write) access += "write"; + + xml << "<property name=\"" << p->name << "\"" + << " type=\"" << p->type << "\"" + << " access=\"" << access << "\"/>"; + } + + for(const IntrospectedMethod* m = intro->methods; m->args; ++m) + { + xml << "<method name=\"" << m->name << "\">"; + + for(const IntrospectedArgument* a = m->args; a->type; ++a) + { + xml << "<arg direction=\"" << (a->in ? "in" : "out") << "\"" + << " type=\"" << a->type << "\""; + + if(a->name) xml << " name=\"" << a->name << "\""; + + xml << "/>"; + } + + xml << "</method>"; + } + + for(const IntrospectedMethod* m = intro->signals; m->args; ++m) + { + xml << "<signal name=\"" << m->name << "\">"; + + for(const IntrospectedArgument* a = m->args; a->type; ++a) + { + xml << "<arg type=\"" << a->type << "\""; + + if(a->name) xml << " name=\"" << a->name << "\""; + + xml << "/>"; + } + xml << "</signal>"; + } + + xml << "</interface>"; + } + } + const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/'); + + ObjectAdaptorPList::const_iterator oci; + + for(oci = children.begin(); oci != children.end(); ++oci) + { + std::string name = (*oci)->path().substr(path.length()+1); + name.substr(name.find('/')); + + xml << "<node name=\"" << name << "\"/>"; + } + + xml << "</node>"; + + ReturnMessage reply(call); + MessageIter wi = reply.writer(); + wi.append_string(xml.str().c_str()); + return reply; +} + +IntrospectedInterface* const IntrospectableAdaptor::introspect() const +{ + static IntrospectedArgument Introspect_args[] = + { + { "data", "s", false }, + { 0, 0, 0 } + }; + static IntrospectedMethod Introspectable_methods[] = + { + { "Introspect", Introspect_args }, + { 0, 0 } + }; + static IntrospectedMethod Introspectable_signals[] = + { + { 0, 0 } + }; + static IntrospectedProperty Introspectable_properties[] = + { + { 0, 0, 0, 0 } + }; + static IntrospectedInterface Introspectable_interface = + { + introspectable_name, + Introspectable_methods, + Introspectable_signals, + Introspectable_properties + }; + return &Introspectable_interface; +} + +IntrospectableProxy::IntrospectableProxy() +: InterfaceProxy(introspectable_name) +{} + +std::string IntrospectableProxy::Introspect() +{ + DBus::CallMessage call; + + call.member("Introspect"); + + DBus::Message ret = invoke_method(call); + + DBus::MessageIter ri = ret.reader(); + const char* str = ri.get_string(); + + return str; +} diff --git a/libs/dbus/src/message.cpp b/libs/dbus/src/message.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f6d7af36ad3586a16195f94aa3cfe2fa5049f9d --- /dev/null +++ b/libs/dbus/src/message.cpp @@ -0,0 +1,638 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/message.h> + +#include <dbus/dbus.h> + +#include "internalerror.h" +#include "message_p.h" + +using namespace DBus; + +/* +*/ + +int MessageIter::type() +{ + return dbus_message_iter_get_arg_type((DBusMessageIter*)&_iter); +} + +bool MessageIter::at_end() +{ + return type() == DBUS_TYPE_INVALID; +} + +bool MessageIter::has_next() +{ + return dbus_message_iter_has_next((DBusMessageIter*)&_iter); +} + +MessageIter& MessageIter::operator ++() +{ + dbus_message_iter_next((DBusMessageIter*)&_iter); + return (*this); +} + +MessageIter MessageIter::operator ++(int) +{ + MessageIter copy(*this); + ++(*this); + return copy; +} + +bool MessageIter::append_basic( int type_id, void* value ) +{ + return dbus_message_iter_append_basic((DBusMessageIter*)&_iter, type_id, value); +} + +void MessageIter::get_basic( int type_id, void* ptr ) +{ + if(type() != type_id) + throw ErrorInvalidArgs("type mismatch"); + + dbus_message_iter_get_basic((DBusMessageIter*)_iter, ptr); +} + +bool MessageIter::append_byte( unsigned char b ) +{ + return append_basic(DBUS_TYPE_BYTE, &b); +} + +unsigned char MessageIter::get_byte() +{ + unsigned char b; + get_basic(DBUS_TYPE_BYTE, &b); + return b; +} + +bool MessageIter::append_bool( bool b ) +{ + dbus_bool_t db = b; + return append_basic(DBUS_TYPE_BOOLEAN, &db); +} + +bool MessageIter::get_bool() +{ + dbus_bool_t db; + get_basic(DBUS_TYPE_BOOLEAN, &db); + return (bool)db; +} + +bool MessageIter::append_int16( signed short i ) +{ + return append_basic(DBUS_TYPE_INT16, &i); +} + +signed short MessageIter::get_int16() +{ + signed short i; + get_basic(DBUS_TYPE_INT16, &i); + return i; +} + +bool MessageIter::append_uint16( unsigned short u ) +{ + return append_basic(DBUS_TYPE_UINT16, &u); +} + +unsigned short MessageIter::get_uint16() +{ + unsigned short u; + get_basic(DBUS_TYPE_UINT16, &u); + return u; +} + +bool MessageIter::append_int32( signed int i ) +{ + return append_basic(DBUS_TYPE_INT32, &i); +} + +signed int MessageIter::get_int32() +{ + signed int i; + get_basic(DBUS_TYPE_INT32, &i); + return i; +} + +bool MessageIter::append_uint32( unsigned int u ) +{ + return append_basic(DBUS_TYPE_UINT32, &u); +} + +unsigned int MessageIter::get_uint32() +{ + unsigned int u; + get_basic(DBUS_TYPE_UINT32, &u); + return u; +} + +signed long long MessageIter::get_int64() +{ + signed long long i; + get_basic(DBUS_TYPE_INT64, &i); + return i; +} + +bool MessageIter::append_int64( signed long long i ) +{ + return append_basic(DBUS_TYPE_INT64, &i); +} + +unsigned long long MessageIter::get_uint64() +{ + unsigned long long u; + get_basic(DBUS_TYPE_UINT64, &u); + return u; +} + +bool MessageIter::append_uint64( unsigned long long u ) +{ + return append_basic(DBUS_TYPE_UINT64, &u); +} + +double MessageIter::get_double() +{ + double d; + get_basic(DBUS_TYPE_DOUBLE, &d); + return d; +} + +bool MessageIter::append_double( double d ) +{ + return append_basic(DBUS_TYPE_DOUBLE, &d); +} + +bool MessageIter::append_string( const char* chars ) +{ + return append_basic(DBUS_TYPE_STRING, &chars); +} + +const char* MessageIter::get_string() +{ + char* chars; + get_basic(DBUS_TYPE_STRING, &chars); + return chars; +} + +bool MessageIter::append_path( const char* chars ) +{ + return append_basic(DBUS_TYPE_OBJECT_PATH, &chars); +} + +const char* MessageIter::get_path() +{ + char* chars; + get_basic(DBUS_TYPE_OBJECT_PATH, &chars); + return chars; +} + +bool MessageIter::append_signature( const char* chars ) +{ + return append_basic(DBUS_TYPE_SIGNATURE, &chars); +} + +const char* MessageIter::get_signature() +{ + char* chars; + get_basic(DBUS_TYPE_SIGNATURE, &chars); + return chars; +} + +MessageIter MessageIter::recurse() +{ + MessageIter iter(msg()); + dbus_message_iter_recurse((DBusMessageIter*)&_iter, (DBusMessageIter*)&(iter._iter)); + return iter; +} + +char* MessageIter::signature() const +{ + return dbus_message_iter_get_signature((DBusMessageIter*)&_iter); +} + +bool MessageIter::append_array( char type, const void* ptr, size_t length ) +{ + return dbus_message_iter_append_fixed_array((DBusMessageIter*)&_iter, type, &ptr, length); +} + +int MessageIter::array_type() +{ + return dbus_message_iter_get_element_type((DBusMessageIter*)&_iter); +} + +int MessageIter::get_array( void* ptr ) +{ + int length; + dbus_message_iter_get_fixed_array((DBusMessageIter*)&_iter, ptr, &length); + return length; +} + +bool MessageIter::is_array() +{ + return dbus_message_iter_get_arg_type((DBusMessageIter*)&_iter) == DBUS_TYPE_ARRAY; +} + +bool MessageIter::is_dict() +{ + return is_array() && dbus_message_iter_get_element_type((DBusMessageIter*)_iter) == DBUS_TYPE_DICT_ENTRY; +} + +MessageIter MessageIter::new_array( const char* sig ) +{ + MessageIter arr(msg()); + dbus_message_iter_open_container( + (DBusMessageIter*)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter*)&(arr._iter) + ); + return arr; +} + +MessageIter MessageIter::new_variant( const char* sig ) +{ + MessageIter var(msg()); + dbus_message_iter_open_container( + (DBusMessageIter*)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter*)&(var._iter) + ); + return var; +} + +MessageIter MessageIter::new_struct() +{ + MessageIter stu(msg()); + dbus_message_iter_open_container( + (DBusMessageIter*)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter*)&(stu._iter) + ); + return stu; +} + +MessageIter MessageIter::new_dict_entry() +{ + MessageIter ent(msg()); + dbus_message_iter_open_container( + (DBusMessageIter*)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter*)&(ent._iter) + ); + return ent; +} + +void MessageIter::close_container( MessageIter& container ) +{ + dbus_message_iter_close_container((DBusMessageIter*)&_iter, (DBusMessageIter*)&(container._iter)); +} + +static bool is_basic_type(int typecode) +{ + switch(typecode) + { + case 'y': + case 'b': + case 'n': + case 'q': + case 'i': + case 'u': + case 'x': + case 't': + case 'd': + case 's': + case 'o': + case 'g': + return true; + default: + return false; + } +} + +void MessageIter::copy_data( MessageIter& to ) +{ + for(MessageIter& from = *this; !from.at_end(); ++from) + { + if(is_basic_type(from.type())) + { + debug_log("copying basic type: %c", from.type()); + + unsigned char value[8]; + from.get_basic(from.type(), &value); + to.append_basic(from.type(), &value); + } + else + { + MessageIter from_container = from.recurse(); + char* sig = from_container.signature(); + + debug_log("copying compound type: %c[%s]", from.type(), sig); + + MessageIter to_container (to.msg()); + dbus_message_iter_open_container + ( + (DBusMessageIter*)&(to._iter), + from.type(), + from.type() == DBUS_TYPE_VARIANT ? NULL : sig, + (DBusMessageIter*)&(to_container._iter) + ); + + from_container.copy_data(to_container); + to.close_container(to_container); + free(sig); + } + } +} + +/* +*/ + +Message::Message() +: _pvt(new Private) +{ +} + +Message::Message( Message::Private* p, bool incref ) +: _pvt(p) +{ + if(_pvt->msg && incref) dbus_message_ref(_pvt->msg); +} + +Message::Message( const Message& m ) +: _pvt(m._pvt) +{ + dbus_message_ref(_pvt->msg); +} + +Message::~Message() +{ + dbus_message_unref(_pvt->msg); +} + +Message& Message::operator = ( const Message& m ) +{ + if(&m != this) + { + dbus_message_unref(_pvt->msg); + _pvt = m._pvt; + dbus_message_ref(_pvt->msg); + } + return *this; +} + +Message Message::copy() +{ + Private* pvt = new Private(dbus_message_copy(_pvt->msg)); + return Message(pvt); +} + +bool Message::append( int first_type, ... ) +{ + va_list vl; + va_start(vl, first_type); + + bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl); + + va_end(vl); + return b; +} + +void Message::terminate() +{ + dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID); +} + +int Message::type() const +{ + return dbus_message_get_type(_pvt->msg); +} + +int Message::serial() const +{ + return dbus_message_get_serial(_pvt->msg); +} + +int Message::reply_serial() const +{ + return dbus_message_get_reply_serial(_pvt->msg); +} + +bool Message::reply_serial( int s ) +{ + return dbus_message_set_reply_serial(_pvt->msg, s); +} + +const char* Message::sender() const +{ + return dbus_message_get_sender(_pvt->msg); +} + +bool Message::sender( const char* s ) +{ + return dbus_message_set_sender(_pvt->msg, s); +} + +const char* Message::destination() const +{ + return dbus_message_get_destination(_pvt->msg); +} + +bool Message::destination( const char* s ) +{ + return dbus_message_set_destination(_pvt->msg, s); +} + +bool Message::is_error() const +{ + return type() == DBUS_MESSAGE_TYPE_ERROR; +} + +bool Message::is_signal( const char* interface, const char* member ) const +{ + return dbus_message_is_signal(_pvt->msg, interface, member); +} + +MessageIter Message::writer() +{ + MessageIter iter(*this); + dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter*)&(iter._iter)); + return iter; +} + +MessageIter Message::reader() const +{ + MessageIter iter(const_cast<Message&>(*this)); + dbus_message_iter_init(_pvt->msg, (DBusMessageIter*)&(iter._iter)); + return iter; +} + +/* +*/ + +ErrorMessage::ErrorMessage() +{ + _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); +} + +ErrorMessage::ErrorMessage( const Message& to_reply, const char* name, const char* message ) +{ + _pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message); +} + +bool ErrorMessage::operator == ( const ErrorMessage& m ) const +{ + return dbus_message_is_error(_pvt->msg, m.name()); +} + +const char* ErrorMessage::name() const +{ + return dbus_message_get_error_name(_pvt->msg); +} + +bool ErrorMessage::name( const char* n ) +{ + return dbus_message_set_error_name(_pvt->msg, n); +} + +/* +*/ + +SignalMessage::SignalMessage( const char* name ) +{ + _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); + member(name); +} + +SignalMessage::SignalMessage( const char* path, const char* interface, const char* name ) +{ + _pvt->msg = dbus_message_new_signal(path, interface, name); +} + +bool SignalMessage::operator == ( const SignalMessage& m ) const +{ + return dbus_message_is_signal(_pvt->msg, m.interface(), m.member()); +} + +const char* SignalMessage::interface() const +{ + return dbus_message_get_interface(_pvt->msg); +} + +bool SignalMessage::interface( const char* i ) +{ + return dbus_message_set_interface(_pvt->msg, i); +} + +const char* SignalMessage::member() const +{ + return dbus_message_get_member(_pvt->msg); +} + +bool SignalMessage::member( const char* m ) +{ + return dbus_message_set_member(_pvt->msg, m); +} + +const char* SignalMessage::path() const +{ + return dbus_message_get_path(_pvt->msg); +} + +char** SignalMessage::path_split() const +{ + char** p; + dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ? + return p; +} + +bool SignalMessage::path( const char* p ) +{ + return dbus_message_set_path(_pvt->msg, p); +} + +/* +*/ + +CallMessage::CallMessage() +{ + _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL); +} + +CallMessage::CallMessage( const char* dest, const char* path, const char* iface, const char* method ) +{ + _pvt->msg = dbus_message_new_method_call(dest, path, iface, method); +} + +bool CallMessage::operator == ( const CallMessage& m ) const +{ + return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member()); +} + +const char* CallMessage::interface() const +{ + return dbus_message_get_interface(_pvt->msg); +} + +bool CallMessage::interface( const char* i ) +{ + return dbus_message_set_interface(_pvt->msg, i); +} + +const char* CallMessage::member() const +{ + return dbus_message_get_member(_pvt->msg); +} + +bool CallMessage::member( const char* m ) +{ + return dbus_message_set_member(_pvt->msg, m); +} + +const char* CallMessage::path() const +{ + return dbus_message_get_path(_pvt->msg); +} + +char** CallMessage::path_split() const +{ + char** p; + dbus_message_get_path_decomposed(_pvt->msg, &p); + return p; +} + +bool CallMessage::path( const char* p ) +{ + return dbus_message_set_path(_pvt->msg, p); +} + +const char* CallMessage::signature() const +{ + return dbus_message_get_signature(_pvt->msg); +} + +/* +*/ + +ReturnMessage::ReturnMessage( const CallMessage& callee ) +{ + _pvt = new Private(dbus_message_new_method_return(callee._pvt->msg)); +} + +const char* ReturnMessage::signature() const +{ + return dbus_message_get_signature(_pvt->msg); +} + diff --git a/libs/dbus/src/message_p.h b/libs/dbus/src/message_p.h new file mode 100644 index 0000000000000000000000000000000000000000..c080d01918a29fea758d40d64ab1066751e518a1 --- /dev/null +++ b/libs/dbus/src/message_p.h @@ -0,0 +1,52 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_MESSAGE_P_H +#define __DBUSXX_MESSAGE_P_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/message.h> +#include <dbus-c++/refptr_impl.h> + +#include <dbus/dbus.h> + +namespace DBus { + +struct DXXAPILOCAL Message::Private +{ + DBusMessage* msg; + + Private() : msg(0) + {} + + Private( DBusMessage* m ) : msg(m) + {} +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_MESSAGE_P_H diff --git a/libs/dbus/src/object.cpp b/libs/dbus/src/object.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8f9b8dfc1de52748e484d9f38efb56cd2a5a36bd --- /dev/null +++ b/libs/dbus/src/object.cpp @@ -0,0 +1,352 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/debug.h> +#include <dbus-c++/object.h> +#include "internalerror.h" + +#include <map> +#include <dbus/dbus.h> + +#include "message_p.h" +#include "server_p.h" +#include "connection_p.h" + +using namespace DBus; + +Object::Object( Connection& conn, const Path& path, const char* service ) +: _conn(conn), _path(path), _service(service ? service : "") +{ +} + +Object::~Object() +{ +} + +struct ObjectAdaptor::Private +{ + static void unregister_function_stub( DBusConnection*, void* ); + static DBusHandlerResult message_function_stub( DBusConnection*, DBusMessage*, void* ); +}; + +static DBusObjectPathVTable _vtable = +{ + ObjectAdaptor::Private::unregister_function_stub, + ObjectAdaptor::Private::message_function_stub, + NULL, NULL, NULL, NULL +}; + +void ObjectAdaptor::Private::unregister_function_stub( DBusConnection* conn, void* data ) +{ + //TODO: what do we have to do here ? +} + +DBusHandlerResult ObjectAdaptor::Private::message_function_stub( DBusConnection*, DBusMessage* dmsg, void* data ) +{ + ObjectAdaptor* o = static_cast<ObjectAdaptor*>(data); + + if( o ) + { + Message msg(new Message::Private(dmsg)); + + debug_log("in object %s", o->path().c_str()); + debug_log(" got message #%d from %s to %s", + msg.serial(), + msg.sender(), + msg.destination() + ); + + return o->handle_message(msg) + ? DBUS_HANDLER_RESULT_HANDLED + : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + else + { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } +} + +typedef std::map<Path, ObjectAdaptor*> ObjectAdaptorTable; +static ObjectAdaptorTable _adaptor_table; + +ObjectAdaptor* ObjectAdaptor::from_path( const Path& path ) +{ + ObjectAdaptorTable::iterator ati = _adaptor_table.find(path); + + if(ati != _adaptor_table.end()) + return ati->second; + + return NULL; +} + +ObjectAdaptorPList ObjectAdaptor::from_path_prefix( const std::string& prefix ) +{ + ObjectAdaptorPList ali; + + ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); + + size_t plen = prefix.length(); + + while(ati != _adaptor_table.end()) + { + if(!strncmp(ati->second->path().c_str(), prefix.c_str(), plen)) + ali.push_back(ati->second); + + ++ati; + } + + return ali; +} + +ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path ) +: Object(conn, path, conn.unique_name()) +{ + register_obj(); +} + +ObjectAdaptor::~ObjectAdaptor() +{ + unregister_obj(); +} + +void ObjectAdaptor::register_obj() +{ + debug_log("registering local object %s", path().c_str()); + + if(!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this)) + { + throw ErrorNoMemory("unable to register object path"); + } + else + { + InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); + while( ii != _interfaces.end() ) + { + std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'"; + conn().add_match(im.c_str()); + ++ii; + } + } + + _adaptor_table[path()] = this; +} + +void ObjectAdaptor::unregister_obj() +{ + _adaptor_table.erase(path()); + + debug_log("unregistering local object %s", path().c_str()); + + dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str()); + + InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); + while( ii != _interfaces.end() ) + { + std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'"; + conn().remove_match(im.c_str()); + ++ii; + } +} + +void ObjectAdaptor::_emit_signal( SignalMessage& sig ) +{ + sig.path(path().c_str()); + + conn().send(sig); +} + +struct ReturnLaterError +{ + const Tag* tag; +}; + +bool ObjectAdaptor::handle_message( const Message& msg ) +{ + switch( msg.type() ) + { + case DBUS_MESSAGE_TYPE_METHOD_CALL: + { + const CallMessage& cmsg = reinterpret_cast<const CallMessage&>(msg); + const char* member = cmsg.member(); + const char* interface = cmsg.interface(); + + debug_log(" invoking method %s.%s", interface, member); + + InterfaceAdaptor* ii = find_interface(interface); + if( ii ) + { + try + { + Message ret = ii->dispatch_method(cmsg); + conn().send(ret); + } + catch(Error& e) + { + ErrorMessage em(cmsg, e.name(), e.message()); + conn().send(em); + } + catch(ReturnLaterError& rle) + { + _continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag); + } + return true; + } + else + { + return false; + } + } + default: + { + return false; + } + } +} + +void ObjectAdaptor::return_later( const Tag* tag ) +{ + ReturnLaterError rle = { tag }; + throw rle; +} + +void ObjectAdaptor::return_now( Continuation* ret ) +{ + ret->_conn.send(ret->_return); + + ContinuationMap::iterator di = _continuations.find(ret->_tag); + + delete di->second; + + _continuations.erase(di); +} + +void ObjectAdaptor::return_error( Continuation* ret, const Error error ) +{ + ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message())); + + ContinuationMap::iterator di = _continuations.find(ret->_tag); + + delete di->second; + + _continuations.erase(di); +} + +ObjectAdaptor::Continuation* ObjectAdaptor::find_continuation( const Tag* tag ) +{ + ContinuationMap::iterator di = _continuations.find(tag); + + return di != _continuations.end() ? di->second : NULL; +} + +ObjectAdaptor::Continuation::Continuation( Connection& conn, const CallMessage& call, const Tag* tag ) +: _conn(conn), _call(call), _return(_call), _tag(tag) +{ + _writer = _return.writer(); //todo: verify +} + +/* +*/ + +ObjectProxy::ObjectProxy( Connection& conn, const Path& path, const char* service ) +: Object(conn, path, service) +{ + register_obj(); +} + +ObjectProxy::~ObjectProxy() +{ + unregister_obj(); +} + +void ObjectProxy::register_obj() +{ + debug_log("registering remote object %s", path().c_str()); + + _filtered = new Callback<ObjectProxy, bool, const Message&>(this, &ObjectProxy::handle_message); + + conn().add_filter(_filtered); + + InterfaceProxyTable::const_iterator ii = _interfaces.begin(); + while( ii != _interfaces.end() ) + { + std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'"; + conn().add_match(im.c_str()); + ++ii; + } +} + +void ObjectProxy::unregister_obj() +{ + debug_log("unregistering remote object %s", path().c_str()); + + InterfaceProxyTable::const_iterator ii = _interfaces.begin(); + while( ii != _interfaces.end() ) + { + std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'"; + conn().remove_match(im.c_str()); + ++ii; + } + conn().remove_filter(_filtered); +} + +Message ObjectProxy::_invoke_method( CallMessage& call ) +{ + call.path(path().c_str()); + call.destination(service().c_str()); + + return conn().send_blocking(call, 2000); +} + +bool ObjectProxy::handle_message( const Message& msg ) +{ + switch( msg.type() ) + { + case DBUS_MESSAGE_TYPE_SIGNAL: + { + const SignalMessage& smsg = reinterpret_cast<const SignalMessage&>(msg); + const char* interface = smsg.interface(); + const char* member = smsg.member(); + const char* objpath = smsg.path(); + + if( objpath != path() ) return false; + + debug_log("filtered signal %s(in %s) from %s to object %s", + member, interface, msg.sender(), objpath); + + InterfaceProxy* ii = find_interface(interface); + if( ii ) + { + return ii->dispatch_signal(smsg); + } + else + { + return false; + } + } + default: + { + return false; + } + } +} diff --git a/libs/dbus/src/pendingcall.cpp b/libs/dbus/src/pendingcall.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4696983f20f53023d687d56ae5dd2c2aa316d0f6 --- /dev/null +++ b/libs/dbus/src/pendingcall.cpp @@ -0,0 +1,139 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/pendingcall.h> + +#include <dbus/dbus.h> + +#include "internalerror.h" +#include "pendingcall_p.h" +#include "message_p.h" + +using namespace DBus; + +PendingCall::Private::Private( DBusPendingCall* dpc ) +: call(dpc), dataslot(-1) +{ + if(!dbus_pending_call_allocate_data_slot(&dataslot)) + { + throw ErrorNoMemory("Unable to allocate data slot"); + } +} + +PendingCall::Private::~Private() +{ + if(dataslot != -1) + { + dbus_pending_call_allocate_data_slot(&dataslot); + } +} + +void PendingCall::Private::notify_stub( DBusPendingCall* dpc, void* data ) +{ + PendingCall::Private* pvt = static_cast<PendingCall::Private*>(data); + + PendingCall pc(pvt); + pvt->slot(pc); +} + +PendingCall::PendingCall( PendingCall::Private* p ) +: _pvt(p) +{ + if(!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL)) + { + throw ErrorNoMemory("Unable to initialize pending call"); + } +} + +PendingCall::PendingCall( const PendingCall& c ) +: _pvt(c._pvt) +{ + dbus_pending_call_ref(_pvt->call); +} + +PendingCall::~PendingCall() +{ + dbus_pending_call_unref(_pvt->call); +} + +PendingCall& PendingCall::operator = ( const PendingCall& c ) +{ + if(&c != this) + { + dbus_pending_call_unref(_pvt->call); + _pvt = c._pvt; + dbus_pending_call_ref(_pvt->call); + } + return *this; +} + +bool PendingCall::completed() +{ + return dbus_pending_call_get_completed(_pvt->call); +} + +void PendingCall::cancel() +{ + dbus_pending_call_cancel(_pvt->call); +} + +void PendingCall::block() +{ + dbus_pending_call_block(_pvt->call); +} + +void PendingCall::data( void* p ) +{ + if(!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL)) + { + throw ErrorNoMemory("Unable to initialize data slot"); + } +} + +void* PendingCall::data() +{ + return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot); +} + +Slot<void, PendingCall&>& PendingCall::slot() +{ + return _pvt->slot; +} + +Message PendingCall::steal_reply() +{ + DBusMessage* dmsg = dbus_pending_call_steal_reply(_pvt->call); + if(!dmsg) + { + dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call); + + if(callComplete) + throw ErrorNoReply("No reply available"); + else + throw ErrorNoReply("Call not complete"); + } + + return Message( new Message::Private(dmsg) ); +} + diff --git a/libs/dbus/src/pendingcall_p.h b/libs/dbus/src/pendingcall_p.h new file mode 100644 index 0000000000000000000000000000000000000000..0c5e7bc44917e09108add29b6854cfea2208da79 --- /dev/null +++ b/libs/dbus/src/pendingcall_p.h @@ -0,0 +1,54 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_PENDING_CALL_P_H +#define __DBUSXX_PENDING_CALL_P_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/pendingcall.h> +#include <dbus-c++/refptr_impl.h> + +#include <dbus/dbus.h> + +namespace DBus { + +struct DXXAPILOCAL PendingCall::Private +{ + DBusPendingCall* call; + int dataslot; + Slot<void, PendingCall&> slot; + + Private( DBusPendingCall* ); + + ~Private(); + + static void notify_stub( DBusPendingCall* dpc, void* data ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_PENDING_CALL_P_H diff --git a/libs/dbus/src/property.cpp b/libs/dbus/src/property.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd196cd9b04311e041857f973f83025bd9a84f94 --- /dev/null +++ b/libs/dbus/src/property.cpp @@ -0,0 +1,151 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <dbus-c++/debug.h> +#include <dbus-c++/property.h> + +#include <dbus-c++/introspection.h> + +using namespace DBus; + +static const char* properties_name = "org.freedesktop.DBus.Properties"; + +PropertiesAdaptor::PropertiesAdaptor() +: InterfaceAdaptor(properties_name) +{ + register_method(PropertiesAdaptor, Get, Get); + register_method(PropertiesAdaptor, Set, Set); +} + +Message PropertiesAdaptor::Get( const CallMessage& call ) +{ + MessageIter ri = call.reader(); + + String iface_name; + String property_name; + + ri >> iface_name >> property_name; + + debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str()); + + InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name); + + if(!interface) + throw ErrorFailed("requested interface not found"); + + Variant* value = interface->get_property(property_name); + + if(!value) + throw ErrorFailed("requested property not found"); + + on_get_property(*interface, property_name, *value); + + ReturnMessage reply(call); + + MessageIter wi = reply.writer(); + + wi << *value; + return reply; +} + +Message PropertiesAdaptor::Set( const CallMessage& call ) +{ + MessageIter ri = call.reader(); + + String iface_name; + String property_name; + Variant value; + + ri >> iface_name >> property_name >> value; + + InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name); + + if(!interface) + throw ErrorFailed("requested interface not found"); + + on_set_property(*interface, property_name, value); + + interface->set_property(property_name, value); + + ReturnMessage reply(call); + + return reply; +} + +IntrospectedInterface* const PropertiesAdaptor::introspect() const +{ + static IntrospectedArgument Get_args[] = + { + { "interface_name", "s", true }, + { "property_name", "s", true }, + { "value", "v", false }, + { 0, 0, 0 } + }; + static IntrospectedArgument Set_args[] = + { + { "interface_name", "s", true }, + { "property_name", "s", true }, + { "value", "v", true }, + { 0, 0, 0 } + }; + static IntrospectedMethod Properties_methods[] = + { + { "Get", Get_args }, + { "Set", Set_args }, + { 0, 0 } + }; + static IntrospectedMethod Properties_signals[] = + { + { 0, 0 } + }; + static IntrospectedProperty Properties_properties[] = + { + { 0, 0, 0, 0 } + }; + static IntrospectedInterface Properties_interface = + { + properties_name, + Properties_methods, + Properties_signals, + Properties_properties + }; + return &Properties_interface; +} + +PropertiesProxy::PropertiesProxy() +: InterfaceProxy(properties_name) +{ +} + +Variant PropertiesProxy::Get( const String& iface, const String& property ) +{ +//todo + Variant v; + return v; +} + +void PropertiesProxy::Set( const String& iface, const String& property, const Variant& value ) +{ +//todo +} + diff --git a/libs/dbus/src/server.cpp b/libs/dbus/src/server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b45845d19f4f315524aa8deb917e1dfe6ccd3f57 --- /dev/null +++ b/libs/dbus/src/server.cpp @@ -0,0 +1,126 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/debug.h> +#include <dbus-c++/server.h> + +#include "internalerror.h" +#include "server_p.h" +#include "connection_p.h" +#include "dispatcher_p.h" + +using namespace DBus; + +Server::Private::Private( DBusServer* s ) +: server(s) +{ +} + +Server::Private::~Private() +{ +} + +void Server::Private::on_new_conn_cb( DBusServer* server, DBusConnection* conn, void* data ) +{ + Server* s = static_cast<Server*>(data); + + Connection nc (new Connection::Private(conn, s->_pvt.get())); + + s->_pvt->connections.push_back(nc); + + s->on_new_connection(nc); + + debug_log("incoming connection 0x%08x", conn); +} + +Server::Server( const char* address ) +{ + InternalError e; + DBusServer* server = dbus_server_listen(address, e); + + if(e) throw Error(e); + + debug_log("server 0x%08x listening on %s", server, address); + + _pvt = new Private(server); + + dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL); + + setup(default_dispatcher); +} +/* +Server::Server( const Server& s ) +: _pvt(s._pvt) +{ + dbus_server_ref(_pvt->server); +} +*/ +Server::~Server() +{ + dbus_server_unref(_pvt->server); +} + +Dispatcher* Server::setup( Dispatcher* dispatcher ) +{ + debug_log("registering stubs for server %p", _pvt->server); + + Dispatcher* prev = _pvt->dispatcher; + + dbus_server_set_watch_functions( + _pvt->server, + Dispatcher::Private::on_add_watch, + Dispatcher::Private::on_rem_watch, + Dispatcher::Private::on_toggle_watch, + dispatcher, + 0 + ); + + dbus_server_set_timeout_functions( + _pvt->server, + Dispatcher::Private::on_add_timeout, + Dispatcher::Private::on_rem_timeout, + Dispatcher::Private::on_toggle_timeout, + dispatcher, + 0 + ); + + _pvt->dispatcher = dispatcher; + + return prev; +} + +bool Server::operator == ( const Server& s ) const +{ + return _pvt->server == s._pvt->server; +} + +bool Server::listening() const +{ + return dbus_server_get_is_connected(_pvt->server); +} +void Server::disconnect() +{ + dbus_server_disconnect(_pvt->server); +} + diff --git a/libs/dbus/src/server_p.h b/libs/dbus/src/server_p.h new file mode 100644 index 0000000000000000000000000000000000000000..7eb460884c874fe4e6d862166befc3943fa82298 --- /dev/null +++ b/libs/dbus/src/server_p.h @@ -0,0 +1,57 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_SERVER_P_H +#define __DBUSXX_SERVER_P_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/server.h> +#include <dbus-c++/dispatcher.h> +#include <dbus-c++/refptr_impl.h> + +#include <dbus/dbus.h> + +namespace DBus { + +struct DXXAPILOCAL Server::Private +{ + DBusServer* server; + + Dispatcher* dispatcher; + + ConnectionList connections; + + Private( DBusServer* ); + + ~Private(); + + static void on_new_conn_cb( DBusServer* server, DBusConnection* conn, void* data ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_SERVER_P_H diff --git a/libs/dbus/src/types.cpp b/libs/dbus/src/types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc85fa51a7704c9378ffa9d11c0b8b07b1a3b7da --- /dev/null +++ b/libs/dbus/src/types.cpp @@ -0,0 +1,102 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include <dbus-c++/types.h> +#include <dbus-c++/object.h> +#include <dbus/dbus.h> +#include <stdarg.h> + +#include "message_p.h" +#include "internalerror.h" + +using namespace DBus; + +Variant::Variant() +: _msg(CallMessage()) // dummy message used as temporary storage for variant data +{ +} + +Variant::Variant( MessageIter& it ) +: _msg(CallMessage()) +{ + MessageIter vi = it.recurse(); + MessageIter mi = _msg.writer(); + vi.copy_data(mi); +} + +Variant& Variant::operator = ( const Variant& v ) +{ + if(&v != this) + { + _msg = v._msg; + } + return *this; +} + +void Variant::clear() +{ + CallMessage empty; + _msg = empty; +} + +const Signature Variant::signature() const +{ + char* sigbuf = reader().signature(); + + Signature signature = sigbuf; + + free(sigbuf); + + return signature; +} + +MessageIter& operator << ( MessageIter& iter, const Variant& val ) +{ + const Signature sig = val.signature(); + + MessageIter rit = val.reader(); + MessageIter wit = iter.new_variant(sig.c_str()); + + rit.copy_data(wit); + + iter.close_container(wit); + + return iter; +} + +MessageIter& operator >> ( MessageIter& iter, Variant& val ) +{ + if(iter.type() != DBUS_TYPE_VARIANT) + throw ErrorInvalidArgs("variant type expected"); + + val.clear(); + + MessageIter vit = iter.recurse(); + MessageIter mit = val.writer(); + + vit.copy_data(mit); + + return ++iter; +} + diff --git a/libs/dbus/tools/Makefile.am b/libs/dbus/tools/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..d6044a102a3985a514b13f4e8bb1e14ceb608945 --- /dev/null +++ b/libs/dbus/tools/Makefile.am @@ -0,0 +1,25 @@ +# hacky, but ... + +CXX = $(CXX_FOR_BUILD) + +AM_CPPFLAGS = \ + $(dbus_CFLAGS) \ + $(xml_CFLAGS) \ + -I$(top_srcdir)/include + +if CROSS_COMPILING +libdbus_cxx_la = $(BUILD_LIBDBUS_CXX_DIR)/src/libdbus-c++-1.la +else +libdbus_cxx_la = $(top_builddir)/src/libdbus-c++-1.la +endif + +bin_PROGRAMS = dbusxx-xml2cpp dbusxx-introspect + +dbusxx_xml2cpp_SOURCES = xml.h xml.cpp xml2cpp.h xml2cpp.cpp +dbusxx_xml2cpp_LDADD = $(libdbus_cxx_la) $(xml_LIBS) + +dbusxx_introspect_SOURCES = introspect.h introspect.cpp +dbusxx_introspect_LDADD = $(libdbus_cxx_la) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/libs/dbus/tools/introspect.cpp b/libs/dbus/tools/introspect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcbf1f3dfd3485b2952ea1c1531af138b55070a0 --- /dev/null +++ b/libs/dbus/tools/introspect.cpp @@ -0,0 +1,78 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <signal.h> +#include <unistd.h> +#include <iostream> +#include "introspect.h" + +DBus::BusDispatcher dispatcher; +static bool systembus; +static char* path; +static char* service; + +void niam( int sig ) +{ + DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus(); + + IntrospectedObject io(conn, path, service); + + std::cout << io.Introspect(); + + dispatcher.leave(); +} + +int main( int argc, char** argv ) +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + signal(SIGALRM, niam); + + if(argc == 1) + { + std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl; + } + else + { + if(strcmp(argv[1], "--system")) + { + systembus = false; + path = argv[1]; + service = argc > 2 ? argv[2] : 0; + } + else + { + systembus = true; + path = argv[2]; + service = argc > 3 ? argv[3] : 0; + } + + DBus::default_dispatcher = &dispatcher; + + alarm(1); + + dispatcher.enter(); + } + + return 0; +} diff --git a/libs/dbus/tools/introspect.h b/libs/dbus/tools/introspect.h new file mode 100644 index 0000000000000000000000000000000000000000..36336115a4748fddf94e9cc87f0fe46074595c67 --- /dev/null +++ b/libs/dbus/tools/introspect.h @@ -0,0 +1,44 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_TOOLS_INTROSPECT_H +#define __DBUSXX_TOOLS_INTROSPECT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/dbus.h> +#include <string> + +class IntrospectedObject : public DBus::IntrospectableProxy, public DBus::ObjectProxy +{ +public: + + IntrospectedObject( DBus::Connection& conn, const char* path, const char* service ) + : DBus::ObjectProxy(conn, path, service) + {} +}; + +#endif//__DBUSXX_TOOLS_INTROSPECT_H diff --git a/libs/dbus/tools/xml.cpp b/libs/dbus/tools/xml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69b403e7bfaff49a9d8461babecb1cc3de785c10 --- /dev/null +++ b/libs/dbus/tools/xml.cpp @@ -0,0 +1,315 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include "xml.h" + +#include <dbus-c++/debug.h> + +#include <expat.h> + +std::istream& operator >> ( std::istream& in, DBus::Xml::Document& doc ) +{ + std::stringbuf xmlbuf; + in.get(xmlbuf, '\0'); + doc.from_xml(xmlbuf.str()); + + return in; +} + +std::ostream& operator << ( std::ostream& out, const DBus::Xml::Document& doc ) +{ + return out << doc.to_xml(); +} + +using namespace DBus; +using namespace DBus::Xml; + +Error::Error( const char* error, int line, int column ) +{ + std::ostringstream estream; + + estream << "line " << line << ", column " << column << ": " << error; + + _error = estream.str(); +} + +Node::Node( const char* n, const char** a ) +: name(n) +{ + if(a) + for(int i = 0; a[i]; i += 2) + { + _attrs[a[i]] = a[i+1]; + + //debug_log("xml:\t%s = %s", a[i], a[i+1]); + } +} + +Nodes Nodes::operator[]( const std::string& key ) +{ + Nodes result; + + for(iterator i = begin(); i != end(); ++i) + { + Nodes part = (**i)[key]; + + result.insert(result.end(), part.begin(), part.end()); + } + return result; +} + +Nodes Nodes::select( const std::string& attr, const std::string& value ) +{ + Nodes result; + + for(iterator i = begin(); i != end(); ++i) + { + if((*i)->get(attr) == value) + result.insert(result.end(), *i); + } + return result; +} + +Nodes Node::operator[]( const std::string& key ) +{ + Nodes result; + + if(key.length() == 0) return result; + + for(Children::iterator i = children.begin(); i != children.end(); ++i) + { + if(i->name == key) + result.push_back(&(*i)); + } + return result; +} + +std::string Node::get( const std::string& attribute ) +{ + if(_attrs.find(attribute) != _attrs.end()) + return _attrs[attribute]; + else + return ""; +} + +void Node::set( const std::string& attribute, std::string value ) +{ + if(value.length()) + _attrs[attribute] = value; + else + _attrs.erase(value); +} + +std::string Node::to_xml() const +{ + std::string xml; + int depth = 0; + + _raw_xml(xml, depth); + + return xml; +} + +void Node::_raw_xml( std::string& xml, int& depth ) const +{ + xml.append(depth*2, ' '); + xml.append("<"+name); + + for(Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i) + { + xml.append(" "+i->first+"=\""+i->second+"\""); + } + + if(cdata.length() == 0 && children.size() == 0) + { + xml.append("/>\n"); + } + else + { + xml.append(">"); + + if(cdata.length()) + { + xml.append(cdata); + } + + if(children.size()) + { + xml.append("\n"); + depth++; + + for(Children::const_iterator i = children.begin(); i != children.end(); ++i) + { + i->_raw_xml(xml, depth); + } + + depth--; + xml.append(depth*2, ' '); + } + xml.append("</"+name+">\n"); + } +} + +Document::Document() +: root(0), _depth(0) +{ +} + +Document::Document( const std::string& xml ) +: root(0), _depth(0) +{ + from_xml(xml); +} + +Document::~Document() +{ + delete root; +} + +struct Document::Expat +{ + static void start_doctype_decl_handler( + void* data, const XML_Char* name, const XML_Char* sysid, const XML_Char* pubid, int has_internal_subset + ); + static void end_doctype_decl_handler( void* data ); + static void start_element_handler( void *data, const XML_Char *name, const XML_Char **atts ); + static void character_data_handler( void *data, const XML_Char* chars, int len ); + static void end_element_handler( void *data, const XML_Char *name ); +}; + +void Document::from_xml( const std::string& xml ) +{ + _depth = 0; + delete root; + root = 0; + + XML_Parser parser = XML_ParserCreate("UTF-8"); + + XML_SetUserData(parser, this); + + XML_SetDoctypeDeclHandler( + parser, + Document::Expat::start_doctype_decl_handler, + Document::Expat::end_doctype_decl_handler + ); + + XML_SetElementHandler( + parser, + Document::Expat::start_element_handler, + Document::Expat::end_element_handler + ); + + XML_SetCharacterDataHandler( + parser, + Document::Expat::character_data_handler + ); + + XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true); + + if(status == XML_STATUS_ERROR) + { + const char* error = XML_ErrorString(XML_GetErrorCode(parser)); + int line = XML_GetCurrentLineNumber(parser); + int column = XML_GetCurrentColumnNumber(parser); + + XML_ParserFree(parser); + + throw Error(error, line, column); + } + else + { + XML_ParserFree(parser); + } +} + +std::string Document::to_xml() const +{ + return root->to_xml(); +} + +void Document::Expat::start_doctype_decl_handler( + void* data, const XML_Char* name, const XML_Char* sysid, const XML_Char* pubid, int has_internal_subset +) +{ +} + +void Document::Expat::end_doctype_decl_handler( void* data ) +{ +} + +void Document::Expat::start_element_handler( void *data, const XML_Char *name, const XML_Char **atts ) +{ + Document* doc = (Document*)data; + + //debug_log("xml:%d -> %s", doc->_depth, name); + + if(!doc->root) + { + doc->root = new Node(name, atts); + } + else + { + Node::Children* cld = &(doc->root->children); + + for(int i = 1; i < doc->_depth; ++i) + { + cld = &(cld->back().children); + } + cld->push_back(Node(name, atts)); + + //std::cerr << doc->to_xml() << std::endl; + } + doc->_depth++; +} + +void Document::Expat::character_data_handler( void *data, const XML_Char* chars, int len ) +{ + Document* doc = (Document*)data; + + Node* nod = doc->root; + + for(int i = 1; i < doc->_depth; ++i) + { + nod = &(nod->children.back()); + } + int x, y; + + x = 0; + y = len-1; + + while(isspace(chars[y]) && y > 0) --y; + while(isspace(chars[x]) && x < y) ++x; + + nod->cdata = std::string(chars, x, y+1); +} + +void Document::Expat::end_element_handler( void *data, const XML_Char *name ) +{ + Document* doc = (Document*)data; + + //debug_log("xml:%d <- %s", doc->_depth, name); + + doc->_depth--; +} + diff --git a/libs/dbus/tools/xml.h b/libs/dbus/tools/xml.h new file mode 100644 index 0000000000000000000000000000000000000000..79574c0d1280a06e21d026867abec0962b4ae4f7 --- /dev/null +++ b/libs/dbus/tools/xml.h @@ -0,0 +1,142 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_XML_H +#define __DBUSXX_XML_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <exception> +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <sstream> + +namespace DBus { + +namespace Xml { + +class Error : public std::exception +{ +public: + + Error( const char* error, int line, int column ); + + ~Error() throw() + {} + + const char* what() const throw() + { + return _error.c_str(); + } + +private: + + std::string _error; +}; + +class Node; + +class Nodes : public std::vector<Node*> +{ +public: + + Nodes operator[]( const std::string& key ); + + Nodes select( const std::string& attr, const std::string& value ); +}; + +class Node +{ +public: + + typedef std::map<std::string, std::string> Attributes; + + typedef std::vector<Node> Children; + + std::string name; + std::string cdata; + Children children; + + Node( std::string& n, Attributes& a ) + : name(n), _attrs(a) + {} + + Node( const char* n, const char** a = NULL ); + + Nodes operator[]( const std::string& key ); + + std::string get( const std::string& attribute ); + + void set( const std::string& attribute, std::string value ); + + std::string to_xml() const; + + Node& add( Node child ) + { + children.push_back(child); + return children.back(); + } + +private: + + void _raw_xml( std::string& xml, int& depth ) const; + + Attributes _attrs; +}; + +class Document +{ +public: + + struct Expat; + + Node* root; + + Document(); + + Document( const std::string& xml ); + + ~Document(); + + void from_xml( const std::string& xml ); + + std::string to_xml() const; + +private: + + int _depth; +}; + +} /* namespace Xml */ + +} /* namespace DBus */ + +std::istream& operator >> ( std::istream&, DBus::Xml::Document& ); +std::ostream& operator << ( std::ostream&, DBus::Xml::Document& ); + +#endif//__DBUSXX_XML_H diff --git a/libs/dbus/tools/xml2cpp.cpp b/libs/dbus/tools/xml2cpp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b38c6c4e609552688e2368bbb18190d947fd3d8 --- /dev/null +++ b/libs/dbus/tools/xml2cpp.cpp @@ -0,0 +1,973 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include "xml2cpp.h" + +#include <dbus/dbus.h> + +#include <string> +#include <map> +#include <iostream> +#include <fstream> +#include <sstream> + +using namespace std; +using namespace DBus; + +static const char* tab = " "; + +static const char* header = "\n\ +/*\n\ + * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT!\n\ + */\n\ +\n\ +"; + +static const char* dbus_includes = "\n\ +#include <dbus-c++/dbus.h>\n\ +\n\ +"; + +typedef map<string,string> TypeCache; + +void usage( const char* argv0 ) +{ + cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]" + << endl << endl; + exit(-1); +} + +void underscorize( string& str ) +{ + for(unsigned int i = 0; i < str.length(); ++i) + { + if(!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_'; + } +} + +string stub_name( string name ) +{ + underscorize(name); + + return "_" + name + "_stub"; +} + +int char_to_atomic_type( char t ) +{ + if(strchr("ybnqiuxtdsgavre", t)) + return t; + + return DBUS_TYPE_INVALID; +} + +const char* atomic_type_to_string( char t ) +{ + static struct { char type; char* name; } atos[] = + { + { 'y', "::DBus::Byte" }, + { 'b', "::DBus::Bool" }, + { 'n', "::DBus::Int16" }, + { 'q', "::DBus::UInt16" }, + { 'i', "::DBus::Int32" }, + { 'u', "::DBus::UInt32" }, + { 'x', "::DBus::Int64" }, + { 't', "::DBus::UInt64" }, + { 'd', "::DBus::Double" }, + { 's', "::DBus::String" }, + { 'o', "::DBus::Path" }, + { 'g', "::DBus::Signature" }, + { 'v', "::DBus::Variant" }, + { '\0', "" } + }; + int i; + + for(i = 0; atos[i].type; ++i) + { + if(atos[i].type == t) break; + } + return atos[i].name; +} + +bool is_atomic_type( const string& type ) +{ + return type.length() == 1 && char_to_atomic_type(type[0]) != DBUS_TYPE_INVALID; +} + +void _parse_signature( const string& signature, string& type, unsigned int& i ) +{ + for(; i < signature.length(); ++i) + { + switch(signature[i]) + { + case 'a': + { + switch(signature[++i]) + { + case '{': + { + type += "std::map< "; + + const char* atom = atomic_type_to_string(signature[++i]); + if(!atom) + { + cerr << "invalid signature" << endl; + exit(-1); + } + type += atom; + type += ", "; + ++i; + break; + } + default: + { + type += "std::vector< "; + break; + } + } + _parse_signature(signature, type, i); + type += " >"; + continue; + } + case '(': + { + type += "::DBus::Struct< "; + ++i; + _parse_signature(signature, type, i); + type += " >"; + continue; + } + case ')': + case '}': + { + return; + } + default: + { + const char* atom = atomic_type_to_string(signature[i]); + if(!atom) + { + cerr << "invalid signature" << endl; + exit(-1); + } + type += atom; + + if(signature[i+1] != ')' && signature[i+1] != '}' && i+1 < signature.length()) + { + type += ", "; + } + break; + } + } + } +} + +string signature_to_type( const string& signature ) +{ + string type; + unsigned int i = 0; + _parse_signature(signature, type, i); + return type; +} + +void generate_proxy( Xml::Document& doc, const char* filename ) +{ + cerr << "writing " << filename << endl; + + ofstream file(filename); + if(file.bad()) + { + cerr << "unable to write file " << filename << endl; + exit(-1); + } + + file << header; + string filestring = filename; + underscorize(filestring); + + string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H"; + + file << "#ifndef " << cond_comp << endl; + file << "#define " << cond_comp << endl; + + file << dbus_includes; + + Xml::Node& root = *(doc.root); + Xml::Nodes interfaces = root["interface"]; + + for(Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i) + { + Xml::Node& iface = **i; + Xml::Nodes methods = iface["method"]; + Xml::Nodes signals = iface["signal"]; + Xml::Nodes properties = iface["property"]; + Xml::Nodes ms; + ms.insert(ms.end(), methods.begin(), methods.end()); + ms.insert(ms.end(), signals.begin(), signals.end()); + + string ifacename = iface.get("name"); + if(ifacename == "org.freedesktop.DBus.Introspectable" + ||ifacename == "org.freedesktop.DBus.Properties") + { + cerr << "skipping interface " << ifacename << endl; + continue; + } + + istringstream ss(ifacename); + string nspace; + unsigned int nspaces = 0; + + while(ss.str().find('.', ss.tellg()) != string::npos) + { + getline(ss, nspace, '.'); + + file << "namespace " << nspace << " {" << endl; + + ++nspaces; + } + file << endl; + + string ifaceclass; + + getline(ss, ifaceclass); + + cerr << "generating code for interface " << ifacename << "..." << endl; + + file << "class " << ifaceclass << endl + << " : public ::DBus::InterfaceProxy" << endl + << "{" << endl + << "public:" << endl + << endl + << tab << ifaceclass << "()" << endl + << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl + << tab << "{" << endl; + + for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node& signal = **si; + + string marshname = "_" + signal.get("name") + "_stub"; + + file << tab << tab << "connect_signal(" + << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name")) + << ");" << endl; + } + + file << tab << "}" << endl + << endl; + + file << "public:" << endl + << endl + << tab << "/* methods exported by this interface," << endl + << tab << " * this functions will invoke the corresponding methods on the remote objects" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) + { + Xml::Node& method = **mi; + Xml::Nodes args = method["arg"]; + Xml::Nodes args_in = args.select("direction","in"); + Xml::Nodes args_out = args.select("direction","out"); + + if(args_out.size() == 0 || args_out.size() > 1 ) + { + file << tab << "void "; + } + else if(args_out.size() == 1) + { + file << tab << signature_to_type(args_out.front()->get("type")) << " "; + } + + file << method.get("name") << "( "; + + unsigned int i = 0; + for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) + { + Xml::Node& arg = **ai; + file << "const " << signature_to_type(arg.get("type")) << "& "; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << arg_name; + else + file << "argin" << i; + + if((i+1 != args_in.size() || args_out.size() > 1)) + file << ", "; + } + + if(args_out.size() > 1) + { + unsigned int i = 0; + for(Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i) + { + Xml::Node& arg = **ao; + file << signature_to_type(arg.get("type")) << "&"; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << " " << arg_name; + else + file << " argout" << i; + + if(i+1 != args_out.size()) + file << ", "; + } + } + file << " )" << endl; + + file << tab << "{" << endl + << tab << tab << "::DBus::CallMessage call;" << endl; + + if(args_in.size() > 0) + { + file << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl + << endl; + } + + unsigned int j = 0; + for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++j) + { + Xml::Node& arg = **ai; + string arg_name = arg.get("name"); + if(arg_name.length()) + file << tab << tab << "wi << " << arg_name << ";" << endl; + else + file << tab << tab << "wi << argin" << j << ";" << endl; + } + + file << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl + << tab << tab << "::DBus::Message ret = invoke_method(call);" << endl; + + + if(args_out.size() > 0) + { + file << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl + << endl; + } + + if(args_out.size() == 1) + { + file << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl; + file << tab << tab << "ri >> argout;" << endl; + file << tab << tab << "return argout;" << endl; + } + else if(args_out.size() > 1) + { + unsigned int i = 0; + for(Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i) + { + Xml::Node& arg = **ao; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << tab << tab << "ri >> " << arg.get("name") << ";" << endl; + else + file << tab << tab << "ri >> argout" << i << ";" << endl; + } + } + + file << tab << "}" << endl + << endl; + } + + file << endl + << "public:" << endl + << endl + << tab << "/* signal handlers for this interface" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node& signal = **si; + Xml::Nodes args = signal["arg"]; + + file << tab << "virtual void " << signal.get("name") << "( "; + + unsigned int i = 0; + for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i) + { + Xml::Node& arg = **ai; + file << "const " << signature_to_type(arg.get("type")) << "& "; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << arg_name; + else + file << "argin" << i; + + if((ai+1 != args.end())) + file << ", "; + } + file << " ) = 0;" << endl; + } + + file << endl + << "private:" << endl + << endl + << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node& signal = **si; + Xml::Nodes args = signal["arg"]; + + file << tab << "void " << stub_name(signal.get("name")) << "( const ::DBus::SignalMessage& sig )" << endl + << tab << "{" << endl; + + if(args.size() > 0) + { + file << tab << tab << "::DBus::MessageIter ri = sig.reader();" << endl + << endl; + } + + unsigned int i = 0; + for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i) + { + Xml::Node& arg = **ai; + file << tab << tab << signature_to_type(arg.get("type")) << " " ; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << arg_name << ";" << " ri >> " << arg_name << ";" << endl; + else + file << "arg" << i << ";" << " ri >> " << "arg" << i << ";" << endl; + } + + file << tab << tab << signal.get("name") << "("; + + unsigned int j = 0; + for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++j) + { + Xml::Node& arg = **ai; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << arg_name; + else + file << "arg" << j; + + if(ai+1 != args.end()) + file << ", "; + } + + file << ");" << endl; + + file << tab << "}" << endl; + } + + + file << "};" << endl + << endl; + + for(unsigned int i = 0; i < nspaces; ++i) + { + file << "} "; + } + file << endl; + } + + file << "#endif//" << cond_comp << endl; + + file.close(); +} + +void generate_adaptor( Xml::Document& doc, const char* filename ) +{ + cerr << "writing " << filename << endl; + + ofstream file(filename); + if(file.bad()) + { + cerr << "unable to write file " << filename << endl; + exit(-1); + } + + file << header; + string filestring = filename; + underscorize(filestring); + + string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H"; + + file << "#ifndef " << cond_comp << endl + << "#define " << cond_comp << endl; + + file << dbus_includes; + + Xml::Node& root = *(doc.root); + Xml::Nodes interfaces = root["interface"]; + + for(Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i) + { + Xml::Node& iface = **i; + Xml::Nodes methods = iface["method"]; + Xml::Nodes signals = iface["signal"]; + Xml::Nodes properties = iface["property"]; + Xml::Nodes ms; + ms.insert(ms.end(), methods.begin(), methods.end()); + ms.insert(ms.end(), signals.begin(), signals.end()); + + string ifacename = iface.get("name"); + if(ifacename == "org.freedesktop.DBus.Introspectable" + ||ifacename == "org.freedesktop.DBus.Properties") + { + cerr << "skipping interface " << ifacename << endl; + continue; + } + + istringstream ss(ifacename); + string nspace; + unsigned int nspaces = 0; + + while(ss.str().find('.', ss.tellg()) != string::npos) + { + getline(ss, nspace, '.'); + + file << "namespace " << nspace << " {" << endl; + + ++nspaces; + } + file << endl; + + string ifaceclass; + + getline(ss, ifaceclass); + + cerr << "generating code for interface " << ifacename << "..." << endl; + + file << "class " << ifaceclass << endl + << ": public ::DBus::InterfaceAdaptor" << endl + << "{" << endl + << "public:" << endl + << endl + << tab << ifaceclass << "()" << endl + << tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl + << tab << "{" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + + file << tab << tab << "bind_property(" + << property.get("name") << ", " + << "\"" << property.get("type") << "\", " + << ( property.get("access").find("read") != string::npos + ? "true" + : "false" ) + << ", " + << ( property.get("access").find("write") != string::npos + ? "true" + : "false" ) + << ");" << endl; + } + + for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) + { + Xml::Node& method = **mi; + + file << tab << tab << "register_method(" + << ifaceclass << ", " << method.get("name") << ", "<< stub_name(method.get("name")) + << ");" << endl; + } + + file << tab << "}" << endl + << endl; + + file << tab << "::DBus::IntrospectedInterface* const introspect() const " << endl + << tab << "{" << endl; + + for(Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi) + { + Xml::Node& method = **mi; + Xml::Nodes args = method["arg"]; + + file << tab << tab << "static ::DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl + << tab << tab << "{" << endl; + + for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai) + { + Xml::Node& arg = **ai; + + file << tab << tab << tab << "{ "; + + if(arg.get("name").length()) + { + file << "\"" << arg.get("name") << "\", "; + } + else + { + file << "0, "; + } + file << "\"" << arg.get("type") << "\", " + << ( arg.get("direction") == "in" ? "true" : "false" ) + << " }," << endl; + } + file << tab << tab << tab << "{ 0, 0, 0 }" << endl + << tab << tab << "};" << endl; + } + + file << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl + << tab << tab << "{" << endl; + + for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) + { + Xml::Node& method = **mi; + + file << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl; + } + + file << tab << tab << tab << "{ 0, 0 }" << endl + << tab << tab << "};" << endl; + + file << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl + << tab << tab << "{" << endl; + + for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node& method = **si; + + file << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl; + } + + file << tab << tab << tab << "{ 0, 0 }" << endl + << tab << tab << "};" << endl; + + file << tab << tab << "static ::DBus::IntrospectedProperty " << ifaceclass << "_properties[] = " << endl + << tab << tab << "{" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + + file << tab << tab << tab << "{ " + << "\"" << property.get("name") << "\", " + << "\"" << property.get("type") << "\", " + << ( property.get("access").find("read") != string::npos + ? "true" + : "false" ) + << ", " + << ( property.get("access").find("write") != string::npos + ? "true" + : "false" ) + << " }," << endl; + } + + + file << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl + << tab << tab << "};" << endl; + + file << tab << tab << "static ::DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl + << tab << tab << "{" << endl + << tab << tab << tab << "\"" << ifacename << "\"," << endl + << tab << tab << tab << ifaceclass << "_methods," << endl + << tab << tab << tab << ifaceclass << "_signals," << endl + << tab << tab << tab << ifaceclass << "_properties" << endl + << tab << tab << "};" << endl + << tab << tab << "return &" << ifaceclass << "_interface;" << endl + << tab << "}" << endl + << endl; + + file << "public:" << endl + << endl + << tab << "/* properties exposed by this interface, use" << endl + << tab << " * property() and property(value) to get and set a particular property" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + string name = property.get("name"); + string type = property.get("type"); + string type_name = signature_to_type(type); + + file << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl; + } + + file << endl; + + file << "public:" << endl + << endl + << tab << "/* methods exported by this interface," << endl + << tab << " * you will have to implement them in your ObjectAdaptor" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) + { + Xml::Node& method = **mi; + Xml::Nodes args = method["arg"]; + Xml::Nodes args_in = args.select("direction","in"); + Xml::Nodes args_out = args.select("direction","out"); + + file << tab << "virtual "; + + if(args_out.size() == 0 || args_out.size() > 1 ) + { + file << "void "; + } + else if(args_out.size() == 1) + { + file << signature_to_type(args_out.front()->get("type")) << " "; + } + + file << method.get("name") << "( "; + + unsigned int i = 0; + for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) + { + Xml::Node& arg = **ai; + file << "const " << signature_to_type(arg.get("type")) << "& "; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << arg_name; + + if((i+1 != args_in.size() || args_out.size() > 1)) + file << ", "; + } + + if(args_out.size() > 1) + { + unsigned int i = 0; + for(Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i) + { + Xml::Node& arg = **ao; + file << signature_to_type(arg.get("type")) << "&"; + + string arg_name = arg.get("name"); + if(arg_name.length()) + file << " " << arg_name; + + if(i+1 != args_out.size()) + file << ", "; + } + } + file << " ) = 0;" << endl; + } + + file << endl + << "public:" << endl + << endl + << tab << "/* signal emitters for this interface" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node& signal = **si; + Xml::Nodes args = signal["arg"]; + + file << tab << "void " << signal.get("name") << "( "; + + unsigned int i = 0; + for(Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i) + { + Xml::Node& arg = **a; + + file << "const " << signature_to_type(arg.get("type")) << "& arg" << i+1; + + if(i+1 != args.size()) + file << ", "; + } + + file << " )" << endl + << tab << "{" << endl + << tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") <<"\");" << endl;; + + + if(args.size() > 0) + { + file << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl; + + for(unsigned int i = 0; i < args.size(); ++i) + { + file << tab << tab << "wi << arg" << i+1 << ";" << endl; + } + } + + file << tab << tab << "emit_signal(sig);" << endl + << tab << "}" << endl; + } + + file << endl + << "private:" << endl + << endl + << tab << "/* unmarshalers (to unpack the DBus message before calling the actual interface method)" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) + { + Xml::Node& method = **mi; + Xml::Nodes args = method["arg"]; + Xml::Nodes args_in = args.select("direction","in"); + Xml::Nodes args_out = args.select("direction","out"); + + file << tab << "::DBus::Message " << stub_name(method.get("name")) << "( const ::DBus::CallMessage& call )" << endl + << tab << "{" << endl + << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl + << endl; + + unsigned int i = 1; + for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) + { + Xml::Node& arg = **ai; + file << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";" + << " ri >> argin" << i << ";" << endl; + } + + if(args_out.size() == 0) + { + file << tab << tab; + } + else if(args_out.size() == 1) + { + file << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout1 = "; + } + else + { + unsigned int i = 1; + for(Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i) + { + Xml::Node& arg = **ao; + file << tab << tab << signature_to_type(arg.get("type")) << " argout" << i << ";" << endl; + } + file << tab << tab; + } + + file << method.get("name") << "("; + + for(unsigned int i = 0; i < args_in.size(); ++i) + { + file << "argin" << i+1; + + if((i+1 != args_in.size() || args_out.size() > 1)) + file << ", "; + } + + if(args_out.size() > 1) + for(unsigned int i = 0; i < args_out.size(); ++i) + { + file << "argout" << i+1; + + if(i+1 != args_out.size()) + file << ", "; + } + + file << ");" << endl; + + file << tab << tab << "::DBus::ReturnMessage reply(call);" << endl; + + if(args_out.size() > 0) + { + file << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl; + + for(unsigned int i = 0; i < args_out.size(); ++i) + { + file << tab << tab << "wi << argout" << i+1 << ";" << endl; + } + } + + file << tab << tab << "return reply;" << endl; + + file << tab << "}" << endl; + } + + file << "};" << endl + << endl; + + for(unsigned int i = 0; i < nspaces; ++i) + { + file << "} "; + } + file << endl; + } + + file << "#endif//" << cond_comp << endl; + + file.close(); +} + +int main( int argc, char** argv ) +{ + if(argc < 2) + { + usage(argv[0]); + } + + bool proxy_mode, adaptor_mode; + char *proxy, *adaptor; + + proxy_mode = false; + proxy = 0; + + adaptor_mode = false; + adaptor = 0; + + for(int a = 1; a < argc; ++a) + { + if(!strncmp(argv[a], "--proxy=", 8)) + { + proxy_mode = true; + proxy = argv[a] +8; + } + else + if(!strncmp(argv[a], "--adaptor=", 10)) + { + adaptor_mode = true; + adaptor = argv[a] +10; + } + } + + if(!proxy_mode && !adaptor_mode) usage(argv[0]); + + ifstream xmlfile(argv[1]); + + if(xmlfile.bad()) + { + cerr << "unable to open file " << argv[1] << endl; + return -1; + } + + Xml::Document doc; + + try + { + xmlfile >> doc; + //cout << doc.to_xml(); + } + catch(Xml::Error& e) + { + cerr << "error parsing " << argv[1] << ": " << e.what() << endl; + return -1; + } + + if(!doc.root) + { + cerr << "empty document" << endl; + return -1; + } + + if(proxy_mode) generate_proxy(doc, proxy); + if(adaptor_mode) generate_adaptor(doc, adaptor); + + return 0; +} diff --git a/libs/dbus/tools/xml2cpp.h b/libs/dbus/tools/xml2cpp.h new file mode 100644 index 0000000000000000000000000000000000000000..84f53feacf4fc7f263f3802097e8ff45e9dea6bc --- /dev/null +++ b/libs/dbus/tools/xml2cpp.h @@ -0,0 +1,37 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com> + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_TOOLS_XML2CPP_H +#define __DBUSXX_TOOLS_XML2CPP_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus-c++/dbus.h> +#include <dbus/dbus.h> + +#include "xml.h" + +#endif//__DBUSXX_TOOLS_XML2CPP_H