--- /dev/null
+Keith Preston <keithpre@gmail.com>
+Jussi Kukkonen <jku@o-hand.com>
+Iain Holmes <Iain@openedhand.com>
+Sangho Park <sangho.g.park@samsung.com>
+Tae-Hwan Kim <the81.kim@samsung.com>
+Youngae Kang <youngae.kang@samsung.com>
+Yunhan Kim <yhan.kim@samsung.com>
+Genie Kim <daejins.kim@samsung.com>
--- /dev/null
+Geoclue is licensed under the GNU LPGL Version 2
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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 library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ 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 Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, 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 or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the 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 a program 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.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ 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, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 6. As an exception to the Sections above, you may also compile 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) 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.
+
+ c) 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.
+
+ d) 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 source code 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.
+\f
+ 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 to
+this License.
+\f
+ 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 Library 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.
+\f
+ 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
--- /dev/null
+SUBDIRS = interfaces geoclue providers src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = geoclue.pc
+
+DISTCLEANFILES = \
+ geoclue.pc
+
+EXTRA_DIST = \
+ geoclue.pc.in
+
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
--- /dev/null
+
+Current providers recognise these options:
+
+ * org.freedesktop.Geoclue.GPSDevice
+ Gypsy provider will use this device name
+ (e.g. "00:02:76:C5:81:BF" or "/dev/pgps")
+
+ * org.freedesktop.Geoclue.GPSHost
+ Gpsd provider will contact gpsd on this host.
+ Default is NULL (localhost)
+
+ * org.freedesktop.Geoclue.GPSPort
+ Gpsd provider will contact gpsd on this port.
+ Default is "2947".
+
+
+
+Provider options can be set with SetOptions-method. Geoclue-master
+reads options from gconf (/apps/geoclue/master): as an example, the
+Gypsy device for geoclue master can be set with
+ gconftool-2 \
+ -t string \
+ -s /apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice 00:02:76:C5:81:BF
+
--- /dev/null
+#! /bin/sh
+
+LIBTOOLIZE=libtoolize
+AUTOMAKE=automake
+ACLOCAL=aclocal
+AUTOCONF=autoconf
+AUTOHEADER=autoheader
+
+# Check for binaries
+
+[ "x$(which ${LIBTOOLIZE})x" = "xx" ] && {
+ echo "${LIBTOOLIZE} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${AUTOMAKE})x" = "xx" ] && {
+ echo "${AUTOMAKE} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${ACLOCAL})x" = "xx" ] && {
+ echo "${ACLOCAL} not found. Please install it."
+ exit 1
+}
+
+[ "x$(which ${AUTOCONF})x" = "xx" ] && {
+ echo "${AUTOCONF} not found. Please install it."
+ exit 1
+}
+
+"${ACLOCAL}" \
+&& "${LIBTOOLIZE}" --force \
+&& "${AUTOHEADER}" \
+&& "${AUTOCONF}" \
+&& "${AUTOMAKE}" --add-missing
--- /dev/null
+AC_PREREQ(2.59)
+AC_INIT(geoclue, 0.12.0, http://geoclue.freedesktop.org)
+
+AC_CONFIG_SRCDIR(geoclue/gc-iface-geoclue.c)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE([1.9 foreign])
+GEOCLUE_VERSION=0.12.0
+
+AC_PROG_CC
+AC_ISC_POSIX
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_GCC_TRADITIONAL
+AM_PROG_LIBTOOL
+
+#GTK_DOC_CHECK(1.0)
+AC_CHECK_PROGS(XSLT, xsltproc)
+
+AC_ARG_ENABLE(system-bus,
+ [AC_HELP_STRING([--enable-system-bus],
+ [Use the system bus instead of session bus])],
+ enable_system_bus="$enableval",
+ enable_system_bus=no)
+
+AM_CONDITIONAL(USE_SYSTEM_BUS, test x$enable_system_bus = xyes)
+if test x$enable_system_bus = xyes; then
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SYSTEM, Use the system bus)
+else
+ AC_DEFINE(GEOCLUE_DBUS_BUS, DBUS_BUS_SESSION, Use the session bus)
+fi
+
+PKG_CHECK_MODULES(GEOCLUE, [
+ glib-2.0
+ gobject-2.0
+ dbus-glib-1 >= 0.60
+ libxml-2.0
+])
+AC_SUBST(GEOCLUE_LIBS)
+AC_SUBST(GEOCLUE_CFLAGS)
+
+PKG_CHECK_MODULES(MASTER, [
+ gconf-2.0
+])
+AC_SUBST(MASTER_LIBS)
+AC_SUBST(MASTER_CFLAGS)
+
+AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool)
+AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
+
+DBUS_SERVICES_DIR="${datadir}/dbus-1/services"
+AC_SUBST(DBUS_SERVICES_DIR)
+AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for D-Bus is])
+
+CFLAGS="$CFLAGS -g -Wall -Werror -Wno-format"
+
+# -----------------------------------------------------------
+# gtk+
+# -----------------------------------------------------------
+AC_ARG_ENABLE(gtk,
+ AS_HELP_STRING([--enable-gtk=@<:@no/yes/auto@:>@],
+ [build with gtk support]), ,
+ enable_gtk=no)
+
+if test "x$enable_gtk" != "xno"; then
+ PKG_CHECK_MODULES(GTK,
+ [
+ gtk+-2.0
+ ], have_gtk="yes", have_gtk="no")
+
+ if test "x$have_gtk" = "xyes"; then
+ AC_DEFINE(HAVE_GTK, 1, [Define if you have gtk+])
+ fi
+else
+ have_gtk=no
+fi
+
+if test "x$enable_gtk" = "xyes" -a "x$have_gtk" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find gtk dependencies."])
+fi
+
+AM_CONDITIONAL(HAVE_GTK, test "x$have_gtk" = "xyes")
+AC_SUBST(GTK_LIBS)
+AC_SUBST(GTK_CFLAGS)
+
+# -----------------------------------------------------------
+# connectivity
+# -----------------------------------------------------------
+
+CONNECTIVITY="None"
+
+AC_ARG_ENABLE(conic,
+ AS_HELP_STRING([--enable-conic=@<:@no/yes/auto@:>@],
+ [build with conic support]), ,
+ enable_conic=auto)
+
+if test "x$enable_conic" != "xno"; then
+ PKG_CHECK_MODULES(CONIC,
+ [
+ conic
+ ], have_conic="yes", have_conic="no")
+
+ if test "x$have_conic" = "xyes"; then
+ CONNECTIVITY="Maemo LibConIC"
+ CONNECTIVITY_LIBS=${CONIC_LIBS}
+ CONNECTIVITY_CFLAGS=${CONIC_CFLAGS}
+ AC_DEFINE(HAVE_CONIC, 1, [define if libconic is installed])
+ fi
+else
+ have_conic=no
+fi
+
+if test "x$enable_conic" = "xyes" -a "x$have_conic" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find conic dependencies."])
+fi
+
+AC_ARG_ENABLE(networkmanager,
+ AS_HELP_STRING([--enable-networkmanager=@<:@no/yes/auto@:>@],
+ [build with NetworkManager support]), ,
+ enable_networkmanager=auto)
+
+if test "x$enable_networkmanager" != "xno"; then
+ PKG_CHECK_MODULES(NETWORK_MANAGER,
+ [
+ NetworkManager libnm_glib
+ ], have_networkmanager="yes", have_networkmanager="no")
+
+ if test "x$have_networkmanager" = "xyes"; then
+ CONNECTIVITY="Network Manager"
+ CONNECTIVITY_LIBS=${NETWORK_MANAGER_LIBS}
+ CONNECTIVITY_CFLAGS=${NETWORK_MANAGER_CFLAGS}
+ AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [define if Network Manager is installed])
+ fi
+else
+ have_networkmanager=no
+fi
+
+if test "x$enable_networkmanager" = "xyes" -a "x$have_networkmanager" != "xyes"; then
+ AC_MSG_ERROR(["Couldn't find Network Manager dependencies."])
+fi
+
+AC_SUBST(CONNECTIVITY_LIBS)
+AC_SUBST(CONNECTIVITY_CFLAGS)
+
+PROVIDER_SUBDIRS="nominatim"
+
+AC_SUBST(PROVIDER_SUBDIRS)
+AC_SUBST(NO_BUILD_PROVIDERS)
+
+AC_CONFIG_FILES([
+geoclue.pc
+Makefile
+interfaces/Makefile
+geoclue/Makefile
+providers/Makefile
+providers/gpsd/Makefile
+providers/nominatim/Makefile
+src/Makefile
+])
+#docs/Makefile
+#docs/reference/Makefile
+#docs/tools/Makefile
+
+AC_OUTPUT
+
+echo ""
+echo "Geoclue ${VERSION} has been configured as follows: "
+echo "---------------------------------------------------"
+echo "Source code location: ${srcdir}"
+echo "Compiler: ${CC}"
+echo "Network connectivity: ${CONNECTIVITY}"
+echo "Providers: ${PROVIDER_SUBDIRS}"
+echo "Excluded providers: ${NO_BUILD_PROVIDERS}"
+echo ""
--- /dev/null
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u="sed s,\\\\\\\\,/,g"
+ depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+SUBDIRS = reference tools
+
--- /dev/null
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=geoclue
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../geoclue
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/geoclue/*.h
+CFILE_GLOB=$(top_srcdir)/geoclue/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES= \
+ geoclue-marshal.h \
+ gc-iface-address-bindings.h \
+ gc-iface-reverse-geocode-bindings.h \
+ gc-iface-geoclue-bindings.h \
+ gc-iface-velocity-bindings.h \
+ gc-iface-geocode-bindings.h \
+ gc-iface-position-bindings.h \
+ gc-iface-address-glue.h \
+ gc-iface-reverse-geocode-glue.h \
+ gc-iface-geoclue-glue.h \
+ gc-iface-velocity-glue.h \
+ gc-iface-geocode-glue.h \
+ gc-iface-position-glue.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+dbus_docs = \
+ gc-iface-master-ref.xml \
+ gc-iface-master-client-ref.xml \
+ gc-iface-geoclue-ref.xml \
+ gc-iface-position-ref.xml \
+ gc-iface-address-ref.xml \
+ gc-iface-geocode-ref.xml \
+ gc-iface-reverse-geocode-ref.xml \
+ gc-iface-velocity-ref.xml
+
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files= \
+ implementing-providers.xml \
+ using-geoclue.xml \
+ $(dbus_docs)
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=-I$(top_srcdir) $(GEOCLUE_CFLAGS)
+GTKDOC_LIBS=$(top_builddir)/geoclue/libgeoclue.la $(GEOCLUE_LIBS)
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
+
+CLEAN_FILES = $(dbus_docs)
+
+%-ref.xml: $(top_srcdir)/interfaces/%-full.xml
+ $(XSLT) -o $@ $(top_srcdir)/docs/tools/spec-to-docbook.xsl $<
+
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Geoclue Reference Manual</title>
+ </bookinfo>
+
+ <xi:include href="using-geoclue.xml"/>
+
+ <reference>
+ <title>C API</title>
+ <xi:include href="xml/geoclue-master.xml"/>
+ <xi:include href="xml/geoclue-master-client.xml"/>
+ <xi:include href="xml/geoclue-provider.xml"/>
+ <xi:include href="xml/geoclue-position.xml"/>
+ <xi:include href="xml/geoclue-address.xml"/>
+ <xi:include href="xml/geoclue-velocity.xml"/>
+ <xi:include href="xml/geoclue-geocode.xml"/>
+ <xi:include href="xml/geoclue-reverse-geocode.xml"/>
+ <xi:include href="xml/geoclue-types.xml"/>
+ <xi:include href="xml/geoclue-accuracy.xml"/>
+ <xi:include href="xml/geoclue-address-details.xml"/>
+ <xi:include href="xml/geoclue-error.xml"/>
+ </reference>
+
+ <reference>
+ <title>D-Bus API</title>
+ <xi:include href="gc-iface-master-ref.xml"/>
+ <xi:include href="gc-iface-master-client-ref.xml"/>
+ <xi:include href="gc-iface-geoclue-ref.xml"/>
+ <xi:include href="gc-iface-position-ref.xml"/>
+ <xi:include href="gc-iface-address-ref.xml"/>
+ <xi:include href="gc-iface-velocity-ref.xml"/>
+ <xi:include href="gc-iface-geocode-ref.xml"/>
+ <xi:include href="gc-iface-reverse-geocode-ref.xml"/>
+ </reference>
+
+</book>
--- /dev/null
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-master-client.h>
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-velocity.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-geocode.h>
+#include <geoclue/geoclue-reverse-geocode.h>
+
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-address-details.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/geoclue-types.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+
+geoclue_master_get_type
+geoclue_master_client_get_type
+geoclue_provider_get_type
+geoclue_position_get_type
+geoclue_velocity_get_type
+geoclue_address_get_type
+geoclue_geocode_get_type
+geoclue_reverse_geocode_get_type
+geoclue_error_get_type
+
+gc_web_service_get_type
+gc_provider_get_type
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<chapter>
+ <title>Developing a Geoclue provider</title>
+ <section id="overview">
+ <title>Overview</title>
+ <para>
+ Geoclue providers are D-Bus services that provide geoinformation services
+ by implementing defined interfaces (such as Position, Address or Geocode).
+ Writing a provider is possible in any language with D-Bus, but
+ Geoclue bindings are provided only for C. This how-to will outline the steps
+ needed to write a provider for Geoclue and provides
+ source code in C. The full source code for an exmple provider and several
+ other providers can be found in providers/ directory in the Geoclue source tree.
+ </para>
+ <para>
+ The only must-have requirements for providers are:
+ <itemizedlist>
+ <listitem>Must implement the *Geoclue*-interface. This interface has
+ some generic methods and signals for getting information about the
+ provider and its status </listitem>
+ <listitem>Must provide a service file. This is used by D-Bus to start the
+ service when needed.</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ A useful provider will also implement one, or several, other interfaces. It should
+ also have a .provider-file so GeoclueMaster can use it.
+ This howto will use "Position"-interface as an example. Possible interfaces
+ are listed here:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>Geoclue</term>
+ <listitem><para>Methods and signals common to all providers.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Position</term>
+ <listitem><para>Methods and signals for acquiring current position
+ (latitude, longitude and altitude).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Velocity</term>
+ <listitem><para>Methods and signals for acquiring current velocity.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Address</term>
+ <listitem><para>Methods and signals for acquiring current address
+ (e.g. country, city, street address).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Geocode</term>
+ <listitem><para>Method for geocoding a known address to position.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ReverseGeocode</term>
+ <listitem><para>Method for reverse geocoding a known position to an address.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+
+ <section id="example_in_c">
+ <title>Minimal example in C</title>
+ <para>
+ In this chapter we'll look at implementing a minimal provider (which just implements
+ Geoclue-interface). Next chapter will show how other interface implementations can
+ be added using GObject interfaces.
+ </para>
+ <sect2 id="service_file">
+ <title>Service file</title>
+ <para>
+ Once your provider is installed, the service file allows D-Bus to start it
+ on demand. This is what your
+ org.freedesktop.Geoclue.Providers.MyExample.service.in should look like
+ (see Makefile.am for the processing):
+ </para>
+ <programlisting>
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.MyExample
+Exec=@libexecdir@/geoclue-my-example
+ </programlisting>
+
+ </sect2>
+
+ <sect2 id="provider_file">
+ <title>Provider file</title>
+ <para>
+ Provider files describe the provider for Geoclue Master. This is still
+ somewhat experimental, but a .provider-file for MyExample should look like this:
+ </para>
+ <programlisting>
+[Geoclue Provider]
+Name=My Example
+Service=org.freedesktop.Geoclue.Providers.MyExample
+Path=/org/freedesktop/Geoclue/Providers/MyExample
+Interfaces=org.freedesktop.Geoclue.Position
+Accuracy=0
+Provides=ProvidesUpdates
+Requires=
+ </programlisting>
+ <para>
+ TODO: list accuracylevels, Requires, Provides...
+ </para>
+ </sect2>
+
+ <sect2>
+ <subtitle>Makefile.am and configure.ac</subtitle>
+ <para>
+ A typical provider can be implemented in a single c-file with a very short
+ Makefile.am. This snippet assumes the code is built inside the geoclue source
+ tree:
+ </para>
+ <programlisting>
+libexec_PROGRAMS = geoclue-my-example
+
+geoclue_my_example_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_my_example_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue-provider.la
+
+geoclue_my_example_SOURCES = \
+ geoclue-example.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-my-example.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.MyExample.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+ </programlisting>
+ <para>
+ To get the provider built along with everything else in Geoclue, configure.ac
+ must be edited: The Makefile filename needs to be added into $AC_CONFIG_FILES
+ and the provider directory needs to be added to $PROVIDER_SUBDIRS.
+ </para>
+ </sect2>
+ <sect2>
+
+ <subtitle>The code</subtitle>
+ <para>
+ When coding in C, providers should be implemented as GObjects derived from
+ GcProvider, as GcProvider will take care of the D-Bus service setup (name
+ request and object registration). It will also partially implement the
+ Geoclue-interface.
+ </para>
+
+ <para>
+ First, include gc-provider.h:
+ </para>
+ <programlisting>
+#include <config.h>
+#include <geoclue/gc-provider.h>
+ </programlisting>
+ <para>
+ Define our ExampleProvider GObject (derive from GcProvider):
+ </para>
+ <programlisting>
+typedef struct {
+ GcProvider parent;
+ GMainLoop *loop;
+} GeoclueExample;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueExampleClass;
+
+#define GEOCLUE_TYPE_EXAMPLE (geoclue_example_get_type ())
+#define GEOCLUE_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_EXAMPLE, GeoclueExample))
+
+G_DEFINE_TYPE (GeoclueExample, geoclue_example, GC_TYPE_PROVIDER)
+ </programlisting>
+
+ <para>
+ Next, implement Geoclue-interface functions (take a look at gc-iface-geoclue.h)
+ and use them to override GcProvider:
+ </para>
+ <programlisting>
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ gboolean *available,
+ GError **error)
+{
+ *available = TRUE;
+
+ return TRUE;
+}
+
+static gboolean
+shutdown (GcIfaceGeoclue *gc,
+ GError **error)
+{
+ GeoclueExample *example = GEOCLUE_EXAMPLE (gc);
+
+ g_main_loop_quit (example->loop);
+ return TRUE;
+}
+
+static void
+geoclue_example_class_init (GeoclueExampleClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+}
+ </programlisting>
+ <para>
+ get_status() and shutdown() return TRUE as an indication that the method
+ was succesfully invoked. The actual return values are set in pointer
+ arguments such as "available" in get_status(). See the interface
+ documentation to find out how the functions should behave.
+ </para>
+
+ <para>
+ Next, write a initialization function for the provider:
+ </para>
+ <programlisting>
+static void
+geoclue_example_init (GeoclueExample *example)
+{
+ gc_provider_set_details (GC_PROVIDER (example),
+ "org.freedesktop.Geoclue.Providers.MyExample",
+ "/org/freedesktop/Geoclue/Providers/MyExample",
+ "My Example", "Example provider");
+}
+ </programlisting>
+ <para>
+ GcProvider will use the service name and path to setup the D-Bus service.
+ Name and description (the last two arguments) will be used to implement
+ get_provider_info().
+ </para>
+
+ <para>
+ That's pretty much it. We still need a main() function to run the code:
+ </para>
+ <programlisting>
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueExample *example;
+
+ g_type_init ();
+
+ example = g_object_new (GEOCLUE_TYPE_EXAMPLE, NULL);
+ example->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (example->loop);
+
+ g_main_loop_unref (example->loop);
+ g_object_unref (example);
+
+ return 0;
+}
+ </programlisting>
+
+ <para>
+ The provider should compile and run now. Start it and test with a D-Bus call:
+ </para>
+ <programlisting>
+dbus-send --print-reply \
+ --dest="org.freedesktop.Geoclue.Providers.MyExample" \
+ /org/freedesktop/Geoclue/Providers/MyExample \
+ org.freedesktop.Geoclue.GetProviderInfo
+ </programlisting>
+ </sect2>
+ </section>
+ <section>
+ <title>Adding functionality by implementing other interfaces</title>
+
+ <para>
+ Adding functionality to the (so far fairly impotent) provider is not
+ difficult. These are the steps needed to implement interface X:
+ </para>
+ <itemizedlist>
+ <listitem>Include the interface header (gc-iface-X.h)</listitem>
+ <listitem>Use G_IMPLEMENT_INTERFACE in your provider type definition</listitem>
+ <listitem>Implement the methods and signals defined in gc-iface-X.h</listitem>
+ <listitem>Implement a interface initialization function</listitem>
+ </itemizedlist>
+
+ <para>
+ In our example we're implementing the Position interface:
+ </para>
+ <programlisting>
+#include <geoclue/gc-iface-position.h>
+ </programlisting>
+ <para>
+ The type definition should now look like this:
+ </para>
+ <programlisting>
+static void geoclue_example_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueExample, geoclue_example, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_example_position_init))
+ </programlisting>
+
+ <para>
+ Next, take a look at the interface header (gc-iface-position.h). Implement
+ the interface method and write some signal emission code:
+ </para>
+ <programlisting>
+
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ *fields = GEOCLUE_POSITION_FIELDS_LATITUDE | GEOCLUE_POSITION_FIELDS_LONGITUDE,
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ *latitude = 60.0;
+ *longitude = 25.0;
+
+ return TRUE;
+}
+
+
+
+static gboolean
+emit_position_signal (GeoclueExample *example)
+{
+ static GeoclueAccuracy *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ / * make up some coordinates * /
+ static double lat = 60.0;
+ static double lon = 25.0;
+
+ lat += 0.1;
+ lon -= 0.1;
+
+ g_debug ("Emitting position\n");
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (example),
+ GEOCLUE_POSITION_FIELDS_LATITUDE | GEOCLUE_POSITION_FIELDS_LONGITUDE,
+ time (NULL),
+ lat, lon, 0,
+ accuracy);
+
+ geoclue_accuracy_free (accuracy);
+
+ return TRUE;
+}
+ </programlisting>
+ <para>
+ Yes, this implementation is too useful... For more realistic
+ examples see the included providers in providers/-directory. Note the
+ use of convenience function gc_iface_position_emit_position_changed() for
+ signal emission.
+ </para>
+
+ <para>
+ The example does not have a real position data source, so we'll
+ emulate signal emission: add a g_timeout_add call in main(), before running the
+ main loop.
+ </para>
+ <programlisting>
+g_timeout_add (5000, (GSourceFunc)emit_position_signal, example);
+ </programlisting>
+
+ <para>
+ Finally, the interface method needs to be initialized to the implementation we just defined:
+ </para>
+ <programlisting>
+static void
+geoclue_example_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+ </programlisting>
+ <para>
+ You can try your provider out by starting it and running
+ "example/position-example MyExample"
+ </para>
+ </section>
+</chapter>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<chapter>
+ <title>Using Geoclue in applications</title>
+ <section id="overview">
+ <title>Overview</title>
+ <sect2>
+ <subtitle>Why use Geoclue</subtitle>
+ <para>
+ Building context-sensitive applications is difficult. Location-sensitivy is no
+ exception, but Geoclue tries to help there. With Geoclue it is possible to build
+ location-aware applications with less work and less knowledge about the actual
+ geoinformation sources.
+ </para>
+ <para> Main features of Geoclue are:
+ <itemizedlist>
+ <listitem>Standardized D-Bus (and GObject) interfaces to various geographical data sources</listitem>
+ <listitem>Easy and fast to implement: Need to get data from provider XYZ?
+ Chances are, Geoclue is the easiest way to do that...</listitem>
+ <listitem>Geoclue Master provider (experimental at the moment) makes things eaven easier:
+ you don't even have to choose a data provider, just let Geoclue choose the
+ best possible provider for you.</listitem>
+ <listitem>Adding new providers (data sources) is straight-forward: Even when the geoinformation
+ source you want is not already in Geoclue, Implementing a Geoclue provider may
+ well turn out to be the easiest way forward.</listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ <sect2>
+ <subtitle>Requirements</subtitle>
+ <para>
+ Geoclue is a collection of D-Bus APIs. Internally it's implemented with GLib and GObject (as is the C wrapper library).
+ Several included providers also use Libxml2, and the master provider uses GConf.
+ </para>
+ <para>
+ There is a GObject-based C API, but using Geoclue is possible from any programming language
+ with D-Bus support.
+ </para>
+ </sect2>
+ <sect2>
+ <subtitle>Using basic Geoclue providers</subtitle>
+ <para>
+ D-Bus can automatically start services as they're needed so basic method calls
+ can be made without any preparation. However, geoclue providers may shut down when
+ they're not used. This means that clients using signals and clients that set any options
+ should always use AddReference() and RemoveReference() methods to ensure server
+ persistence. In C the wrapper takes care of this.
+ </para>
+ <para>
+ Clients should not assume that method calls will return instantly or that the
+ response will contain valid data. Examples of possible problems
+ <itemizedlist>
+ <listitem>Many geoclue providers use web services so method calls may take seconds or even time out.</listitem>
+ <listitem>GPS providers usually respond instantly, but will not have a valid data until after getting a fix (which may take anything from a few seconds to minutes)</listitem>
+ </itemizedlist>
+ Using signals should be the first option whenever the used provider supports them.
+ When signals are not available, asynchronous method calls can be used in
+ applications where UI responsiveness is important.
+ </para>
+ </sect2>
+ <sect2>
+ <subtitle>Using Geoclue Master</subtitle>
+ <para>Master provider was designed to solve the following problems:
+ <itemizedlist>
+ <listitem>A single provider cannot be the best solution to all problems</listitem>
+ <listitem>The "best" providers will be different depending on the user</listitem>
+ <listitem>Supporting a single geodata source can be a big job for an application developer, supporting several would be a nightmare</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Master provider implements the same interfaces as regular providers, but internally
+ it uses whichever regular provider happens to be the best one (with "best" defined as
+ a provider that fulfills the accuracy requirements and does not surpass resource restrictions).
+ The internally used provider may change over time -- this does not interrupt clients use in any way,
+ but the changes can be observed using the MasterClient API.
+ </para>
+ <para>
+ A typical Master provider use includes:
+ <itemizedlist>
+ <listitem>Getting a client-specific GeoclueMasterClient from GeoclueMaster</listitem>
+ <listitem>Setting GeoclueMasterClient requirements (such as accuracy)</listitem>
+ <listitem>Starting the wanted interfaces (such as Position) </listitem>
+ <listitem>Using the client just like a regular provider</listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Master provider is fairly new and may not be as stable as the rest of Geoclue.
+ </para>
+ </sect2>
+ <sect2>
+ <subtitle>Current providers</subtitle>
+ TODO: list the providers shipped with geoclue, shortly explain their features.
+ </sect2>
+ </section>
+ <section id="simple-example">
+ <title>Using basic Geoclue providers: simple example in C</title>
+ <para>There are several examples in the geoclue source, these are included here to
+ give a quick overview.
+ </para>
+ <para>
+ Here is a very simple example of using a specific Geoclue Position provider.
+ Note that we're using the synchronous version of the method call here, so
+ geoclue_position_get_position() will block until the response comes (or until D-Bus timeouts).
+ </para>
+ <programlisting>
+#include <geoclue/geoclue-position.h>
+
+int main()
+{
+ GeocluePosition *pos;
+ GeocluePositionFields fields;
+ double lat, lon;
+ GError *error = NULL;
+
+ g_type_init ();
+
+ / * Create the position object * /
+ pos = geoclue_position_new ("org.freedesktop.Geoclue.Providers.Hostip",
+ "/org/freedesktop/Geoclue/Providers/Hostip");
+
+ / * call get_position. Note that unneeded output variables (here
+ timestamp, altitude and accuracy) can be left NULL * /
+ fields = geoclue_position_get_position (pos, NULL,
+ &lat, &lon, NULL,
+ NULL, &error);
+ if (error) {
+ g_printerr ("Error in get_position: %s.\n", error->message);
+ g_error_free (error);
+ g_object_unref (pos);
+ return 1;
+ }
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("According to Hostip.info we're at %.3f, %.3f.\n",
+ lat, lon);
+ } else {
+ g_print ("Hostip does not have a valid location available.\nVisit http://www.hostip.info/ to correct this");
+ }
+ g_object_unref (pos);
+
+ return 0;
+}
+ </programlisting>
+ <para>Save as test-hostip.c and compile with
+ </para>
+ <programlisting>
+gcc `pkg-config --libs --cflags geoclue` -o test-hostip test-hostip.c
+ </programlisting>
+ <para>Here is a similarly simple example using GLib mainloop and Gypsy provider with
+ position-changed signals:
+ </para>
+ <programlisting>
+#include <geoclue/geoclue-position.h>
+
+/ * device name or bluetooth address * /
+#define GPS_DEVICE_NAME "00:02:76:C5:81:BF"
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ g_print ("Position changed:\n");
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("\t%f, %f\n\n", latitude, longitude);
+ } else {
+ g_print ("\tLatitude and longitude not available.\n\n");
+ }
+}
+
+int main()
+{
+ GMainLoop *loop;
+ GHashTable *options;
+ GeocluePosition *pos;
+ GError *error = NULL;
+
+ g_type_init ();
+
+ / * Create the position object * /
+ pos = geoclue_position_new ("org.freedesktop.Geoclue.Providers.Gypsy",
+ "/org/freedesktop/Geoclue/Providers/Gypsy");
+
+ / * Set GPS device name option for Gypsy * /
+ options = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (options, "org.freedesktop.Geoclue.GPSDevice", GPS_DEVICE_NAME);
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (pos), options, &error)) {
+ g_printerr ("Error setting options: %s\n", error->message);
+ g_error_free (error);
+ g_hash_table_destroy (options);
+ g_object_unref (pos);
+ return 1;
+ }
+ g_hash_table_destroy (options);
+
+ / * connect to signal * /
+ g_signal_connect (G_OBJECT (pos), "position-changed",
+ G_CALLBACK (position_changed), NULL);
+
+ g_print ("Waiting for position change signals...\n");
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ g_main_loop_unref (loop);
+ g_object_unref (pos);
+
+ return 0;
+}
+ </programlisting>
+ </section>
+ <section id="simple-master-example">
+ <title>Master provider: simple example in C</title>
+ <para>
+ Here is the "Hello World" for Geoclue Master. It shows one of the advantages of
+ using the Master provider: Even most web service
+ providers can be used as signal emitting providers (master queries them whenever
+ network connection changes).
+ </para>
+
+ <programlisting>
+#include <geoclue/geoclue-master.h>
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ g_print ("Position changed:\n");
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("\t%f, %f\n\n", latitude, longitude);
+ } else {
+ g_print ("\tLatitude and longitude not available.\n\n");
+ }
+}
+
+int main()
+{
+ GMainLoop *loop;
+ GeoclueMaster *master;
+ GeoclueMasterClient *client;
+ GeocluePosition *pos;
+ GeocluePositionFields fields;
+ double lat, lon;
+ GError *error = NULL;
+
+ g_type_init ();
+
+ / * create a MasterClient using Master * /
+ master = geoclue_master_get_default ();
+ client = geoclue_master_create_client (master, NULL, &error);
+ g_object_unref (master);
+
+ if (!client) {
+ g_printerr ("Error creating GeoclueMasterClient: %s\n", error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ / * Set our requirements: We want at least city level accuracy, require signals,
+ and allow the use of network (but not e.g. GPS) * /
+ if (!geoclue_master_client_set_requirements (client,
+ GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0, TRUE,
+ GEOCLUE_RESOURCE_NETWORK,
+ &error)){
+ g_printerr ("set_requirements failed: %s", error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return 1;
+
+ }
+
+ / * Get a Position object * /
+ pos = geoclue_master_client_create_position (client, NULL);
+ if (!pos) {
+ g_printerr ("Failed to get a position object");
+ g_object_unref (client);
+ return 1;
+ }
+
+ / * call get_position. We do not know which provider actually provides
+ the answer (although we could find out using MasterClient API) * /
+ fields = geoclue_position_get_position (pos, NULL,
+ &lat, &lon, NULL,
+ NULL, &error);
+ if (error) {
+ g_printerr ("Error in geoclue_position_get_position: %s.\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ } else {
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("We're at %.3f, %.3f.\n", lat, lon);
+ }
+ }
+
+
+ g_signal_connect (G_OBJECT (pos), "position-changed",
+ G_CALLBACK (position_changed), NULL);
+
+ g_print ("Waiting for position change signals...\n");
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ g_main_loop_unref (loop);
+ g_object_unref (pos);
+ g_object_unref (client);
+ return 0;
+}
+ </programlisting>
+ </section>
+</chapter>
--- /dev/null
+EXTRA_DIST = spec-strip-docs.xsl spec-to-docbook.xsl
+
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"
+ exclude-result-prefixes="doc">
+
+ <xsl:output method="xml"
+ indent="yes"
+ encoding="UTF-8"
+ omit-xml-declaration="no"
+ doctype-system="http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+ doctype-public="-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" />
+
+ <xsl:template match="*">
+ <xsl:copy>
+ <xsl:for-each select="@*">
+ <xsl:if test="not(starts-with(name(.), 'doc:'))">
+ <xsl:copy/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="node">
+ <node>
+ <xsl:for-each select="@*">
+ <xsl:if test="not(starts-with(name(.), 'xmlns'))">
+ <xsl:copy/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </node>
+ </xsl:template>
+
+ <xsl:template match="doc:*"/>
+ <xsl:template match="text()"/>
+</xsl:stylesheet>
+
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"
+ exclude-result-prefixes="doc">
+<!--
+ Convert D-Bus Glib xml into DocBook refentries
+ Copyright (C) 2007 William Jon McCann
+ License: GPL
+-->
+<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+
+<xsl:template match="/node">
+ <xsl:apply-templates select="interface"/>
+</xsl:template>
+
+<xsl:template match="interface">
+
+<xsl:variable name="interface" select="@name"/>
+<xsl:variable name="basename">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="$interface"/>
+ </xsl:call-template>
+</xsl:variable>
+
+<refentry><xsl:attribute name="id"><xsl:value-of select="$basename"/></xsl:attribute>
+ <refmeta>
+
+ <refentrytitle role="top_of_page"><xsl:value-of select="@name"/></refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname><xsl:value-of select="@name"/></refname>
+ <refpurpose><xsl:value-of select="$basename"/> interface</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv role="synopsis">
+
+ <title role="synopsis.title">Methods</title>
+ <synopsis>
+ <xsl:call-template name="methods-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 role="signal_proto">
+
+ <title role="signal_proto.title">Signals</title>
+ <synopsis>
+ <xsl:call-template name="signals-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsect1>
+
+ <refsect1 role="impl_interfaces">
+
+ <title role="impl_interfaces.title">Implemented Interfaces</title>
+ <para>
+ <xsl:value-of select="$interface"/> implements
+ org.freedesktop.DBus.Introspectable,
+ org.freedesktop.DBus.Properties
+ </para>
+ </refsect1>
+
+ <refsect1 role="properties">
+ <title role="properties.title">Properties</title>
+
+ <synopsis>
+ <xsl:call-template name="properties-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsect1>
+
+ <refsect1 role="desc">
+ <title role="desc.title">Description</title>
+
+ <para>
+ <xsl:apply-templates select="doc:doc"/>
+ </para>
+ </refsect1>
+
+ <refsect1 role="details">
+ <title role="details.title">Details</title>
+ <xsl:call-template name="method-details">
+ <xsl:with-param name="basename" select="$basename"/>
+
+ </xsl:call-template>
+ </refsect1>
+
+ <refsect1 role="signals">
+ <title role="signals.title">Signal Details</title>
+ <xsl:call-template name="signal-details">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </refsect1>
+
+ <refsect1 role="property_details">
+ <title role="property_details.title">Property Details</title>
+ <xsl:call-template name="property-details">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </refsect1>
+
+</refentry>
+</xsl:template>
+
+
+<xsl:template name="property-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+
+<xsl:template name="property-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="property">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute></anchor>The "<xsl:value-of select="@name"/>" property</title>
+
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting>'<xsl:value-of select="@name"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="2"/></xsl:call-template>
+<xsl:call-template name="property-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/></xsl:call-template></programlisting>
+
+ <xsl:call-template name="property-doc"/>
+
+ </refsect2>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="signal-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+<xsl:template name="signal-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+ </xsl:call-template>
+
+ </xsl:variable>
+ <xsl:for-each select="signal">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute></anchor>The <xsl:value-of select="@name"/> signal</title>
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
+
+ <xsl:call-template name="signal-doc"/>
+
+ </refsect2>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="doc:code">
+<programlisting>
+<xsl:apply-templates />
+</programlisting>
+</xsl:template>
+
+<xsl:template match="doc:summary">
+
+<!-- by default don't display -->
+</xsl:template>
+
+<xsl:template match="doc:example">
+<informalexample>
+<xsl:apply-templates />
+</informalexample>
+</xsl:template>
+
+<xsl:template match="doc:para">
+<para>
+<xsl:apply-templates />
+</para>
+</xsl:template>
+
+<xsl:template match="doc:description">
+<xsl:apply-templates />
+
+</xsl:template>
+
+<xsl:template match="doc:since">
+<para role="since">Since <xsl:value-of select="@version"/>
+</para>
+</xsl:template>
+
+<xsl:template match="doc:deprecated">
+ <xsl:variable name="name" select="../../@name"/>
+ <xsl:variable name="parent">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="../../../@name"/>/>
+ </xsl:call-template>
+
+ </xsl:variable>
+
+ <xsl:variable name="type" select="name(../..)"/>
+
+ <para role="deprecated">
+ <warning><para><literal><xsl:value-of select="$name"/></literal> is deprecated since version <xsl:value-of select="@version"/> and should not be used in newly-written code. Use
+
+ <xsl:variable name="to">
+ <xsl:choose>
+ <xsl:when test="contains($type,'property')">
+
+ <xsl:value-of select="$parent"/>:<xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:when test="contains($type,'signal')">
+ <xsl:value-of select="$parent"/>::<xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:when test="contains($type,'method')">
+ <xsl:value-of select="$parent"/>.<xsl:value-of select="@instead"/>
+
+ </xsl:when>
+ <xsl:when test="contains($type,'interface')">
+ <xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@instead"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:call-template name="create-link">
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="to" select="$to"/>
+ <xsl:with-param name="val" select="@instead"/>
+ </xsl:call-template>
+instead.</para></warning>
+</para>
+</xsl:template>
+
+<xsl:template match="doc:permission">
+
+<para role="permission">
+<xsl:apply-templates />
+</para>
+</xsl:template>
+
+<xsl:template match="doc:seealso">
+<para>
+See also:
+<xsl:apply-templates />
+
+</para>
+</xsl:template>
+
+<xsl:template name="create-link">
+ <xsl:param name="type"/>
+ <xsl:param name="to"/>
+
+ <xsl:param name="val"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($type,'property')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
+ </xsl:when>
+ <xsl:when test="contains($type,'signal')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
+ </xsl:when>
+
+ <xsl:when test="contains($type,'method')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><function><xsl:value-of select="$val"/></function></link>
+ </xsl:when>
+ <xsl:when test="contains($type,'interface')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><xsl:value-of select="$val"/></link>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="doc:ref">
+
+ <xsl:call-template name="create-link">
+ <xsl:with-param name="type" select="@type"/>
+ <xsl:with-param name="to" select="@to"/>
+ <xsl:with-param name="val" select="."/>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="method-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem>
+<para><xsl:value-of select="doc:doc/doc:summary"/></para>
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+</listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+<xsl:template name="method-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="method">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute></anchor><xsl:value-of select="@name"/> ()</title>
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="method-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
+
+ <xsl:call-template name="method-doc"/>
+ </refsect2>
+
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="properties-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+
+ <xsl:with-param name="set" select="property/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="property">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute>'<xsl:value-of select="@name"/>'</link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template> <xsl:call-template name="property-args"><xsl:with-param name="indent" select="$longest + 2"/></xsl:call-template>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="signals-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="signal/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="signal">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="signal"/></xsl:call-template>)
+
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="methods-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="method/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:for-each select="method">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="method-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="method"/></xsl:call-template>)
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="method-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg"><xsl:value-of select="@direction"/>
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="4 - string-length(@direction)"/></xsl:call-template>'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
+<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="signal-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg">'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
+<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="property-args"><xsl:param name="indent"/>
+<xsl:value-of select="@access"/><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="9 - string-length(@access) + 1"/></xsl:call-template>'<xsl:value-of select="@type"/>'
+</xsl:template>
+
+
+<xsl:template name="pad-spaces">
+ <xsl:param name="width"/>
+ <xsl:variable name="spaces" xml:space="preserve"> </xsl:variable>
+ <xsl:value-of select="substring($spaces,1,$width)"/>
+</xsl:template>
+
+
+<xsl:template name="find-longest">
+ <xsl:param name="set"/>
+ <xsl:param name="index" select="1"/>
+ <xsl:param name="longest" select="0"/>
+
+ <xsl:choose>
+ <xsl:when test="$index > count($set)">
+ <!--finished looking-->
+ <xsl:value-of select="$longest"/>
+ </xsl:when>
+ <xsl:when test="string-length($set[$index])>$longest">
+ <!--found new longest-->
+ <xsl:call-template name="find-longest">
+
+ <xsl:with-param name="set" select="$set"/>
+ <xsl:with-param name="index" select="$index + 1"/>
+ <xsl:with-param name="longest" select="string-length($set[$index])"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!--this isn't any longer-->
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="$set"/>
+
+ <xsl:with-param name="index" select="$index + 1"/>
+ <xsl:with-param name="longest" select="$longest"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="interface-basename">
+ <xsl:param name="str"/>
+ <xsl:choose>
+
+ <xsl:when test="contains($str,'.')">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="substring-after($str,'.')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$str"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+noinst_PROGRAMS = \
+ position-example \
+ position-async-example \
+ master-example \
+ master-pos-example \
+ address-example \
+ geocode-example \
+ revgeocode-example \
+ common-example
+
+position_example_SOURCES = position-example.c
+position_async_example_SOURCES = position-async-example.c
+master_example_SOURCES = master-example.c
+master_pos_example_SOURCES = master-pos-example.c
+address_example_SOURCES = address-example.c
+geocode_example_SOURCES = geocode-example.c
+revgeocode_example_SOURCES = revgeocode-example.c
+common_example_SOURCES = common-example.c
+
+AM_CFLAGS = $(GEOCLUE_CFLAGS)
+LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
--- /dev/null
+/*
+ * Geoclue
+ * address-example.c - Example using the Address client API
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include <geoclue/geoclue-address.h>
+
+/* GHFunc, use with g_hash_table_foreach */
+static void
+print_address_key_and_value (char *key, char *value, gpointer user_data)
+{
+ g_print (" %s: %s\n", key, value);
+}
+
+static GHashTable *
+parse_options (int argc,
+ char **argv)
+{
+ GHashTable *options;
+ int i;
+
+ options = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 2; i < argc; i += 2) {
+ g_hash_table_insert (options, argv[i], argv[i + 1]);
+ }
+
+ return options;
+}
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeoclueAddress *address = NULL;
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GeoclueAccuracyLevel level;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc < 2 || argc % 2 != 0) {
+ g_printerr ("Usage:\n address-example <provider_name> [option value]\n");
+ return 1;
+ }
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+ /* Create new GeoclueAddress */
+ address = geoclue_address_new (service, path);
+ g_free (service);
+ g_free (path);
+ if (address == NULL) {
+ g_printerr ("Error while creating GeoclueAddress object.\n");
+ return 1;
+ }
+
+ /* Set options */
+ if (argc > 2) {
+ GHashTable *options;
+
+ options = parse_options (argc, argv);
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (address), options, &error)) {
+ g_printerr ("Error setting options: %s\n",
+ error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ g_hash_table_destroy (options);
+ }
+
+ /* Query current address */
+ if (!geoclue_address_get_address (address, ×tamp,
+ &details, &accuracy,
+ &error)) {
+ g_printerr ("Error getting address: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (address);
+ return 1;
+ }
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+
+ /* address data is in GHashTable details, need to turn that into a string */
+ g_print ("Current address: (accuracy level %d)\n", level);
+ g_hash_table_foreach (details, (GHFunc)print_address_key_and_value, NULL);
+
+ g_hash_table_destroy (details);
+ geoclue_accuracy_free (accuracy);
+ g_object_unref (address);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * common-example.c - Example using the Geoclue common client API
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include <geoclue/geoclue-position.h>
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeocluePosition *pos = NULL;
+ gchar *name = NULL;
+ gchar *desc = NULL;
+ GeoclueStatus status;
+ GHashTable *options;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc != 2) {
+ g_printerr ("Usage:\n common-example <provider_name>\n");
+ return 1;
+ }
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+
+ /* Create new GeoclueCommon */
+ pos = geoclue_position_new (service, path);
+ g_free (service);
+ g_free (path);
+ if (pos == NULL) {
+ g_printerr ("Error while creating GeocluePosition object.\n");
+ return 1;
+ }
+
+
+ options = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (options, "GPSProvider", "Gypsy");
+ g_hash_table_insert (options, "PlaySong", "MGMT-Kids.mp3");
+
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (pos), options, &error)) {
+ g_printerr ("Error setting options: %s\n\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ } else {
+ g_print ("Options set correctly\n\n");
+ }
+ g_hash_table_destroy (options);
+
+ if (!geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (pos),
+ &name, &desc,
+ &error)) {
+ g_printerr ("Error getting provider info: %s\n\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ } else {
+ g_print ("Provider info:\n");
+ g_print ("\tName: %s\n", name);
+ g_print ("\tDescription: %s\n\n", desc);
+ g_free (name);
+ g_free (desc);
+ }
+
+ if (!geoclue_provider_get_status (GEOCLUE_PROVIDER (pos), &status, &error)) {
+ g_printerr ("Error getting status: %s\n\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ } else {
+ switch (status) {
+ case GEOCLUE_STATUS_ERROR:
+ g_print ("Provider status: error\n");
+ break;
+ case GEOCLUE_STATUS_UNAVAILABLE:
+ g_print ("Provider status: unavailable\n");
+ break;
+ case GEOCLUE_STATUS_ACQUIRING:
+ g_print ("Provider status: acquiring\n");
+ break;
+ case GEOCLUE_STATUS_AVAILABLE:
+ g_print ("Provider status: available\n");
+ break;
+ }
+ }
+
+ g_object_unref (pos);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * geocode-example.c - Example using the Geocode client API
+ *
+ * Provider options are not used in this sample. See other files for
+ * examples on that.
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007, 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include <geoclue/geoclue-geocode.h>
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeoclueGeocode *geocoder = NULL;
+ GeocluePositionFields fields;
+ double lat, lon;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc < 2) {
+ g_printerr ("Usage:\n geocode-example <provider_name> [\"freeform address\"]\n\n"
+ " If freeform address is not given, a hard coded address hash "
+ "will be used.\n");
+ return 1;
+ }
+
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+ /* Create new GeoclueGeocode */
+ geocoder = geoclue_geocode_new (service, path);
+ g_free (service);
+ g_free (path);
+ if (geocoder == NULL) {
+ g_printerr ("Error while creating GeoclueGeocode object.\n");
+ return 1;
+ }
+
+ if (argc == 2) {
+ GHashTable *address = NULL;
+ /* Address we'd like geocoded */
+ address = geoclue_address_details_new();
+ geoclue_address_details_insert (address, "locality", "Helsinki");
+ geoclue_address_details_insert (address, "postalcode", "00330");
+ geoclue_address_details_insert (address, "countrycode", "FI");
+ geoclue_address_details_insert (address, "street", "Solnantie 24");
+
+ /* Geocode. We're not interested in altitude
+ this time, so leave it NULL. */
+ fields = geoclue_geocode_address_to_position (geocoder, address,
+ &lat, &lon, NULL,
+ &accuracy, &error);
+ g_hash_table_destroy (address);
+ } else {
+ char *str;
+ str = g_strjoinv (" ", &argv[2]);
+ fields = geoclue_geocode_freeform_address_to_position
+ (geocoder, str,
+ &lat, &lon, NULL,
+ &accuracy, &error);
+ g_free (str);
+ }
+
+ if (error) {
+ g_printerr ("Error while geocoding: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (geocoder);
+
+ return 1;
+ }
+
+ /* Print out coordinates if they are valid */
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("Geocoded position (accuracy level %d): \n", level);
+ g_print ("\t%f, %f\n", lat, lon);
+
+ } else {
+ g_print ("Latitude and longitude not available.\n");
+ }
+
+ geoclue_accuracy_free (accuracy);
+ g_object_unref (geocoder);
+ return 0;
+
+}
--- /dev/null
+/*
+ * Geoclue
+ * master-example.c - Example using the Master client API
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/* This example uses geoclue master to get approximate position
+ * and address signals. Following params are
+ * given to geoclue_master_client_set_requirements():
+ * min_accuracy = GEOCLUE_ACCURACY_LEVEL_LOCALITY
+ * Locality means a city or a town. Expect coordinates
+ * to routinely have 10-20 km error.
+ * min_time = 0
+ * No limit on frequency of position-changed signals
+ * (this is not actually implemented yet)
+ * require_updates = TRUE
+ * We want position-changed and address-changed signals
+ * allowed_resources = GEOCLUE_RESOURCE_NETWORK
+ * Web services may be used but e.g. GPS is off limits
+ *
+ * To ensure at least one working provider for your testing, visit
+ * hostip.info and define your IPs location if it's not set or is
+ * marked as "guessed"
+ *
+ * */
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-position.h>
+
+/* Provider methods */
+static void
+provider_changed_cb (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ gpointer userdata)
+{
+ g_print ("%s provider changed: %s\n", (char *)userdata, name);
+}
+
+
+/* Address methods */
+static void
+print_address_key_and_value (char *key, char *value, gpointer user_data)
+{
+ g_print ("\t%s: %s\n", key, value);
+}
+
+static void
+address_changed_cb (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy)
+{
+ GeoclueAccuracyLevel level;
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("New address (accuracy level %d):\n", level);
+ g_hash_table_foreach (details, (GHFunc)print_address_key_and_value, NULL);
+ g_print ("\n");
+}
+
+static GeoclueAddress *
+init_address (GeoclueMasterClient *client)
+{
+ GError *error = NULL;
+ GeoclueAddress *address;
+ GHashTable *details = NULL;
+ GeoclueAccuracyLevel level;
+ GeoclueAccuracy *accuracy = NULL;
+ int timestamp = 0;
+
+ /* create the object and connect to signal */
+ address = geoclue_master_client_create_address (client, &error);
+ if (!address) {
+ g_warning ("Creating GeoclueAddress failed: %s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+ g_signal_connect (G_OBJECT (address), "address-changed",
+ G_CALLBACK (address_changed_cb), NULL);
+
+ /* print initial address */
+ if (!geoclue_address_get_address (address, ×tamp,
+ &details, &accuracy,
+ &error)) {
+ g_printerr ("Error getting address: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("Current address: (accuracy level %d):\n", level);
+ g_hash_table_foreach (details, (GHFunc)print_address_key_and_value, NULL);
+ g_print ("\n");
+ g_hash_table_destroy (details);
+ geoclue_accuracy_free (accuracy);
+ }
+ return address;
+}
+
+
+/* Position methods */
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("New position (accuracy level %d):\n", level);
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("\t%f, %f\n\n", latitude, longitude);
+ } else {
+ g_print ("\nlatitude and longitude not valid.\n");
+ }
+}
+
+static GeocluePosition *
+init_position (GeoclueMasterClient *client)
+{
+ GeocluePosition *position;
+ GError *error = NULL;
+ GeocluePositionFields fields;
+ double lat = 0.0, lon = 0.0;
+ GeoclueAccuracy *accuracy;
+
+ position = geoclue_master_client_create_position (client, &error);
+ if (!position) {
+ g_warning ("Creating GeocluePosition failed: %s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ g_signal_connect (G_OBJECT (position), "position-changed",
+ G_CALLBACK (position_changed_cb), NULL);
+
+ /*print initial position */
+ fields = geoclue_position_get_position (position, NULL,
+ &lat, &lon, NULL,
+ &accuracy, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ } else {
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("New position (accuracy level %d):\n", level);
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ g_print ("\t%f, %f\n\n", lat, lon);
+ } else {
+ g_print ("\nlatitude and longitude not valid.\n");
+ }
+
+ geoclue_accuracy_free (accuracy);
+ }
+
+ return position;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueMaster *master;
+ GeoclueMasterClient *client;
+ GeocluePosition *pos;
+ GeoclueAddress *addr;
+ GMainLoop *mainloop;
+
+ g_type_init ();
+
+ master = geoclue_master_get_default ();
+ client = geoclue_master_create_client (master, NULL, NULL);
+ g_object_unref (master);
+
+ g_signal_connect (G_OBJECT (client), "address-provider-changed",
+ G_CALLBACK (provider_changed_cb), "Address");
+ g_signal_connect (G_OBJECT (client), "position-provider-changed",
+ G_CALLBACK (provider_changed_cb), "Position");
+
+ if (!geoclue_master_client_set_requirements (client,
+ GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0,
+ TRUE,
+ GEOCLUE_RESOURCE_NETWORK,
+ NULL)){
+ g_printerr ("set_requirements failed");
+ g_object_unref (client);
+ return 1;
+ }
+
+ addr = init_address (client);
+ pos = init_position (client);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (mainloop);
+
+ g_main_loop_unref (mainloop);
+ g_object_unref (pos);
+ g_object_unref (addr);
+ g_object_unref (client);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * master-example.c - Example using the Master client API
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+
+/* This example shows typical GPS-like usage. Following params are
+ * given to geoclue_master_client_set_requirements():
+ * min_accuracy = GEOCLUE_ACCURACY_LEVEL_DETAILED
+ * We require the highest level of accuracy
+ * min_time = 0
+ * No limit on frequency of position-changed signals
+ * (this is not actually implemented yet)
+ * require_updates = TRUE
+ * We need position-changed signals
+ * allowed_resources = GEOCLUE_RESOURCE_ALL
+ * Any available resource can be used
+ *
+ * Geoclue master will try to select a suitable provider based on these
+ * requirements -- currently only Gypsy and Gpsd providers fulfill
+ * the above requiremens. Gpsd-provider should work out-of-the-box as
+ * long as gpsd is running in the default port. Gypsy provider requires
+ * that you set device name in the options: see README for details.
+ *
+ */
+
+#include <string.h>
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-position.h>
+
+static void
+provider_changed_cb (GeoclueMasterClient *client,
+ char *iface,
+ char *name,
+ char *description,
+ gpointer userdata)
+{
+ if (strlen (name) == 0) {
+ g_print ("No provider available\n");
+ } else {
+ g_print ("now using provider: %s\n", name);
+ }
+}
+
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("got position (accuracy level %d):\n", level);
+ g_print ("\t%f, %f\n", latitude, longitude);
+
+ } else {
+ g_print ("position emitted, but latitude and longitude are not valid.\n");
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GError *error = NULL;
+ GMainLoop *mainloop;
+ GeoclueMaster *master;
+ GeoclueMasterClient *client;
+ GeocluePosition *position;
+
+ g_type_init ();
+
+ master = geoclue_master_get_default ();
+ client = geoclue_master_create_client (master, NULL, NULL);
+ g_object_unref (master);
+
+ g_signal_connect (G_OBJECT (client), "position-provider-changed",
+ G_CALLBACK (provider_changed_cb), NULL);
+
+ /* We want provider that has detailed accuracy and emits signals.
+ * The provider is allowed to use any resources available. */
+ if (!geoclue_master_client_set_requirements (client,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ 0, TRUE,
+ GEOCLUE_RESOURCE_ALL,
+ NULL)){
+ g_printerr ("Setting requirements failed");
+ g_object_unref (client);
+ return 1;
+ }
+
+ position = geoclue_master_client_create_position (client, &error);
+ if (!position) {
+ g_warning ("Creating GeocluePosition failed: %s", error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return 1;
+ }
+
+ g_signal_connect (G_OBJECT (position), "position-changed",
+ G_CALLBACK (position_changed_cb), NULL);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (mainloop);
+
+ g_main_loop_unref (mainloop);
+ g_object_unref (client);
+ g_object_unref (position);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * position-example.c - Example using the Position client API
+ * (asynchronous method call)
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/* NOTE: provider options are not used in this example */
+
+#include <glib.h>
+#include <geoclue/geoclue-position.h>
+
+static void
+position_callback (GeocluePosition *pos,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Error getting position: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (accuracy, &level, NULL, NULL);
+ g_print ("Current position (accuracy %d):\n", level);
+ g_print ("\t%f, %f\n", latitude, longitude);
+ } else {
+ g_print ("Current position not available.\n");
+ }
+ }
+ g_main_loop_quit ((GMainLoop *)userdata);
+}
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GMainLoop *mainloop;
+ GeocluePosition *pos = NULL;
+
+ if (argc < 2 || argc % 2 != 0) {
+ g_printerr ("Usage:\n position-example <provider_name>");
+ return 1;
+ }
+
+ g_type_init();
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+
+ pos = geoclue_position_new (service, path);
+ g_free (service);
+ g_free (path);
+ if (pos == NULL) {
+ g_printerr ("Error while creating GeocluePosition object.\n");
+ return 1;
+ }
+
+ geoclue_position_get_position_async (pos,
+ (GeocluePositionCallback) position_callback,
+ mainloop);
+ g_print ("Asynchronous call made, going to main loop now...\n");
+ g_main_loop_run (mainloop);
+
+ g_main_loop_unref (mainloop);
+ g_object_unref (pos);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * position-example.c - Example using the Position client API
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include <geoclue/geoclue-position.h>
+
+static void
+position_changed_cb (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, NULL);
+ g_print ("Current position:\n");
+ g_print ("\t%f, %f\n", latitude, longitude);
+ g_print ("\tAccuracy level %d (%.0f meters)\n", level, horiz_acc);
+
+ } else {
+ g_print ("Latitude and longitude not available.\n");
+ }
+}
+
+static GHashTable *
+parse_options (int argc,
+ char **argv)
+{
+ GHashTable *options;
+ int i;
+
+ options = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 2; i < argc; i += 2) {
+ g_hash_table_insert (options, argv[i], argv[i + 1]);
+ }
+
+ return options;
+}
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeocluePosition *pos = NULL;
+ GeocluePositionFields fields;
+ int timestamp;
+ double lat, lon;
+ GeoclueAccuracy *accuracy = NULL;
+ GMainLoop *mainloop;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc < 2 || argc % 2 != 0) {
+ g_printerr ("Usage:\n position-example <provider_name> [option,value]\n");
+ return 1;
+ }
+
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ /* Create new GeocluePosition */
+ pos = geoclue_position_new (service, path);
+ if (pos == NULL) {
+ g_printerr ("Error while creating GeocluePosition object.\n");
+ return 1;
+ }
+
+ g_free (service);
+ g_free (path);
+
+ if (argc > 2) {
+ GHashTable *options;
+
+ options = parse_options (argc, argv);
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (pos), options, &error)) {
+ g_printerr ("Error setting options: %s\n",
+ error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ g_hash_table_destroy (options);
+ }
+
+ /* Query current position. We're not interested in altitude
+ this time, so leave it NULL. Same can be done with all other
+ arguments that aren't interesting to the client */
+ fields = geoclue_position_get_position (pos, ×tamp,
+ &lat, &lon, NULL,
+ &accuracy, &error);
+ if (error) {
+ g_printerr ("Error getting position: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (pos);
+ return 1;
+ }
+
+ /* Print out coordinates if they are valid */
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, NULL);
+ g_print ("Current position:\n");
+ g_print ("\t%f, %f\n", lat, lon);
+ g_print ("\tAccuracy level %d (%.0f meters)\n", level, horiz_acc);
+
+ } else {
+ g_print ("Latitude and longitude not available.\n");
+ }
+
+ geoclue_accuracy_free (accuracy);
+
+ g_signal_connect (G_OBJECT (pos), "position-changed",
+ G_CALLBACK (position_changed_cb), NULL);
+
+ g_main_loop_run (mainloop);
+ return 0;
+
+}
--- /dev/null
+/*
+ * Geoclue
+ * revgeocode-example.c - Example using the ReverseGeocode client API
+ *
+ * Author: Jussi Kukkonen <jku@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include <stdlib.h>
+#include <geoclue/geoclue-reverse-geocode.h>
+
+/* GHFunc, use with g_hash_table_foreach */
+static void
+print_address_key_and_value (char *key, char *value, gpointer user_data)
+{
+ g_print (" %s: %s\n", key, value);
+}
+
+static GHashTable *
+parse_options (int argc,
+ char **argv)
+{
+ GHashTable *options;
+ int i;
+
+ options = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 4; i < argc; i += 2) {
+ g_hash_table_insert (options, argv[i], argv[i + 1]);
+ }
+
+ return options;
+}
+
+int main (int argc, char** argv)
+{
+ gchar *service, *path;
+ GeoclueReverseGeocode *revgeocoder = NULL;
+ GeoclueAccuracy *accuracy, *out_accuracy;
+ GHashTable *address = NULL;
+ double lat, lon;
+ GError *error = NULL;
+
+ g_type_init();
+
+ if (argc < 4) {
+ g_printerr ("Usage:\n revgeocode-example <provider_name> <lat> <lon>\n");
+ return 1;
+ }
+ g_print ("Using provider '%s'\n", argv[1]);
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", argv[1]);
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", argv[1]);
+
+ /* Create new GeoclueReverseGeocode */
+ revgeocoder = geoclue_reverse_geocode_new (service, path);
+ g_free (service);
+ g_free (path);
+ if (revgeocoder == NULL) {
+ g_printerr ("Error while creating GeoclueGeocode object.\n");
+ return 1;
+ }
+
+
+ /* Set options */
+ if (argc > 4) {
+ GHashTable *options;
+
+ options = parse_options (argc, argv);
+ if (!geoclue_provider_set_options (GEOCLUE_PROVIDER (revgeocoder), options, &error)) {
+ g_printerr ("Error setting options: %s\n",
+ error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ g_hash_table_destroy (options);
+ }
+
+ address = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)g_free);
+
+ lat = atof (argv[2]);
+ lon = atof (argv[3]);
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET, 0.0, 0.0);
+ if (!geoclue_reverse_geocode_position_to_address (revgeocoder,
+ lat, lon, accuracy,
+ &address, &out_accuracy, &error)) {
+ g_printerr ("Error while reverse geocoding: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (revgeocoder);
+ return 1;
+ }
+
+ /* Print out the address */
+ GeoclueAccuracyLevel level;
+ geoclue_accuracy_get_details (out_accuracy, &level, NULL, NULL);
+ g_print ("Reverse Geocoded [%f, %f] to address (accuracy %d):\n", lat, lon, level);
+ g_hash_table_foreach (address, (GHFunc)print_address_key_and_value, NULL);
+
+ g_hash_table_destroy (address);
+ g_object_unref (revgeocoder);
+ return 0;
+
+}
--- /dev/null
+[Version] geoclue_0.12.0-28
+[date] 15 Jan 2013
+[Title] In order to build geoclue with GCC-4.7, apply patches(lp_718911.patch,
+ lp_738584.patch, and lp_829436.patch) on https://launchpad.net/ubuntu/+source/geoclue/0.12.0-1ubuntu10
+[Issue#] NA
+[Problem] build break with GCC-4.7
+[Cause] NA
+[Solution] update new patches
+[Developer] Youngae Kang <youngae.kang@samsung.com>
+
+================================================================================
+
+geoclue (0.12.0-27slp2) unstable; urgency=low
+
+ * Add PositionVelocity interface.
+ * Tag : geoclue_0.12.0-27slp2
+
+ -- Minjune Kim <sena06.kim@samsung.com> Wed, 02 Jan 2013 14:11:04 +0900
+
+geoclue (0.12.0-26slp2) unstable; urgency=low
+
+ * Support POI
+ * Tag : geoclue_0.12.0-26slp2
+
+ -- Minjune Kim <sena06.kim@samsung.com> Mon, 02 Jul 2012 23:27:13 +0900
+
+geoclue (0.12.0-25slp2) unstable; urgency=low
+
+ * fix for system proxy setting
+ * Tag : geoclue_0.12.0-25slp2
+
+ -- Genie Kim <daejins.kim@samsung.com> Mon, 02 Apr 2012 20:24:00 +0900
+
+geoclue (0.12.0-24slp2) unstable; urgency=low
+
+ * add feature for last position & velocity & satellite
+ * Tag : geoclue_0.12.0-24slp2
+
+ -- Genie Kim <daejins.kim@samsung.com> Mon, 27 Feb 2012 17:30:01 +0900
+
+geoclue (0.12.0-23slp2) unstable; urgency=low
+
+ * remove geoclue-gpsd
+ * Tag : geoclue_0.12.0-23slp2
+
+ -- Minjune kim <sena06.kim.kim@samsung.com> Wed, 22 Feb 2012 16:55:45 +0900
+
+geoclue (0.12.0-22slp2) unstable; urgency=low
+
+ * remove geoclue-gpsd
+ * Tag : geoclue_0.12.0-22slp2
+
+ -- Genie Kim <daejins.kim@samsung.com> Fri, 10 Feb 2012 17:58:42 +0900
+
+geoclue (0.12.0-21slp2) unstable; urgency=low
+
+ * add altitude / h_accuracy / v_accurcy in last position(geoclue_0.12.0-21slp2.patch)
+ * Tag : geoclue_0.12.0-21slp2
+
+ -- Genie Kim <daejins.kim@samsung.com> Tue, 10 Jan 2012 19:48:21 +0900
+
+geoclue (0.12.0-20slp2) unstable; urgency=low
+
+ * use quilt for patch(tizen.patch)
+ * add last knonw position(geoclue_0.12.0-20slp2.patch)
+ * Tag : geoclue_0.12.0-20slp2
+
+ -- Genie Kim <daejins.kim@samsung.com> Mon, 02 Jan 2012 19:27:14 +0900
+
+geoclue (0.12.0-19slp2+5) unstable; urgency=low
+
+ * add geoclue-gpsd install file
+ * Tag : geoclue_0.12.0-19slp2+5
+
+ -- Genie Kim <daejins.kim@samsung.com> Mon, 19 Dec 2011 13:56:07 +0900
+
+geoclue (0.12.0-19slp2+4) unstable; urgency=low
+
+ * activate geoclue-gpsd
+ * Tag : geoclue_0.12.0-19slp2+4
+
+ -- Genie Kim <daejins.kim@samsung.com> Wed, 07 Dec 2011 16:47:11 +0900
+
+geoclue (0.12.0-19slp2+3) unstable; urgency=low
+
+ * remove not using packages
+ * Tag : geoclue_0.12.0-19slp2+3
+
+ -- Genie Kim <daejins.kim@samsung.com> Tue, 06 Dec 2011 22:36:09 +0900
+
+geoclue (0.12.0-19slp2+2) unstable; urgency=low
+
+ * Remove geoclue-gpsd package for add new feature and geoclue-gpsd is moved under geoclue-providers
+ * Tag : geoclue_0.12.0-19slp2+2
+
+ -- Genie Kim <daejins.kim@samsung.com> Sat, 26 Nov 2011 12:15:52 +0900
+
+geoclue (0.12.0-19slp2+1) unstable; urgency=low
+
+ * Fix bug in dbus signal for satellite information
+ * Tag : geoclue_0.12.0-19slp2+1
+
+ -- Yunhan Kim <yhan.kim@samsung.com> Fri, 21 Oct 2011 09:03:40 +0900
+
+geoclue (0.12.0-18slp2+5) unstable; urgency=low
+
+ * remove GTK dependency
+ * Tag : geoclue_0.12.0-18slp2+5
+
+ -- Genie Kim <daejins.kim@samsung.com> Thu, 15 Sep 2011 13:55:47 +0900
+
+geoclue (0.12.0-18slp2+4) unstable; urgency=low
+
+ * upgrade of dbus-glib : remove Depends
+ * Tag : geoclue_0.12.0-18slp2+4
+
+ -- Genie Kim <daejins.kim@samsung.com> Tue, 02 Aug 2011 11:30:11 +0900
+
+geoclue (0.12.0-18slp2+3) unstable; urgency=low
+
+ * Add and change boilerplate
+ * Tag : geoclue_0.12.0-18slp2+3
+
+ -- Genie Kim <daejins.kim@samsung.com> Tue, 19 Jul 2011 17:22:02 +0900
+
+geoclue (0.12.0-18slp2+2) unstable; urgency=low
+
+ * Install geoclue-nominatim package
+ * Tag : geoclue_0.12.0-18slp2+2
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Mon, 13 Jun 2011 11:20:07 +0900
+
+geoclue (0.12.0-18slp2+1) unstable; urgency=low
+
+ * Release again for glib upgrade
+ * Tag : geoclue_0.12.0-18slp2+1
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Wed, 30 Mar 2011 15:13:47 +0900
+
+geoclue (0.12.0-17slp2+17) unstable; urgency=low
+
+ * Fix geoclue-gpsd & Add debug package
+ * Tag : geoclue_0.12.0-17slp2+17
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Wed, 24 Nov 2010 22:38:02 +0900
+
+geoclue (0.12.0-17slp2+16) unstable; urgency=low
+
+ * Remove test-gui & remove auto genarated files
+ * Tag : geoclue_0.12.0-17slp2+16
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 12 Nov 2010 13:31:03 +0900
+
+geoclue (0.12.0-17slp2+15) unstable; urgency=low
+
+ * Release geoclue_0.12.0-17slp2+15
+ * Tag : geoclue_0.12.0-17slp2+15
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Wed, 10 Nov 2010 17:00:18 +0900
+
+geoclue (0.12.0-16slp2+13) unstable; urgency=low
+
+ * Add xps provider
+ * Tag : geoclue_0.12.0-16slp2+13
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Mon, 08 Nov 2010 13:18:51 +0900
+
+geoclue (0.12.0-15slp2+12) unstable; urgency=low
+
+ * Remove skyhooks & gpsd packages
+ * Tag : geoclue_0.12.0-15slp2+12
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 29 Oct 2010 16:21:45 +0900
+
+geoclue (0.12.0-14slp2+11) unstable; urgency=low
+
+ * Fix for Limo contrib.
+ * Tag : geoclue_0.12.0-14slp2+11
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 29 Oct 2010 16:21:41 +0900
+
+geoclue (0.12.0-13slp2+10) unstable; urgency=low
+
+ * Fix BS for multi process
+ * Tag : geoclue_0.12.0-13slp2+10
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Tue, 12 Oct 2010 21:09:36 +0900
+
+geoclue (0.12.0-12slp2+9) unstable; urgency=low
+
+ * Apply tweak guide
+ * Tag : geoclue_0.12.0-12slp2+9
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 17 Sep 2010 19:17:45 +0900
+
+geoclue (0.12.0-11slp2+8) unstable; urgency=low
+
+ * Bug fix for impolite clients
+ * Tag : geoclue_0.12.0-11slp2+8
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Thu, 09 Sep 2010 11:52:42 +0900
+
+geoclue (0.12.0-10slp2+7) unstable; urgency=low
+
+ * We can use sync API if lbs-engine is already initialized
+ * Tag : geoclue_0.12.0-10slp2+7
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Mon, 06 Sep 2010 10:53:59 +0900
+
+geoclue (0.12.0-9slp2+6) unstable; urgency=low
+
+ * Modify lbs-sync API & Fix signaling & Add lbs-example & Remove lbs-stub
+ * Tag : geoclue_0.12.0-9slp2+6
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Sat, 04 Sep 2010 17:55:05 +0900
+
+geoclue (0.12.0-8slp2+5) unstable; urgency=low
+
+ * change lbs-stub --> lbs-client (lbs-engine)
+ * Tag : geoclue_0.12.0-8slp2+5
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Wed, 01 Sep 2010 11:41:56 +0900
+
+geoclue (0.12.0-7slp2+4) unstable; urgency=low
+
+ * Add G_END_DECLS ( Bug fix )
+ * Tag : geoclue_0.12.0-7slp2+4
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Mon, 30 Aug 2010 18:14:30 +0900
+
+geoclue (0.12.0-6slp2+3) unstable; urgency=low
+
+ * Modifying version
+ * Tag : geoclue_0.12.0-6slp2+3
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Sat, 28 Aug 2010 21:59:03 +0900
+
+geoclue (0.12.0-1slp2+3) unstable; urgency=low
+
+ * Add nmea&sattelite interface
+ * Tag : geoclue_0.12.0-1slp2+3
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Sat, 28 Aug 2010 21:38:51 +0900
+
+geoclue (0.12.0-5slp2+2) unstable; urgency=low
+
+ * Temporary patch for browser (lbs-engine --> lbs stub)
+ * Tag : geoclue_0.12.0-5slp2+2
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 27 Aug 2010 14:00:04 +0900
+
+geoclue (0.12.0-5slp2+1) unstable; urgency=low
+
+ * Change libgeoclue0.install.in --> libgeoclue.install.in
+ * Tag : geoclue_0.12.0-5slp2+1
+
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Sat, 21 Aug 2010 01:00:44 +0900
+
+geoclue (0.12.0-4slp2+1) unstable; urgency=low
+
+ * Version up
+ * Tag : geoclue_0.12.0-4slp2+1
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Sat, 21 Aug 2010 00:41:18 +0900
+
+geoclue (0.12.0-3slp2+1) unstable; urgency=low
+
+ * Change git tag again
+ * Tag : geoclue_0.12.0-3slp2+1
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 20 Aug 2010 17:10:00 +0900
+
+geoclue (0.12.0-2slp2+1) unstable; urgency=low
+
+ * Change git tag
+ * Tag : geoclue_0.12.0-2slp2+1
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 20 Aug 2010 16:55:13 +0900
+
+geoclue (0.12.0-1slp2+1) unstable; urgency=low
+
+ * Fix geoclue-lbs for receiving callback from lbs-client
+ * Change debian/control for using lbs-client
+ * Tag : geoclue_0.12.0-1slp2+1
+
+ -- Tae-Hwan Kim <the81.kim@samsung.com> Fri, 20 Aug 2010 14:22:17 +0900
+
+geoclue (0.11.1-13slp2+3) unstable; urgency=low
+
+ * Disable to check gtkdocize
+ * Tag : geoclue_0.11.1-13slp2+3
+
+ -- Gyuyoung Kim <gyuyoung.kim@samsung.com> Sat, 05 Jun 2010 16:43:43 +0900
+
+geoclue (0.11.1-13slp2+2) unstable; urgency=low
+
+ * Change DBUS_BUS_SESSION with DBUS_BUS_SYSTEM
+ * Tag : geoclue_0.11.1-13slp2+2
+
+ -- Gyuyoung Kim <gyuyoung.kim@samsung.com> Mon, 24 May 2010 13:36:37 +0900
+
+geoclue (0.11.1-13slp2+1) unstable; urgency=low
+
+ * Followd SLP package naming rule
+
+ -- Joone Hur <joone.hur@samsung.com> Thu, 01 Apr 2010 09:36:53 +0900
+
+geoclue (0.11.1-12) unstable; urgency=low
+
+ * Added missing gtk dependency for library
+
+ -- Lukasz Slachciak <l.slachciak@samsung.com> Wed, 31 Mar 2010 10:50:30 +0200
+
+geoclue (0.11.1-11) unstable; urgency=low
+
+ * Uploaders section added
+
+ -- Lukasz Slachciak <l.slachciak@samsung.com> Thu, 25 Mar 2010 16:31:33 +0100
+
+geoclue (0.11.1-10) unstable; urgency=low
+
+ * Toolchain upgrade
+
+ -- Lukasz Slachciak <l.slachciak@samsung.com> Thu, 25 Mar 2010 10:55:21 +0100
+
+geoclue (0.11.1-9) unstable; urgency=low
+
+ * add missing skyhook files to the package
+ * hostip provider allows for FORCE_IP env var
+ * let's have SUWON location by default
+ * use the data returned by LBS CLIENT in the signal - this could work with GPS now
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Tue, 16 Mar 2010 17:16:20 +0100
+
+geoclue (0.11.1-8) unstable; urgency=low
+
+ * Merged with changes from vanilla geoclue; this adds skyhook provider
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Fri, 12 Mar 2010 16:12:51 +0100
+
+geoclue (0.11.1-7) unstable; urgency=low
+
+ * Add LBS stub library (working) for testing LBS provider
+ * Make geoclue LBS provider emit position-changed signal
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Mon, 08 Mar 2010 17:07:01 +0100
+
+geoclue (0.11.1-6) unstable; urgency=low
+
+ * Update lbs service config
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Mon, 22 Feb 2010 16:25:06 +0100
+
+geoclue (0.11.1-5) unstable; urgency=low
+
+ * added LBS Position Provider
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Mon, 22 Feb 2010 15:02:20 +0100
+
+geoclue (0.11.1-4) unstable; urgency=low
+
+ * add gtk deps for devel package, required by geoclue-test-gui
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Thu, 21 Jan 2010 15:05:55 +0100
+
+geoclue (0.11.1-3) unstable; urgency=low
+
+ * more deps on gconf
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Tue, 19 Jan 2010 12:56:49 +0100
+
+geoclue (0.11.1-2) unstable; urgency=low
+
+ * added dependency on gconf
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Tue, 19 Jan 2010 11:48:25 +0100
+
+geoclue (0.11.1-1) unstable; urgency=low
+
+ * Initial release.
+
+ -- Jaroslaw Staniek <j.staniek@samsung.com> Thu, 14 Jan 2010 15:45:33 +0100
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir = @datarootdir@
+datadir=@datadir@
+
+Name: geoclue
+Description: Geoinformation service
+Requires: dbus-glib-1 libxml-2.0
+Version: @VERSION@
+Libs: -L${libdir} -lgeoclue
+Cflags: -I${includedir}
--- /dev/null
+lib_LTLIBRARIES = libgeoclue.la
+
+nodist_libgeoclue_la_SOURCES = \
+ geoclue-marshal.c \
+ geoclue-marshal.h \
+ gc-iface-address-bindings.h \
+ gc-iface-address-glue.h \
+ gc-iface-geoclue-bindings.h \
+ gc-iface-geoclue-glue.h \
+ gc-iface-geocode-bindings.h \
+ gc-iface-geocode-glue.h \
+ gc-iface-poi-bindings.h \
+ gc-iface-poi-glue.h \
+ gc-iface-master-bindings.h \
+ gc-iface-master-client-bindings.h \
+ gc-iface-position-bindings.h \
+ gc-iface-position-glue.h \
+ gc-iface-position-ext-bindings.h \
+ gc-iface-position-ext-glue.h \
+ gc-iface-nmea-bindings.h \
+ gc-iface-nmea-glue.h \
+ gc-iface-reverse-geocode-bindings.h \
+ gc-iface-reverse-geocode-glue.h \
+ gc-iface-velocity-bindings.h \
+ gc-iface-velocity-glue.h \
+ gc-iface-satellite-bindings.h \
+ gc-iface-satellite-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_libgeoclue_la_SOURCES) \
+ geoclue-enum-types.h \
+ geoclue-enum-types.c
+
+libgeoclue_la_SOURCES = \
+ geoclue-accuracy.c \
+ geoclue-address.c \
+ geoclue-address-details.c \
+ geoclue-provider.c \
+ geoclue-error.c \
+ geoclue-geocode.c \
+ geoclue-poi.c \
+ geoclue-master.c \
+ geoclue-master-client.c \
+ geoclue-position.c \
+ geoclue-position-ext.c \
+ geoclue-nmea.c \
+ geoclue-reverse-geocode.c \
+ geoclue-types.c \
+ geoclue-velocity.c \
+ geoclue-satellite.c \
+ gc-provider.c \
+ gc-web-service.c \
+ gc-iface-address.c \
+ gc-iface-geoclue.c \
+ gc-iface-geocode.c \
+ gc-iface-poi.c \
+ gc-iface-position.c \
+ gc-iface-position-ext.c \
+ gc-iface-nmea.c \
+ gc-iface-reverse-geocode.c \
+ gc-iface-velocity.c \
+ gc-iface-satellite.c \
+ geoclue-enum-types.c
+
+libgeoclue_la_LIBADD = \
+ $(GEOCLUE_LIBS)
+
+libgeoclue_la_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_headers = \
+ gc-iface-address.h \
+ gc-iface-geoclue.h \
+ gc-iface-geocode.h \
+ gc-iface-poi.h \
+ gc-iface-position.h \
+ gc-iface-position-ext.h \
+ gc-iface-nmea.h \
+ gc-iface-reverse-geocode.h \
+ gc-iface-velocity.h \
+ gc-iface-satellite.h \
+ gc-provider.h \
+ gc-web-service.h \
+ geoclue-accuracy.h \
+ geoclue-address.h \
+ geoclue-address-details.h \
+ geoclue-provider.h \
+ geoclue-error.h \
+ geoclue-geocode.h \
+ geoclue-master.h \
+ geoclue-master-client.h \
+ geoclue-poi.h \
+ geoclue-landmark.h \
+ geoclue-position.h \
+ geoclue-position-ext.h \
+ geoclue-nmea.h \
+ geoclue-reverse-geocode.h \
+ geoclue-types.h \
+ geoclue-velocity.h \
+ geoclue-satellite.h \
+ geoclue-satellite-info.h \
+ geoclue-enum-types.h
+
+libgeoclue_includedir = $(includedir)/geoclue
+libgeoclue_include_HEADERS = \
+ $(geoclue_headers)
+
+EXTRA_DIST = \
+ geoclue-marshal.list
+
+CLEANFILES = $(BUILT_SOURCES) \
+ stamp-gc-iface-address-glue.h \
+ stamp-gc-iface-geoclue-glue.h \
+ stamp-gc-iface-geocode-glue.h \
+ stamp-gc-iface-poi-glue.h \
+ stamp-gc-iface-position-glue.h \
+ stamp-gc-iface-position-ext-glue.h \
+ stamp-gc-iface-nmea-glue.h \
+ stamp-gc-iface-reverse-geocode-glue.h \
+ stamp-gc-iface-velocity-glue.h \
+ stamp-gc-iface-satellite-glue.h
+
+DISTCLEANFILES = \
+ $(nodist_libgeoclue_la_SOURCES) \
+ geoclue-enum-types.h \
+ geoclue-enum-types.c
+
+geoclue-marshal.h: geoclue-marshal.list $(GLIB_GENMARSHAL)
+ $(GLIB_GENMARSHAL) $< --header --prefix=geoclue_marshal > $@
+geoclue-marshal.c: geoclue-marshal.list geoclue-marshal.h $(GLIB_GENMARSHAL)
+ echo "#include \"geoclue-marshal.h\"" > $@ \
+ && $(GLIB_GENMARSHAL) --prefix=geoclue_marshal $(srcdir)/geoclue-marshal.list --body >> $@
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-gc-iface-address-glue.h: ../interfaces/gc-iface-address.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_address --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-geoclue-glue.h: ../interfaces/gc-iface-geoclue.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_geoclue --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-geocode-glue.h: ../interfaces/gc-iface-geocode.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_geocode --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-poi-glue.h: ../interfaces/gc-iface-poi.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_poi --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-position-glue.h: ../interfaces/gc-iface-position.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_position --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-position-ext-glue.h: ../interfaces/gc-iface-position-ext.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_position_ext --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-nmea-glue.h: ../interfaces/gc-iface-nmea.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_nmea --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-reverse-geocode-glue.h: ../interfaces/gc-iface-reverse-geocode.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_reverse_geocode --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-velocity-glue.h: ../interfaces/gc-iface-velocity.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_velocity --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-satellite-glue.h: ../interfaces/gc-iface-satellite.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_satellite --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+%-bindings.h: stamp-%-bindings.h
+ @true
+stamp-%-bindings.h: ../interfaces/%.xml
+ $(DBUS_BINDING_TOOL) --mode=glib-client --prefix=geoclue $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+geoclue_headers_to_scan_for_enums = geoclue-error.h
+# Generate the enums source code, with glib-mkenums:
+# This is based on the same Makefile.am stuff in pango:
+geoclue_built_headers = geoclue-enum-types.h
+geoclue_built_cfiles = geoclue-enum-types.c
+
+geoclue-enum-types.h: $(geoclue_headers_to_scan_for_enums) Makefile
+ $(AM_V_GEN) (cd $(srcdir) && glib-mkenums \
+ --fhead "#ifndef __GEOCLUE_ENUM_TYPES_H__\n#define __GEOCLUE_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name@_get_type (void);\n#define GEOCLUE_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __GEOCLUE_ENUM_TYPES_H__ */" \
+ $(geoclue_headers_to_scan_for_enums)) > $@
+
+geoclue-enum-types.c: $(geoclue_headers_to_scan_for_enums) Makefile geoclue-enum-types.h
+ $(AM_V_GEN) (cd $(srcdir) && glib-mkenums \
+ --fhead "#include <geoclue-error.h>\n" \
+ --fhead "#include \"geoclue-enum-types.h\"\n" \
+ --fhead "#include <glib-object.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(geoclue_headers_to_scan_for_enums)) > $@
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-address.c - GInterface for org.freedesktop.Address
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/gc-iface-address.h>
+
+enum {
+ ADDRESS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_address_get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+#include "gc-iface-address-glue.h"
+
+static void
+gc_iface_address_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[ADDRESS_CHANGED] = g_signal_new ("address-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_POINTER_BOXED,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT,
+ DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+ GEOCLUE_ACCURACY_TYPE);
+ dbus_g_object_type_install_info (gc_iface_address_get_type (),
+ &dbus_glib_gc_iface_address_object_info);
+}
+
+GType
+gc_iface_address_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceAddressClass),
+ gc_iface_address_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceAddress", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_address_get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_ADDRESS_GET_CLASS (gc)->get_address
+ (gc, timestamp, address, accuracy, error);
+}
+
+void
+gc_iface_address_emit_address_changed (GcIfaceAddress *gc,
+ int timestamp,
+ GHashTable *address,
+ GeoclueAccuracy *accuracy)
+{
+ g_signal_emit (gc, signals[ADDRESS_CHANGED], 0, timestamp,
+ address, accuracy);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-address.h - GInterface for org.freedesktop.Address
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_ADDRESS_H
+#define _GC_IFACE_ADDRESS_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-address-details.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_ADDRESS (gc_iface_address_get_type ())
+#define GC_IFACE_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_ADDRESS, GcIfaceAddress))
+#define GC_IFACE_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_ADDRESS, GcIfaceAddressClass))
+#define GC_IS_IFACE_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_ADDRESS))
+#define GC_IS_IFACE_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_ADDRESS))
+#define GC_IFACE_ADDRESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_ADDRESS, GcIfaceAddressClass))
+
+typedef struct _GcIfaceAddress GcIfaceAddress; /* Dummy typedef */
+typedef struct _GcIfaceAddressClass GcIfaceAddressClass;
+
+struct _GcIfaceAddressClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* address_changed) (GcIfaceAddress *gc,
+ int timestamp,
+ GHashTable *address,
+ GeoclueAccuracy *accuracy);
+
+ /* vtable */
+ gboolean (*get_address) (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+};
+
+GType gc_iface_address_get_type (void);
+
+void gc_iface_address_emit_address_changed (GcIfaceAddress *gc,
+ int timestamp,
+ GHashTable *address,
+ GeoclueAccuracy *accuracy);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-geoclue.c - GInterface for org.freedesktop.Geoclue
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/gc-iface-geoclue.h>
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean gc_iface_geoclue_get_provider_info (GcIfaceGeoclue *gc,
+ gchar **name,
+ gchar **description,
+ GError **error);
+static gboolean gc_iface_geoclue_get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error);
+static gboolean gc_iface_geoclue_set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error);
+static void gc_iface_geoclue_add_reference (GcIfaceGeoclue *gc,
+ DBusGMethodInvocation *context);
+static void gc_iface_geoclue_remove_reference (GcIfaceGeoclue *gc,
+ DBusGMethodInvocation *context);
+
+#include "gc-iface-geoclue-glue.h"
+
+
+static void
+gc_iface_geoclue_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcIfaceGeoclueClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+ dbus_g_object_type_install_info (gc_iface_geoclue_get_type (),
+ &dbus_glib_gc_iface_geoclue_object_info);
+}
+
+GType
+gc_iface_geoclue_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceGeoclueClass),
+ gc_iface_geoclue_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceGeoclue", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_geoclue_get_provider_info (GcIfaceGeoclue *gc,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ return GC_IFACE_GEOCLUE_GET_CLASS (gc)->get_provider_info (gc,
+ name,
+ description,
+ error);
+}
+
+static gboolean
+gc_iface_geoclue_get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ return GC_IFACE_GEOCLUE_GET_CLASS (gc)->get_status (gc, status,
+ error);
+}
+
+static gboolean
+gc_iface_geoclue_set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ return GC_IFACE_GEOCLUE_GET_CLASS (gc)->set_options (gc, options,
+ error);
+}
+
+static void
+gc_iface_geoclue_add_reference (GcIfaceGeoclue *gc,
+ DBusGMethodInvocation *context)
+{
+ GC_IFACE_GEOCLUE_GET_CLASS (gc)->add_reference (gc, context);
+}
+static void
+gc_iface_geoclue_remove_reference (GcIfaceGeoclue *gc,
+ DBusGMethodInvocation *context)
+{
+ GC_IFACE_GEOCLUE_GET_CLASS (gc)->remove_reference (gc, context);
+}
+
+void
+gc_iface_geoclue_emit_status_changed (GcIfaceGeoclue *gc,
+ GeoclueStatus status)
+{
+ g_signal_emit (gc, signals[STATUS_CHANGED], 0, status);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-geoclue.h - GInterface for org.freedesktop.Geoclue
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_GEOCLUE_H
+#define _GC_IFACE_GEOCLUE_H
+
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_GEOCLUE (gc_iface_geoclue_get_type ())
+#define GC_IFACE_GEOCLUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_GEOCLUE, GcIfaceGeoclue))
+#define GC_IFACE_GEOCLUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_GEOCLUE, GcIfaceGeoclueClass))
+#define GC_IS_IFACE_GEOCLUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_GEOCLUE))
+#define GC_IS_IFACE_GEOCLUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_GEOCLUE))
+#define GC_IFACE_GEOCLUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_GEOCLUE, GcIfaceGeoclueClass))
+
+typedef struct _GcIfaceGeoclue GcIfaceGeoclue; /* Dummy typedef */
+typedef struct _GcIfaceGeoclueClass GcIfaceGeoclueClass;
+
+struct _GcIfaceGeoclueClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* status_changed) (GcIfaceGeoclue *geoclue,
+ GeoclueStatus status);
+
+ /* vtable */
+ gboolean (*get_provider_info) (GcIfaceGeoclue *gc,
+ gchar **name,
+ gchar **description,
+ GError **error);
+ gboolean (*get_status) (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error);
+ gboolean (*set_options) (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error);
+ void (*add_reference) (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context);
+ void (*remove_reference) (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context);
+};
+
+GType gc_iface_geoclue_get_type (void);
+
+void gc_iface_geoclue_emit_status_changed (GcIfaceGeoclue *gc,
+ GeoclueStatus status);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-geocode.c - GInterface for org.freedesktop.Geocode
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/* This is a GInterface for implementing Geoclue Geocode providers */
+
+#include <glib.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/gc-iface-geocode.h>
+
+static gboolean
+gc_iface_geocode_address_to_position (GcIfaceGeocode *gc,
+ GHashTable *address,
+ int *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+static gboolean
+gc_iface_geocode_freeform_address_to_position (GcIfaceGeocode *gc,
+ const char *address,
+ int *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+#include "gc-iface-geocode-glue.h"
+
+static void
+gc_iface_geocode_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ dbus_g_object_type_install_info (gc_iface_geocode_get_type (),
+ &dbus_glib_gc_iface_geocode_object_info);
+}
+
+GType
+gc_iface_geocode_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceGeocodeClass),
+ gc_iface_geocode_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceGeocode", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_geocode_address_to_position (GcIfaceGeocode *gc,
+ GHashTable *address,
+ int *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_GEOCODE_GET_CLASS (gc)->address_to_position
+ (gc, address, (GeocluePositionFields *) fields,
+ latitude, longitude, altitude, accuracy, error);
+}
+
+static gboolean
+gc_iface_geocode_freeform_address_to_position (GcIfaceGeocode *gc,
+ const char *address,
+ int *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_GEOCODE_GET_CLASS (gc)->freeform_address_to_position
+ (gc, address, (GeocluePositionFields *) fields,
+ latitude, longitude, altitude, accuracy, error);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-geocode.h - GInterface for org.freedesktop.Geocode
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_GEOCODE_H
+#define _GC_IFACE_GEOCODE_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_GEOCODE (gc_iface_geocode_get_type ())
+#define GC_IFACE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_GEOCODE, GcIfaceGeocode))
+#define GC_IFACE_GEOCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_GEOCODE, GcIfaceGeocodeClass))
+#define GC_IS_IFACE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_GEOCODE))
+#define GC_IS_IFACE_GEOCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_GEOCODE))
+#define GC_IFACE_GEOCODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_GEOCODE, GcIfaceGeocodeClass))
+
+typedef struct _GcIfaceGeocode GcIfaceGeocode; /* Dummy typedef */
+typedef struct _GcIfaceGeocodeClass GcIfaceGeocodeClass;
+
+struct _GcIfaceGeocodeClass {
+ GTypeInterface base_iface;
+
+ /* vtable */
+ gboolean (*address_to_position) (GcIfaceGeocode *gc,
+ GHashTable *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+ gboolean (*freeform_address_to_position) (GcIfaceGeocode *gc,
+ const char *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+};
+
+GType gc_iface_geocode_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-nmea.c - GInterface for org.freedesktop.Geoclue.Nmea
+ *
+ * Author: Tae-Hwan Kim <the81.kim@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <geoclue/gc-iface-nmea.h>
+#include <geoclue/geoclue-marshal.h>
+
+enum {
+ NMEA_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_nmea_get_nmea (GcIfaceNmea *nmea,
+ int *timestamp,
+ char **nmea_data,
+ GError **error);
+
+#include "gc-iface-nmea-glue.h"
+
+static void
+gc_iface_nmea_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[NMEA_CHANGED] = g_signal_new ("nmea-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_STRING);
+
+ dbus_g_object_type_install_info (gc_iface_nmea_get_type (),
+ &dbus_glib_gc_iface_nmea_object_info);
+}
+
+GType
+gc_iface_nmea_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceNmeaClass),
+ gc_iface_nmea_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceNmea", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_nmea_get_nmea (GcIfaceNmea *gc,
+ int *timestamp,
+ char **nmea_data,
+ GError **error)
+{
+ return GC_IFACE_NMEA_GET_CLASS (gc)->get_nmea (gc, timestamp, nmea_data, error);
+}
+
+void
+gc_iface_nmea_emit_nmea_changed (GcIfaceNmea *gc,
+ int timestamp,
+ char *nmea_data)
+{
+ g_signal_emit (gc, signals[NMEA_CHANGED], 0, timestamp, nmea_data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-nmea.h - GInterface for org.freedesktop.Geoclue.Nmea
+ *
+ * Author: Tae-Hwan Kim <the81.kim@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_NMEA_H
+#define _GC_IFACE_NMEA_H
+
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_NMEA (gc_iface_nmea_get_type ())
+#define GC_IFACE_NMEA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_NMEA, GcIfaceNmea))
+#define GC_IFACE_NMEA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_NMEA, GcIfaceNmeaClass))
+#define GC_IS_IFACE_NMEA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_NMEA))
+#define GC_IS_IFACE_NMEA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_NMEA))
+#define GC_IFACE_NMEA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_NMEA, GcIfaceNmeaClass))
+
+typedef struct _GcIfaceNmea GcIfaceNmea; /* Dummy typedef */
+
+typedef struct _GcIfaceNmeaClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* nmea_changed) (GcIfaceNmea *gc,
+ int timestamp,
+ char *nmea_data);
+
+ /* vtable */
+ gboolean (* get_nmea) (GcIfaceNmea *gc,
+ int *timestamp,
+ char **nmea_data,
+ GError **error);
+} GcIfaceNmeaClass;
+
+GType gc_iface_nmea_get_type (void);
+
+void gc_iface_nmea_emit_nmea_changed (GcIfaceNmea *gc,
+ int timestamp,
+ char *nmea_data);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-poi.c - GInterface for org.freedesktop.Poi
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/* This is a GInterface for implementing Geoclue Poi providers */
+
+#include <glib.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/gc-iface-poi.h>
+
+static gboolean
+gc_iface_poi_search_by_position (GcIfacePoi *gc,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error);
+
+#include "gc-iface-poi-glue.h"
+
+static void
+gc_iface_poi_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ dbus_g_object_type_install_info (gc_iface_poi_get_type (),
+ &dbus_glib_gc_iface_poi_object_info);
+}
+
+GType
+gc_iface_poi_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfacePoiClass),
+ gc_iface_poi_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfacePoi", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_poi_search_by_position (GcIfacePoi *gc,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error)
+{
+ return GC_IFACE_POI_GET_CLASS (gc)->search_by_position
+ (gc, keyword, lang, country_code, limit, left, top, right, bottom, count, landmark, error);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-poi.h - GInterface for org.freedesktop.Poi
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_POI_H
+#define _GC_IFACE_POI_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_POI (gc_iface_poi_get_type ())
+#define GC_IFACE_POI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_POI, GcIfacePoi))
+#define GC_IFACE_POI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_POI, GcIfacePoiClass))
+#define GC_IS_IFACE_POI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_POI))
+#define GC_IS_IFACE_POI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_POI))
+#define GC_IFACE_POI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_POI, GcIfacePoiClass))
+
+typedef struct _GcIfacePoi GcIfacePoi; /* Dummy typedef */
+typedef struct _GcIfacePoiClass GcIfacePoiClass;
+
+struct _GcIfacePoiClass {
+ GTypeInterface base_iface;
+
+ /* vtable */
+ gboolean (*search_by_position) (GcIfacePoi *gc,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error);
+};
+
+GType gc_iface_poi_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-position.c - GInterface for org.freedesktop.Geoclue.Position
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <geoclue/gc-iface-position-ext.h>
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-accuracy.h>
+
+enum {
+ POSITION_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_position_ext_get_position (GcIfacePositionExt *position,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+static gboolean
+gc_iface_position_ext_get_last_position (GcIfacePositionExt *position,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+#include "gc-iface-position-ext-glue.h"
+
+static void
+gc_iface_position_ext_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 9,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ GEOCLUE_ACCURACY_TYPE);
+
+ dbus_g_object_type_install_info (gc_iface_position_ext_get_type (),
+ &dbus_glib_gc_iface_position_ext_object_info);
+}
+
+GType
+gc_iface_position_ext_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfacePositionExtClass),
+ gc_iface_position_ext_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfacePositionExt", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_position_ext_get_position (GcIfacePositionExt *gc,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_POSITION_EXT_GET_CLASS (gc)->get_position
+ (gc, (GeocluePositionExtFields *) fields, timestamp,
+ latitude, longitude, altitude, speed, direction, climb, accuracy, error);
+}
+
+static gboolean
+gc_iface_position_ext_get_last_position (GcIfacePositionExt *gc,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_POSITION_EXT_GET_CLASS (gc)->get_last_position
+ (gc, (GeocluePositionExtFields *) fields, timestamp,
+ latitude, longitude, altitude, speed, direction, climb, accuracy, error);
+}
+
+void
+gc_iface_position_ext_emit_position_changed (GcIfacePositionExt *gc,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy)
+{
+ g_signal_emit (gc, signals[POSITION_CHANGED], 0, fields, timestamp,
+ latitude, longitude, altitude, speed, direction, climb, accuracy);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-position-ext.h - GInterface for org.freedesktop.Geoclue.PositionExt
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_POSITION_EXT_H
+#define _GC_IFACE_POSITION_EXT_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_POSITION_EXT (gc_iface_position_ext_get_type ())
+#define GC_IFACE_POSITION_EXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_POSITION_EXT, GcIfacePositionExt))
+#define GC_IFACE_POSITION_EXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_POSITION_EXT, GcIfacePositionExtClass))
+#define GC_IS_IFACE_POSITION_EXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_POSITION_VELOCITY))
+#define GC_IS_IFACE_POSITION_EXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_POSITION_EXT))
+#define GC_IFACE_POSITION_EXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_POSITION_EXT, GcIfacePositionExtClass))
+
+typedef struct _GcIfacePositionExt GcIfacePositionExt; /* Dummy typedef */
+typedef struct _GcIfacePositionExtClass GcIfacePositionExtClass;
+
+struct _GcIfacePositionExtClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* position_changed) (GcIfacePositionExt *gc,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy);
+
+ /* vtable */
+ gboolean (* get_position) (GcIfacePositionExt *gc,
+ GeocluePositionExtFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+ /* vtable */
+ gboolean (* get_last_position) (GcIfacePositionExt *gc,
+ GeocluePositionExtFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+};
+
+GType gc_iface_position_ext_get_type (void);
+
+void gc_iface_position_ext_emit_position_changed (GcIfacePositionExt *gc,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-position.c - GInterface for org.freedesktop.Geoclue.Position
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-accuracy.h>
+
+enum {
+ POSITION_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_position_get_position (GcIfacePosition *position,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+static gboolean
+gc_iface_position_get_last_position (GcIfacePosition *position,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+#include "gc-iface-position-glue.h"
+
+static void
+gc_iface_position_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 6,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ GEOCLUE_ACCURACY_TYPE);
+
+ dbus_g_object_type_install_info (gc_iface_position_get_type (),
+ &dbus_glib_gc_iface_position_object_info);
+}
+
+GType
+gc_iface_position_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfacePositionClass),
+ gc_iface_position_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfacePosition", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_position_get_position (GcIfacePosition *gc,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_POSITION_GET_CLASS (gc)->get_position
+ (gc, (GeocluePositionFields *) fields, timestamp,
+ latitude, longitude, altitude, accuracy, error);
+}
+
+static gboolean
+gc_iface_position_get_last_position (GcIfacePosition *gc,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ return GC_IFACE_POSITION_GET_CLASS (gc)->get_last_position
+ (gc, (GeocluePositionFields *) fields, timestamp,
+ latitude, longitude, altitude, accuracy, error);
+}
+
+void
+gc_iface_position_emit_position_changed (GcIfacePosition *gc,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy)
+{
+ g_signal_emit (gc, signals[POSITION_CHANGED], 0, fields, timestamp,
+ latitude, longitude, altitude, accuracy);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-position.h - GInterface for org.freedesktop.Geoclue.Position
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_POSITION_H
+#define _GC_IFACE_POSITION_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_POSITION (gc_iface_position_get_type ())
+#define GC_IFACE_POSITION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_POSITION, GcIfacePosition))
+#define GC_IFACE_POSITION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_POSITION, GcIfacePositionClass))
+#define GC_IS_IFACE_POSITION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_POSITION))
+#define GC_IS_IFACE_POSITION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_POSITION))
+#define GC_IFACE_POSITION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_POSITION, GcIfacePositionClass))
+
+typedef struct _GcIfacePosition GcIfacePosition; /* Dummy typedef */
+typedef struct _GcIfacePositionClass GcIfacePositionClass;
+
+struct _GcIfacePositionClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* position_changed) (GcIfacePosition *gc,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy);
+
+ /* vtable */
+ gboolean (* get_position) (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+ /* vtable */
+ gboolean (* get_last_position) (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+};
+
+GType gc_iface_position_get_type (void);
+
+void gc_iface_position_emit_position_changed (GcIfacePosition *gc,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-reverse-geocode.c - GInterface for org.freedesktop.ReverseGeocode
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/gc-iface-reverse-geocode.h>
+
+static gboolean
+gc_iface_reverse_geocode_position_to_address (GcIfaceReverseGeocode *gc,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **address,
+ GeoclueAccuracy **address_accuracy,
+ GError **error);
+#include "gc-iface-reverse-geocode-glue.h"
+
+static void
+gc_iface_reverse_geocode_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ dbus_g_object_type_install_info (gc_iface_reverse_geocode_get_type (),
+ &dbus_glib_gc_iface_reverse_geocode_object_info);
+}
+
+GType
+gc_iface_reverse_geocode_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceReverseGeocodeClass),
+ gc_iface_reverse_geocode_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceReverseGeocode", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_reverse_geocode_position_to_address (GcIfaceReverseGeocode *gc,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **address,
+ GeoclueAccuracy **address_accuracy,
+ GError **error)
+{
+ return GC_IFACE_REVERSE_GEOCODE_GET_CLASS (gc)->position_to_address
+ (gc, latitude, longitude, position_accuracy,
+ address, address_accuracy, error);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-reverse_geocode.h - GInterface for org.freedesktop.Reverse_Geocode
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_REVERSE_GEOCODE_H
+#define _GC_IFACE_REVERSE_GEOCODE_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_REVERSE_GEOCODE (gc_iface_reverse_geocode_get_type ())
+#define GC_IFACE_REVERSE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_REVERSE_GEOCODE, GcIfaceReverseGeocode))
+#define GC_IFACE_REVERSE_GEOCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_REVERSE_GEOCODE, GcIfaceReverseGeocodeClass))
+#define GC_IS_IFACE_REVERSE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_REVERSE_GEOCODE))
+#define GC_IS_IFACE_REVERSE_GEOCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_REVERSE_GEOCODE))
+#define GC_IFACE_REVERSE_GEOCODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_REVERSE_GEOCODE, GcIfaceReverseGeocodeClass))
+
+typedef struct _GcIfaceReverseGeocode GcIfaceReverseGeocode; /* Dummy typedef */
+typedef struct _GcIfaceReverseGeocodeClass GcIfaceReverseGeocodeClass;
+
+struct _GcIfaceReverseGeocodeClass {
+ GTypeInterface base_iface;
+
+ /* vtable */
+ gboolean (*position_to_address) (GcIfaceReverseGeocode *gc,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **address,
+ GeoclueAccuracy **address_accuracy,
+ GError **error);
+};
+
+GType gc_iface_reverse_geocode_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-satellite.c - GInterface for org.freedesktop.Geoclue.Satellite
+ *
+ * Author: Sagnho Park <sangho.g.park@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <geoclue/gc-iface-satellite.h>
+#include <geoclue/geoclue-marshal.h>
+
+enum {
+ SATELLITE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_satellite_get_satellite (GcIfaceSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+
+static gboolean
+gc_iface_satellite_get_last_satellite (GcIfaceSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+
+#include "gc-iface-satellite-glue.h"
+
+static void
+gc_iface_satellite_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[SATELLITE_CHANGED] = g_signal_new ("satellite-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_INT_POINTER_POINTER,
+ G_TYPE_NONE, 5,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ DBUS_TYPE_G_INT_ARRAY,
+ GEOCLUE_SATELLITE_INFO_ARRAY);
+ dbus_g_object_type_install_info (gc_iface_satellite_get_type (),
+ &dbus_glib_gc_iface_satellite_object_info);
+}
+
+GType
+gc_iface_satellite_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceSatelliteClass),
+ gc_iface_satellite_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceSatellite", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_satellite_get_satellite (GcIfaceSatellite *gc,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error)
+{
+ return GC_IFACE_SATELLITE_GET_CLASS (gc)->get_satellite (gc,
+ timestamp,
+ satellite_used,
+ satellite_visible,
+ used_prn,
+ sat_info,
+ error);
+}
+
+static gboolean
+gc_iface_satellite_get_last_satellite (GcIfaceSatellite *gc,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error)
+{
+ return GC_IFACE_SATELLITE_GET_CLASS (gc)->get_last_satellite (gc,
+ timestamp,
+ satellite_used,
+ satellite_visible,
+ used_prn,
+ sat_info,
+ error);
+}
+
+void
+gc_iface_satellite_emit_satellite_changed (GcIfaceSatellite *gc,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info)
+{
+ g_signal_emit (gc, signals[SATELLITE_CHANGED], 0,
+ timestamp, satellite_used, satellite_visible,
+ used_prn, sat_info);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-satellite.c - GInterface for org.freedesktop.Geoclue.Satellite
+ *
+ * Author: Sagnho Park <sangho.g.park@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_SATELLITE_H
+#define _GC_IFACE_SATELLITE_H
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-satellite-info.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_SATELLITE (gc_iface_satellite_get_type ())
+#define GC_IFACE_SATELLITE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_SATELLITE, GcIfaceSatellite))
+#define GC_IFACE_SATELLITE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_SATELLITE, GcIfaceSatelliteClass))
+#define GC_IS_IFACE_SATELLITE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_SATELLITE))
+#define GC_IS_IFACE_SATELLITE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_SATELLITE))
+#define GC_IFACE_SATELLITE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_SATELLITE, GcIfaceSatelliteClass))
+
+typedef struct _GcIfaceSatellite GcIfaceSatellite; /* Dummy typedef */
+typedef struct _GcIfaceSatelliteClass GcIfaceSatelliteClass;
+
+struct _GcIfaceSatelliteClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* satellite_changed) (GcIfaceSatellite *gc,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info);
+
+ /* vtable */
+ gboolean (* get_satellite) (GcIfaceSatellite *gc,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+
+ /* vtable */
+ gboolean (* get_last_satellite) (GcIfaceSatellite *gc,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+};
+
+GType gc_iface_satellite_get_type (void);
+
+void gc_iface_satellite_emit_satellite_changed (GcIfaceSatellite *gc,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-velocity.c - GInterface for org.freedesktop.Geoclue.Velocity
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+
+#include <dbus/dbus-glib.h>
+#include <geoclue/gc-iface-velocity.h>
+#include <geoclue/geoclue-marshal.h>
+
+enum {
+ VELOCITY_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static gboolean
+gc_iface_velocity_get_velocity (GcIfaceVelocity *velocity,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GError **error);
+
+static gboolean
+gc_iface_velocity_get_last_velocity (GcIfaceVelocity *velocity,
+ int *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GError **error);
+
+#include "gc-iface-velocity-glue.h"
+
+static void
+gc_iface_velocity_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+ initialized = TRUE;
+
+ signals[VELOCITY_CHANGED] = g_signal_new ("velocity-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE,
+ G_TYPE_NONE, 5,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE);
+ dbus_g_object_type_install_info (gc_iface_velocity_get_type (),
+ &dbus_glib_gc_iface_velocity_object_info);
+}
+
+GType
+gc_iface_velocity_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GcIfaceVelocityClass),
+ gc_iface_velocity_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GcIfaceVelocity", &info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gc_iface_velocity_get_velocity (GcIfaceVelocity *gc,
+ int *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ return GC_IFACE_VELOCITY_GET_CLASS (gc)->get_velocity
+ (gc, (GeoclueVelocityFields *) fields, timestamp,
+ speed, direction, climb, error);
+}
+
+static gboolean
+gc_iface_velocity_get_last_velocity (GcIfaceVelocity *gc,
+ int *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ return GC_IFACE_VELOCITY_GET_CLASS (gc)->get_last_velocity
+ (gc, (GeoclueVelocityFields *) fields, timestamp,
+ speed, direction, climb, error);
+}
+
+void
+gc_iface_velocity_emit_velocity_changed (GcIfaceVelocity *gc,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb)
+{
+ g_signal_emit (gc, signals[VELOCITY_CHANGED], 0, fields, timestamp,
+ speed, direction, climb);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-velocity.h - GInterface for org.freedesktop.Geoclue.Velocity
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_IFACE_VELOCITY_H
+#define _GC_IFACE_VELOCITY_H
+
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_IFACE_VELOCITY (gc_iface_velocity_get_type ())
+#define GC_IFACE_VELOCITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_IFACE_VELOCITY, GcIfaceVelocity))
+#define GC_IFACE_VELOCITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_IFACE_VELOCITY, GcIfaceVelocityClass))
+#define GC_IS_IFACE_VELOCITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_IFACE_VELOCITY))
+#define GC_IS_IFACE_VELOCITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_IFACE_VELOCITY))
+#define GC_IFACE_VELOCITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GC_TYPE_IFACE_VELOCITY, GcIfaceVelocityClass))
+
+typedef struct _GcIfaceVelocity GcIfaceVelocity; /* Dummy typedef */
+typedef struct _GcIfaceVelocityClass GcIfaceVelocityClass;
+
+struct _GcIfaceVelocityClass {
+ GTypeInterface base_iface;
+
+ /* signals */
+ void (* velocity_changed) (GcIfaceVelocity *gc,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb);
+
+ /* vtable */
+ gboolean (* get_velocity) (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error);
+
+ /* vtable */
+ gboolean (* get_last_velocity) (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error);
+};
+
+GType gc_iface_velocity_get_type (void);
+
+void gc_iface_velocity_emit_velocity_changed (GcIfaceVelocity *gc,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-provider.c - A provider object that handles the basic D-Bus required for
+ * a provider.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:gc-provider
+ * @short_description: Abstract class to derive Geoclue providers from.
+ *
+ * #GcProvider is an abstract class that all Geoclue providers should
+ * derive from. It takes care of setting up the provider D-Bus service,
+ * and also implements #GcIfaceGeoclue interface (derived classes still
+ * need to implement the functionality).
+ *
+ * Derived classes should define the #GcIfaceGeoclue methods in their
+ * class_init() and call gc_provider_set_details() in init()
+ *
+ */
+#include <config.h>
+
+#include <string.h>
+#include <glib-object.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+
+
+typedef struct {
+ char *name;
+ char *description;
+
+ GHashTable *connections;
+} GcProviderPrivate;
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GC_TYPE_PROVIDER, GcProviderPrivate))
+
+static void gc_provider_geoclue_init (GcIfaceGeoclueClass *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GcProvider, gc_provider, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE,
+ gc_provider_geoclue_init))
+
+static void
+finalize (GObject *object)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->name);
+ g_free (priv->description);
+
+ ((GObjectClass *) gc_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->connections);
+
+ ((GObjectClass *) gc_provider_parent_class)->dispose (object);
+}
+
+static void
+gc_provider_class_init (GcProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ klass->shutdown = NULL;
+
+ g_type_class_add_private (klass, sizeof (GcProviderPrivate));
+}
+
+static void
+gc_provider_init (GcProvider *provider)
+{
+ GError *error = NULL;
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ provider->connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (provider->connection == NULL) {
+ g_warning ("%s was unable to create a connection to D-Bus: %s",
+ G_OBJECT_TYPE_NAME (provider), error->message);
+ g_error_free (error);
+ }
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+
+static void
+gc_provider_shutdown (GcProvider *provider)
+{
+ GC_PROVIDER_GET_CLASS (provider)->shutdown (provider);
+}
+
+
+static gboolean
+get_provider_info (GcIfaceGeoclue *geoclue,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ GcProvider *provider = GC_PROVIDER (geoclue);
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (name) {
+ *name = g_strdup (priv->name);
+ }
+ if (description) {
+ *description = g_strdup (priv->description);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GcProviderClass *klass;
+
+ klass = GC_PROVIDER_GET_CLASS (geoclue);
+ if (klass->get_status) {
+ return klass->get_status (geoclue, status, error);
+ } else {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_IMPLEMENTED,
+ "get_status is not implemented");
+ return FALSE;
+ }
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error)
+{
+ GcProviderClass *klass;
+
+ klass = GC_PROVIDER_GET_CLASS (geoclue);
+ if (klass->set_options) {
+ return klass->set_options (geoclue, options, error);
+ }
+
+ /* It is not an error to not have a SetOptions implementation */
+ return TRUE;
+}
+
+static gboolean
+gc_provider_remove_client (GcProvider *provider, const char *client)
+{
+ int *pcount;
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ pcount = g_hash_table_lookup (priv->connections, client);
+ if (!pcount) {
+ g_debug("Client[%s] is already removed", client);
+ return FALSE;
+ }
+ (*pcount)--;
+ g_debug("Client[%s] has reference count[%d]", client, *pcount);
+ if (*pcount == 0) {
+ g_debug("Reference count is zero, Now remove client[%s] in hash table", client);
+ g_hash_table_remove (priv->connections, client);
+ }
+ if (g_hash_table_size (priv->connections) == 0) {
+ g_debug("Hash table size is zero, Now we shutdown provider[%s]", priv->name);
+ gc_provider_shutdown (provider);
+ }
+ return TRUE;
+}
+
+static gboolean
+gc_provider_remove_client_by_force(GcProvider *provider, const char *client)
+{
+ int *pcount;
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+
+ pcount = g_hash_table_lookup (priv->connections, client);
+ if(!pcount){
+ g_debug("Client(%s) is already removed", client);
+ return FALSE;
+ }
+
+ (*pcount)--;
+ g_debug("Client(%s) has reference count[%d]. Anway, we will remove it by force!", client, *pcount);
+ g_hash_table_remove (priv->connections, client);
+ if (g_hash_table_size (priv->connections) == 0) {
+ g_debug("Hash table size is zero, Now we shutdown provider[%s]", priv->name);
+ gc_provider_shutdown (provider);
+ }
+ return TRUE;
+}
+
+
+static void
+add_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (geoclue);
+ char *sender;
+ int *pcount;
+
+ /* Update the hash of open connections */
+ sender = dbus_g_method_get_sender (context);
+ pcount = g_hash_table_lookup (priv->connections, sender);
+ if (!pcount) {
+ pcount = g_malloc0 (sizeof (int));
+ g_hash_table_insert (priv->connections, sender, pcount);
+ }
+ (*pcount)++;
+
+ dbus_g_method_return (context);
+}
+
+static void
+remove_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ GcProvider *provider = GC_PROVIDER (geoclue);
+ char *sender;
+
+ sender = dbus_g_method_get_sender (context);
+ if (!gc_provider_remove_client (provider, sender)) {
+ g_warning ("Unreffed by client that has not been referenced");
+ }
+
+ g_free (sender);
+
+ dbus_g_method_return (context);
+}
+
+static void
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ GcProvider *provider)
+{
+ g_debug("name_owner_changed, name:%s, prev_owner:%s, new_owner:%s", name, prev_owner, new_owner);
+ if (strcmp (new_owner, "") == 0 && strcmp (name, prev_owner) == 0) {
+ if (gc_provider_remove_client_by_force (provider, prev_owner)) {
+ g_warning ("Impolite client %s disconnected without unreferencing\n", prev_owner);
+ }
+ }
+}
+
+static void
+gc_provider_geoclue_init (GcIfaceGeoclueClass *iface)
+{
+ iface->get_provider_info = get_provider_info;
+ iface->get_status = get_status;
+ iface->set_options = set_options;
+ iface->add_reference = add_reference;
+ iface->remove_reference = remove_reference;
+}
+
+
+/**
+ * gc_provider_set_details:
+ * @provider: A #GcProvider object
+ * @service: The service name to be requested
+ * @path: The path the object should be registered at
+ * @name: The provider name
+ * @description: The description of the provider
+ *
+ * Requests ownership of the @service name, and if that succeeds registers
+ * @provider at @path. @name should be the name of the provider (e.g.
+ * "Hostip"), @description should be a short description of the provider
+ * (e.g. "Web service based Position & Address provider (http://hostip.info)").
+ */
+void
+gc_provider_set_details (GcProvider *provider,
+ const char *service,
+ const char *path,
+ const char *name,
+ const char *description)
+{
+ GcProviderPrivate *priv = GET_PRIVATE (provider);
+ GError *error = NULL;
+ DBusGProxy *driver;
+ guint request_ret;
+
+ g_return_if_fail (GC_IS_PROVIDER (provider));
+ g_return_if_fail (provider->connection != NULL);
+ g_return_if_fail (service != NULL);
+ g_return_if_fail (path != NULL);
+
+ driver = dbus_g_proxy_new_for_name (provider->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+
+ if (!org_freedesktop_DBus_request_name (driver, service, 0,
+ &request_ret, &error)) {
+ g_warning ("%s was unable to register service %s: %s",
+ G_OBJECT_TYPE_NAME (provider), service,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ dbus_g_proxy_add_signal (driver, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (driver, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed),
+ provider, NULL);
+
+ dbus_g_connection_register_g_object (provider->connection,
+ path, G_OBJECT (provider));
+
+ priv->name = g_strdup (name);
+ priv->description = g_strdup (description);
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-provider.h - A provider object that handles the basic D-Bus required for
+ * a provider.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GC_PROVIDER
+#define _GC_PROVIDER
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/gc-iface-geoclue.h>
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_PROVIDER (gc_provider_get_type ())
+
+#define GC_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_PROVIDER, GcProvider))
+#define GC_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_PROVIDER, GcProviderClass))
+#define GC_IS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_PROVIDER))
+#define GC_IS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_PROVIDER))
+#define GC_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GC_TYPE_PROVIDER, GcProviderClass))
+
+typedef struct _GcProvider {
+ GObject parent_class;
+
+ DBusGConnection *connection;
+} GcProvider;
+
+typedef struct _GcProviderClass {
+ GObjectClass parent_class;
+
+ void (*shutdown) (GcProvider *provider);
+
+ /* Implements the GcIfaceGeoclue interface */
+ gboolean (*get_status) (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error);
+ gboolean (*set_options) (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error);
+} GcProviderClass;
+
+GType gc_provider_get_type (void);
+
+void gc_provider_set_details (GcProvider *provider,
+ const char *service,
+ const char *path,
+ const char *name,
+ const char *description);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-web-service.c - A web service helper object for geoclue providers
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * Copyright 2007 Jussi Kukkonen (from old geoclue_web_service.c)
+ * Copyright 2007, 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:gc-web-service
+ * @short_description: Web service helper object for Geoclue providers.
+ *
+ * #GcWebService is a web service abstraction for Geoclue provider
+ * implementations. It handles basic http stuff and xml parsing
+ * (although the raw data is available through
+ * gc_web_service_get_response() as well).
+ *
+ * At the moment xml parsing functions only exist for double and
+ * char-array data types. Adding new functions is trivial, though.
+ * <informalexample>
+ * <programlisting>
+ * . . .
+ *
+ * #GcWebService *web_service;
+ * web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ * gc_web_service_set_base_url (web_service, "http://example.org");
+ *
+ * / * Add namespaces if needed * /
+ * gc_web_service_add_namespace (web_service,
+ * "ns_name", "http://example.org/ns");
+ *
+ * . . .
+ *
+ * / * Fetch document "http://api.example.org?key1=val1&key2=val2" * /
+ * if (!gc_web_service_query (web_service,
+ * "key1", "val1"
+ * "key2", val2"
+ * (char *)0)) {
+ * / * error * /
+ * return;
+ * }
+ *
+ * / * Use XPath expressions to parse the xml in fetched document * /
+ * gchar *str;
+ * if (gc_web_service_get_string (web_service,
+ * &str, "//path/to/element")) {
+ * g_debug("got string: %s", str);
+ * }
+ *
+ * gdouble number;
+ * if (gc_web_service_get_double (web_service,
+ * &number, "//path/to/another/element")) {
+ * g_debug("got double: %f", number);
+ * }
+ *
+ * . . .
+ *
+ * g_object_unref (G_OBJECT (web_service));
+ * </programlisting>
+ * </informalexample>
+ */
+
+#include <stdarg.h>
+#include <glib-object.h>
+#include <string.h>
+
+#include <libxml/nanohttp.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/uri.h> /* for xmlURIEscapeStr */
+
+#include "gc-web-service.h"
+#include "geoclue-error.h"
+
+G_DEFINE_TYPE (GcWebService, gc_web_service, G_TYPE_OBJECT)
+
+typedef struct _XmlNamespace {
+ gchar *name;
+ gchar *uri;
+}XmlNamespace;
+
+/* GFunc, use with g_list_foreach */
+static void
+gc_web_service_register_ns (gpointer data, gpointer user_data)
+{
+ GcWebService *self = (GcWebService *)user_data;
+ XmlNamespace *ns = (XmlNamespace *)data;
+
+ xmlXPathRegisterNs (self->xpath_ctx,
+ (xmlChar*)ns->name, (xmlChar*)ns->uri);
+}
+
+/* GFunc, use with g_list_foreach */
+static void
+gc_web_service_free_ns (gpointer data, gpointer user_data)
+{
+ XmlNamespace *ns = (XmlNamespace *)data;
+
+ g_free (ns->name);
+ g_free (ns->uri);
+ g_free (ns);
+}
+
+
+/* Register namespaces listed in self->namespaces */
+static void
+gc_web_service_register_namespaces (GcWebService *self)
+{
+ g_assert (self->xpath_ctx);
+ g_list_foreach (self->namespaces, (GFunc)gc_web_service_register_ns, self);
+}
+
+static void
+gc_web_service_reset (GcWebService *self)
+{
+ g_free (self->response);
+ self->response = NULL;
+ self->response_length = 0;
+
+ if (self->xpath_ctx) {
+ if (self->xpath_ctx->doc) {
+ xmlFreeDoc (self->xpath_ctx->doc);
+ }
+ xmlXPathFreeContext (self->xpath_ctx);
+ self->xpath_ctx = NULL;
+ }
+}
+
+/* Parse data (self->response), build xpath context and register
+ * namespaces. Nothing will be done if xpath context exists already. */
+static gboolean
+gc_web_service_build_xpath_context (GcWebService *self)
+{
+ xmlDocPtr doc;
+ xmlChar *tmp;
+
+ /* don't rebuild if there's no need */
+ if (self->xpath_ctx) {
+ return TRUE;
+ }
+
+ /* make sure response is NULL-terminated */
+ tmp = xmlStrndup(self->response, self->response_length);
+ doc = xmlParseDoc (tmp);
+ if (!doc) {
+ /* TODO: error handling */
+ g_free (tmp);
+ return FALSE;
+ }
+ xmlFree (tmp);
+
+ self->xpath_ctx = xmlXPathNewContext(doc);
+ if (!self->xpath_ctx) {
+ /* TODO: error handling */
+ return FALSE;
+ }
+ gc_web_service_register_namespaces (self);
+ return TRUE;
+}
+
+/* fetch data from url, save into self->response */
+static gboolean
+gc_web_service_fetch (GcWebService *self, gchar *url, GError **error)
+{
+ void* ctxt = NULL;
+ gint len;
+ xmlChar buf[1024];
+ xmlBuffer *output;
+ char *system_http_proxy = NULL;
+ char http_proxy[128] = {0,};
+
+ g_assert (url);
+
+ gc_web_service_reset (self);
+
+ xmlNanoHTTPInit();
+
+ system_http_proxy = getenv("http_proxy");
+ if (system_http_proxy != NULL) {
+ if (strncmp(system_http_proxy, "http://", 7)) {
+ snprintf(http_proxy, sizeof(http_proxy), "http://%s", system_http_proxy);
+ } else {
+ snprintf(http_proxy, sizeof(http_proxy), "%s", system_http_proxy);
+ }
+ xmlNanoHTTPScanProxy(http_proxy);
+ }
+
+ ctxt = xmlNanoHTTPMethod (url, "GET", NULL, NULL, NULL, 0);
+ if (!ctxt) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ g_strdup_printf ("xmlNanoHTTPMethod did not get a response from %s\n", url));
+ return FALSE;
+ }
+
+ output = xmlBufferCreate ();
+ while ((len = xmlNanoHTTPRead (ctxt, buf, sizeof(buf))) > 0) {
+ if (xmlBufferAdd (output, buf, len) != 0) {
+ xmlNanoHTTPClose(ctxt);
+ xmlBufferFree (output);
+
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ g_strdup_printf ("libxml error (xmlBufferAdd failed)"));
+
+ return FALSE;
+ }
+ }
+ xmlNanoHTTPClose(ctxt);
+
+ self->response_length = xmlBufferLength (output);
+ self->response = g_memdup (xmlBufferContent (output), self->response_length);
+ xmlBufferFree (output);
+
+ return TRUE;
+}
+
+static xmlXPathObject*
+gc_web_service_get_xpath_object (GcWebService *self, gchar* xpath)
+{
+ xmlXPathObject *obj = NULL;
+
+ g_return_val_if_fail (xpath, FALSE);
+
+ /* parse the doc if not parsed yet and register namespaces */
+ if (!gc_web_service_build_xpath_context (self)) {
+ return FALSE;
+ }
+ g_assert (self->xpath_ctx);
+
+ obj = xmlXPathEvalExpression ((xmlChar*)xpath, self->xpath_ctx);
+ if (obj &&
+ (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval))) {
+ xmlXPathFreeObject (obj);
+ obj = NULL;
+ }
+ return obj;
+}
+
+static void
+gc_web_service_init (GcWebService *self)
+{
+ self->response = NULL;
+ self->response_length = 0;
+ self->xpath_ctx = NULL;
+ self->namespaces = NULL;
+ self->base_url = NULL;
+}
+
+
+static void
+gc_web_service_finalize (GObject *obj)
+{
+ GcWebService *self = (GcWebService *) obj;
+
+ gc_web_service_reset (self);
+
+ g_free (self->base_url);
+
+ g_list_foreach (self->namespaces, (GFunc)gc_web_service_free_ns, NULL);
+ g_list_free (self->namespaces);
+
+ ((GObjectClass *) gc_web_service_parent_class)->finalize (obj);
+}
+
+static void
+gc_web_service_class_init (GcWebServiceClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ o_class->finalize = gc_web_service_finalize;
+}
+
+/**
+ * gc_web_service_set_base_url:
+ * @self: The #GcWebService object
+ * @url: base url
+ *
+ * Sets base url for the web service. Must be called before calls to
+ * gc_web_service_get_* -methods.
+ */
+void
+gc_web_service_set_base_url (GcWebService *self, gchar *url)
+{
+ g_assert (url);
+
+ gc_web_service_reset (self);
+
+ g_free (self->base_url);
+ self->base_url = g_strdup (url);
+}
+
+/**
+ * gc_web_service_add_namespace:
+ * @self: The #GcWebService object
+ * @namespace: Namespace name
+ * @uri: Namespace uri
+ *
+ * Adds an xml namespace that will be used in all following calls to
+ * gc_web_service_get_*-functions.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_add_namespace (GcWebService *self, gchar *namespace, gchar *uri)
+{
+ XmlNamespace *ns;
+
+ g_return_val_if_fail (self->base_url, FALSE);
+
+ ns = g_new0 (XmlNamespace,1);
+ ns->name = g_strdup (namespace);
+ ns->uri = g_strdup (uri);
+ self->namespaces = g_list_prepend (self->namespaces, ns);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_query:
+ * @self: A #GcWebService object
+ * @Varargs: NULL-terminated list of key-value gchar* pairs
+ *
+ * Fetches data from the web. The url is constructed using the
+ * optional arguments as GET parameters (see example in the
+ * Description-section). Data should be read using
+ * gc_web_service_get_* -functions.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_query (GcWebService *self, GError **error, ...)
+{
+ va_list list;
+ gchar *key, *value, *esc_value, *tmp, *url;
+ gboolean first_pair = TRUE;
+
+ g_return_val_if_fail (self->base_url, FALSE);
+
+ url = g_strdup (self->base_url);
+
+ /* read the arguments one key-value pair at a time,
+ add the pairs to url as "?key1=value1&key2=value2&..." */
+ va_start (list, error);
+ key = va_arg (list, char*);
+ while (key) {
+ value = va_arg (list, char*);
+ esc_value = (gchar *)xmlURIEscapeStr ((xmlChar *)value, NULL);
+
+ if (first_pair) {
+ tmp = g_strdup_printf ("%s?%s=%s", url, key, esc_value);
+ first_pair = FALSE;
+ } else {
+ tmp = g_strdup_printf ("%s&%s=%s", url, key, esc_value);
+ }
+ g_free (esc_value);
+ g_free (url);
+ url = tmp;
+ key = va_arg (list, char*);
+ }
+ va_end (list);
+
+ if (!gc_web_service_fetch (self, url, error)) {
+ g_free (url);
+ return FALSE;
+ }
+ g_free (url);
+
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_double:
+ * @self: A #GcWebService object
+ * @value: Pointer to returned value
+ * @xpath: XPath expression to find the value
+ *
+ * Extracts a @value from the data that was fetched in the last call
+ * to gc_web_service_query() using XPath expression @xpath. Returned
+ * value is the first match.
+ *
+ * Return value: %TRUE if a value was found.
+ */
+gboolean
+gc_web_service_get_double (GcWebService *self, gdouble *value, gchar *xpath)
+{
+ xmlXPathObject *obj;
+
+ obj = gc_web_service_get_xpath_object (self, xpath);
+ if (!obj) {
+ return FALSE;
+ }
+ *value = xmlXPathCastNodeSetToNumber (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_string:
+ * @self: The #GcWebService object
+ * @value: pointer to newly allocated string
+ * @xpath: XPath expression used to find the value
+ *
+ * Extracts a @value from the data that was fetched in the last call
+ * to gc_web_service_query() using XPath expression @xpath (returned
+ * value is the first match).
+ *
+ * Return value: %TRUE if a value was found.
+ */
+gboolean
+gc_web_service_get_string (GcWebService *self, gchar **value, gchar* xpath)
+{
+ xmlXPathObject *obj;
+
+ obj = gc_web_service_get_xpath_object (self, xpath);
+ if (!obj) {
+ return FALSE;
+ }
+ *value = (char*)xmlXPathCastNodeSetToString (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+/**
+ * gc_web_service_get_response:
+ * @self: The #GcWebService object
+ * @response: returned guchar array
+ * @response_length: length of the returned array
+ *
+ * Returns the raw data fetched with the last call to
+ * gc_web_service_query(). Data may be unterminated.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gc_web_service_get_response (GcWebService *self, guchar **response, gint *response_length)
+{
+ *response = g_memdup (self->response, self->response_length);
+ *response_length = self->response_length;
+ return TRUE;
+}
--- /dev/null
+/*
+ * Geoclue
+ * gc-web-service.h
+ *
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 GC_WEB_SERVICE_H
+#define GC_WEB_SERVICE_H
+
+#include <glib-object.h>
+#include <libxml/xpath.h> /* TODO: could move privates to .c-file and get rid of this*/
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_WEB_SERVICE (gc_web_service_get_type ())
+
+#define GC_WEB_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_WEB_SERVICE, GcWebService))
+#define GC_WEB_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GC_TYPE_WEB_SERVICE, GcWebServiceClass))
+#define GC_IS_WEB_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_WEB_SERVICE))
+#define GC_IS_WEB_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GC_TYPE_WEB_SERVICE))
+#define GC_WEB_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GC_TYPE_WEB_SERVICE, GcWebServiceClass))
+
+
+typedef struct _GcWebService {
+ GObject parent;
+
+ /* private */
+ gchar *base_url;
+ guchar *response;
+ gint response_length;
+ GList *namespaces;
+ xmlXPathContext *xpath_ctx;
+} GcWebService;
+
+typedef struct _GcWebServiceClass {
+ GObjectClass parent_class;
+} GcWebServiceClass;
+
+GType gc_web_service_get_type (void);
+
+void gc_web_service_set_base_url (GcWebService *self, gchar *url);
+gboolean gc_web_service_add_namespace (GcWebService *self, gchar *namespace, gchar *uri);
+
+gboolean gc_web_service_query (GcWebService *self, GError **error, ...);
+gboolean gc_web_service_get_string (GcWebService *self, gchar **value, gchar *xpath);
+gboolean gc_web_service_get_double (GcWebService *self, gdouble *value, gchar *xpath);
+
+gboolean gc_web_service_get_response (GcWebService *self, guchar **response, gint *response_length);
+
+G_END_DECLS
+
+#endif /* GC_WEB_SERVICE_H */
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-accuracy.c - Code for manipulating the GeoclueAccuracy structure
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-accuracy
+ * @short_description: Methods for manipulating #GeoclueAccuracy structure
+ *
+ * A #GeoclueAccuracy holds accuracy information: a
+ * #GeoclueAccuracyLevel and metric values for horizontal and vertical
+ * accuracy. The last two will only be defined if #GeoclueAccuracyLevel is
+ * %GEOCLUE_ACCURACY_LEVEL_DETAILED. These values should be set and queried
+ * using provided functions.
+ **/
+
+#include <glib-object.h>
+
+#include <geoclue/geoclue-accuracy.h>
+
+/**
+ * geoclue_accuracy_new:
+ * @level: A #GeoclueAccuracyLevel
+ * @horizontal_accuracy: Horizontal accuracy in meters
+ * @vertical_accuracy: Vertical accuracy in meters
+ *
+ * Creates a new #GeoclueAccuracy with given values. Use 0 for
+ * horizontal_accuracy and vertical_accuracy if @level is not
+ * %GEOCLUE_ACCURACY_LEVEL_DETAILED.
+ *
+ * Return value: New #GeoclueAccuracy.
+ */
+GeoclueAccuracy *
+geoclue_accuracy_new (GeoclueAccuracyLevel level,
+ double horizontal_accuracy,
+ double vertical_accuracy)
+{
+ GValue accuracy_struct = {0, };
+
+ g_value_init (&accuracy_struct, GEOCLUE_ACCURACY_TYPE);
+ g_value_take_boxed (&accuracy_struct,
+ dbus_g_type_specialized_construct
+ (GEOCLUE_ACCURACY_TYPE));
+
+ dbus_g_type_struct_set (&accuracy_struct,
+ 0, level,
+ 1, horizontal_accuracy,
+ 2, vertical_accuracy,
+ G_MAXUINT);
+
+ return (GeoclueAccuracy *) g_value_get_boxed (&accuracy_struct);
+}
+
+/**
+ * geoclue_accuracy_free:
+ * @accuracy: A #GeoclueAccuracy
+ *
+ * Frees the #GeoclueAccuracy.
+ */
+void
+geoclue_accuracy_free (GeoclueAccuracy *accuracy)
+{
+ if (!accuracy) {
+ return;
+ }
+
+ g_boxed_free (GEOCLUE_ACCURACY_TYPE, accuracy);
+}
+
+/**
+ * geoclue_accuracy_get_details:
+ * @accuracy: A #GeoclueAccuracy
+ * @level: Pointer to returned #GeoclueAccuracyLevel or %NULL
+ * @horizontal_accuracy: Pointer to returned horizontal accuracy in meters or %NULL
+ * @vertical_accuracy: Pointer to returned vertical accuracy in meters or %NULL
+ *
+ * @horizontal_accuracy and @vertical_accuracy will only be defined
+ * if @level is %GEOCLUE_ACCURACY_LEVEL_DETAILED.
+ */
+void
+geoclue_accuracy_get_details (GeoclueAccuracy *accuracy,
+ GeoclueAccuracyLevel *level,
+ double *horizontal_accuracy,
+ double *vertical_accuracy)
+{
+ GValueArray *vals;
+
+ vals = accuracy;
+ if (level != NULL) {
+ *level = g_value_get_int (g_value_array_get_nth (vals, 0));
+ }
+ if (horizontal_accuracy != NULL) {
+ *horizontal_accuracy = g_value_get_double (g_value_array_get_nth (vals, 1));
+ }
+ if (vertical_accuracy != NULL) {
+ *vertical_accuracy = g_value_get_double (g_value_array_get_nth (vals, 2));
+ }
+}
+
+/**
+ * geoclue_accuracy_set_details:
+ * @accuracy: A #GeoclueAccuracy
+ * @level: A #GeoclueAccuracyLevel
+ * @horizontal_accuracy: Horizontal accuracy in meters
+ * @vertical_accuracy: Vertical accuracy in meters
+ *
+ * Replaces @accuracy values with given ones.
+ */
+void
+geoclue_accuracy_set_details (GeoclueAccuracy *accuracy,
+ GeoclueAccuracyLevel level,
+ double horizontal_accuracy,
+ double vertical_accuracy)
+{
+ GValueArray *vals = accuracy;
+
+ g_value_set_int (g_value_array_get_nth (vals, 0), level);
+ g_value_set_double (g_value_array_get_nth (vals, 1),
+ horizontal_accuracy);
+ g_value_set_double (g_value_array_get_nth (vals, 2),
+ vertical_accuracy);
+}
+
+/**
+ * geoclue_accuracy_copy:
+ * @accuracy: A #GeoclueAccuracy
+ *
+ * Creates a copy of @accuracy.
+ *
+ * Return value: A newly allocated #GeoclueAccuracy
+ */
+GeoclueAccuracy *
+geoclue_accuracy_copy (GeoclueAccuracy *accuracy)
+{
+ GeoclueAccuracyLevel level;
+ double hor, ver;
+
+ geoclue_accuracy_get_details (accuracy, &level, &hor, &ver);
+ return geoclue_accuracy_new (level, hor, ver);
+}
+
+/**
+ * geoclue_accuracy_comapre:
+ * @accuracy1: First GeoclueAccuracy
+ * @accuracy1: Second GeoclueAccuracy
+ *
+ * Compares two accuracies.
+ *
+ * Return value: 0 if accuracies are same, negative value if accuracy1 is more accurate than accuracy2, or positive value if accuracy1 is less accurate than accuracy2
+ */
+int
+geoclue_accuracy_compare (GeoclueAccuracy *accuracy1, GeoclueAccuracy *accuracy2)
+{
+ GeoclueAccuracyLevel level1, level2;
+ double hor1, hor2;
+
+ geoclue_accuracy_get_details (accuracy1, &level1, &hor1, NULL);
+ geoclue_accuracy_get_details (accuracy2, &level2, &hor2, NULL);
+
+ if (level1 == GEOCLUE_ACCURACY_LEVEL_DETAILED &&
+ level2 == GEOCLUE_ACCURACY_LEVEL_DETAILED) {
+ if (hor1 > hor2) {
+ return 1;
+ } else if (hor1 < hor2) {
+ return -1;
+ }
+ return 0;
+ }
+ return level1 -level2;
+
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-accuracy.h - Functions for manipulating GeoclueAccuracy structs
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_ACCURACY_H
+#define _GEOCLUE_ACCURACY_H
+
+#include <glib.h>
+#include <geoclue/geoclue-types.h>
+
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_ACCURACY_TYPE (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_INVALID))
+
+typedef GValueArray GeoclueAccuracy;
+
+GeoclueAccuracy *geoclue_accuracy_new (GeoclueAccuracyLevel level,
+ double horizontal_accuracy,
+ double vertical_accuracy);
+void geoclue_accuracy_free (GeoclueAccuracy *accuracy);
+void geoclue_accuracy_get_details (GeoclueAccuracy *accuracy,
+ GeoclueAccuracyLevel *level,
+ double *horizontal_accuracy,
+ double *vertical_accuracy);
+void geoclue_accuracy_set_details (GeoclueAccuracy *accuracy,
+ GeoclueAccuracyLevel level,
+ double horizontal_accuracy,
+ double vertical_accuracy);
+
+GeoclueAccuracy *geoclue_accuracy_copy (GeoclueAccuracy *accuracy);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-address-details.c - Helper functions for GeoclueAddress
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <stdio.h>
+#include <glib.h>
+
+char *countries[][2] = {
+ {"AF", "Afghanistan"},
+ {"AX", "Aland Islands"},
+ {"AL", "Albania"},
+ {"DZ", "Algeria"},
+ {"AS", "American Samoa"},
+ {"AD", "Andorra"},
+ {"AO", "Angola"},
+ {"AI", "Anguilla"},
+ {"AQ", "Antarctica"},
+ {"AG", "Antigua and Barbuda"},
+ {"AR", "Argentina"},
+ {"AM", "Armenia"},
+ {"AW", "Aruba"},
+ {"AU", "Australia"},
+ {"AT", "Austria"},
+ {"AZ", "Azerbaijan"},
+ {"BS", "Bahamas"},
+ {"BH", "Bahrain"},
+ {"BD", "Bangladesh"},
+ {"BB", "Barbados"},
+ {"BY", "Belarus"},
+ {"BE", "Belgium"},
+ {"BZ", "Belize"},
+ {"BJ", "Benin"},
+ {"BM", "Bermuda"},
+ {"BT", "Bhutan"},
+ {"BO", "Bolivia"},
+ {"BA", "Bosnia and Herzegovina"},
+ {"BW", "Botswana"},
+ {"BV", "Bouvet Island"},
+ {"BR", "Brazil"},
+ {"IO", "British Indian Ocean Territory"},
+ {"BN", "Brunei Darussalam"},
+ {"BG", "Bulgaria"},
+ {"BF", "Burkina Faso"},
+ {"BI", "Burundi"},
+ {"KH", "Cambodia"},
+ {"CM", "Cameroon"},
+ {"CA", "Canada"},
+ {"CV", "Cape Verde"},
+ {"KY", "Cayman Islands"},
+ {"CF", "Central African Republic"},
+ {"TD", "Chad"},
+ {"CL", "Chile"},
+ {"CN", "China"},
+ {"CX", "Christmas Island"},
+ {"CC", "Cocos (Keeling) Islands"},
+ {"CO", "Colombia"},
+ {"KM", "Comoros"},
+ {"CG", "Congo"},
+ {"CD", "Democratic Republic of Congo"},
+ {"CK", "Cook Islands"},
+ {"CR", "Costa Rica"},
+ {"CI", "Cote d'Ivoire"},
+ {"HR", "Croatia"},
+ {"CU", "Cuba"},
+ {"CY", "Cyprus"},
+ {"CZ", "Czech"},
+ {"DK", "Denmark"},
+ {"DJ", "Djibouti"},
+ {"DM", "Dominica"},
+ {"DO", "Dominican"},
+ {"EC", "Ecuador"},
+ {"EG", "Egypt"},
+ {"SV", "El Salvador"},
+ {"GQ", "Equatorial Guinea"},
+ {"ER", "Eritrea"},
+ {"EE", "Estonia"},
+ {"ET", "Ethiopia"},
+ {"FK", "Falkland Islands"},
+ {"FO", "Faroe Islands"},
+ {"FJ", "Fiji"},
+ {"FI", "Finland"},
+ {"FR", "France"},
+ {"GF", "French Guiana"},
+ {"PF", "French Polynesia"},
+ {"TF", "French Southern Territories"},
+ {"GA", "Gabon"},
+ {"GM", "Gambia"},
+ {"GE", "Georgia"},
+ {"DE", "Germany"},
+ {"GH", "Ghana"},
+ {"GI", "Gibraltar"},
+ {"GR", "Greece"},
+ {"GL", "Greenland"},
+ {"GD", "Grenada"},
+ {"GP", "Guadeloupe"},
+ {"GU", "Guam"},
+ {"GT", "Guatemala"},
+ {"GG", "Guernsey"},
+ {"GN", "Guinea"},
+ {"GW", "Guinea-Bissau"},
+ {"GY", "Guyana"},
+ {"HT", "Haiti"},
+ {"HM", "Heard Island and McDonald Islands"},
+ {"VA", "Vatican"},
+ {"HN", "Honduras"},
+ {"HK", "Hong Kong"},
+ {"HU", "Hungary"},
+ {"IS", "Iceland"},
+ {"IN", "India"},
+ {"ID", "Indonesia"},
+ {"IR", "Iran"},
+ {"IQ", "Iraq"},
+ {"IE", "Ireland"},
+ {"IM", "Isle of Man"},
+ {"IL", "Israel"},
+ {"IT", "Italy"},
+ {"JM", "Jamaica"},
+ {"JP", "Japan"},
+ {"JE", "Jersey"},
+ {"JO", "Jordan"},
+ {"KZ", "Kazakhstan"},
+ {"KE", "Kenya"},
+ {"KI", "Kiribati"},
+ {"KP", "Democratic People's Republic of Korea"},
+ {"KR", "Korea"},
+ {"KW", "Kuwait"},
+ {"KG", "Kyrgyzstan"},
+ {"LA", "Lao"},
+ {"LV", "Latvia"},
+ {"LB", "Lebanon"},
+ {"LS", "Lesotho"},
+ {"LR", "Liberia"},
+ {"LY", "Libya"},
+ {"LI", "Liechtenstein"},
+ {"LT", "Lithuania"},
+ {"LU", "Luxembourg"},
+ {"MO", "Macao"},
+ {"MK", "Macedonia"},
+ {"MG", "Madagascar"},
+ {"MW", "Malawi"},
+ {"MY", "Malaysia"},
+ {"MV", "Maldives"},
+ {"ML", "Mali"},
+ {"MT", "Malta"},
+ {"MH", "Marshall Islands"},
+ {"MQ", "Martinique"},
+ {"MR", "Mauritania"},
+ {"MU", "Mauritius"},
+ {"YT", "Mayotte"},
+ {"MX", "Mexico"},
+ {"FM", "Micronesia"},
+ {"MD", "Moldova"},
+ {"MC", "Monaco"},
+ {"MN", "Mongolia"},
+ {"ME", "Montenegro"},
+ {"MS", "Montserrat"},
+ {"MA", "Morocco"},
+ {"MZ", "Mozambique"},
+ {"MM", "Myanmar"},
+ {"NA", "Namibia"},
+ {"NR", "Nauru"},
+ {"NP", "Nepal"},
+ {"NL", "Netherlands"},
+ {"AN", "Netherlands Antilles"},
+ {"NC", "New Caledonia"},
+ {"NZ", "New Zealand"},
+ {"NI", "Nicaragua"},
+ {"NE", "Niger"},
+ {"NG", "Nigeria"},
+ {"NU", "Niue"},
+ {"NF", "Norfolk Island"},
+ {"MP", "Northern Mariana Islands"},
+ {"NO", "Norway"},
+ {"OM", "Oman"},
+ {"PK", "Pakistan"},
+ {"PW", "Palau"},
+ {"PS", "Palestinian Territory"},
+ {"PA", "Panama"},
+ {"PG", "Papua New Guinea"},
+ {"PY", "Paraguay"},
+ {"PE", "Peru"},
+ {"PH", "Philippines"},
+ {"PN", "Pitcairn"},
+ {"PL", "Poland"},
+ {"PT", "Portugal"},
+ {"PR", "Puerto Rico"},
+ {"QA", "Qatar"},
+ {"RE", "Reunion"},
+ {"RO", "Romania"},
+ {"RU", "Russia"},
+ {"RW", "Rwanda"},
+ {"BL", "Saint Barthélemy"},
+ {"SH", "Saint Helena"},
+ {"KN", "Saint Kitts and Nevis"},
+ {"LC", "Saint Lucia"},
+ {"MF", "Saint Martin"},
+ {"PM", "Saint Pierre and Miquelon"},
+ {"VC", "Saint Vincent and the Grenadines"},
+ {"WS", "Samoa"},
+ {"SM", "San Marino"},
+ {"ST", "Sao Tome and Principe"},
+ {"SA", "Saudi Arabia"},
+ {"SN", "Senegal"},
+ {"RS", "Serbia"},
+ {"SC", "Seychelles"},
+ {"SL", "Sierra Leone"},
+ {"SG", "Singapore"},
+ {"SK", "Slovakia"},
+ {"SI", "Slovenia"},
+ {"SB", "Solomon Islands"},
+ {"SO", "Somalia"},
+ {"ZA", "South Africa"},
+ {"GS", "South Georgia and the South Sandwich Islands"},
+ {"ES", "Spain"},
+ {"LK", "Sri Lanka"},
+ {"SD", "Sudan"},
+ {"SR", "Suriname"},
+ {"SJ", "Svalbard and Jan Mayen"},
+ {"SZ", "Swaziland"},
+ {"SE", "Sweden"},
+ {"CH", "Switzerland"},
+ {"SY", "Syria"},
+ {"TW", "Taiwan"},
+ {"TJ", "Tajikistan"},
+ {"TZ", "Tanzania"},
+ {"TH", "Thailand"},
+ {"TL", "Timor-Leste"},
+ {"TG", "Togo"},
+ {"TK", "Tokelau"},
+ {"TO", "Tonga"},
+ {"TT", "Trinidad and Tobago"},
+ {"TN", "Tunisia"},
+ {"TR", "Turkey"},
+ {"TM", "Turkmenistan"},
+ {"TC", "Turks and Caicos Islands"},
+ {"TV", "Tuvalu"},
+ {"UG", "Uganda"},
+ {"UA", "Ukraine"},
+ {"AE", "United Arab Emirates"},
+ {"GB", "United Kingdom"},
+ {"US", "United States"},
+ {"UM", "United States"}, /* US Minor Outlying Islands */
+ {"UY", "Uruguay"},
+ {"UZ", "Uzbekistan"},
+ {"VU", "Vanuatu"},
+ {"VE", "Venezuela"},
+ {"VN", "Viet Nam"},
+ {"VG", "Virgin Islands"}, /* British */
+ {"VI", "Virgin Islands"}, /* US */
+ {"WF", "Wallis and Futuna"},
+ {"EH", "Western Sahara"},
+ {"YE", "Yemen"},
+ {"ZM", "Zambia"},
+ {"ZW", "Zimbabwe"},
+ {NULL, NULL},
+};
+
+
+/**
+ * SECTION:geoclue-address-details
+ * @short_description: Convenience functions for handling Geoclue address
+ * #GHashTables
+ */
+#include <geoclue/geoclue-types.h>
+#include "geoclue-address-details.h"
+
+/**
+ * geoclue_address_details_new:
+ *
+ * Creates a new #GHashTable suitable for Geoclue Address details.
+ * Both keys and values inserted to this #GHashTable will be freed
+ * on g_hash_table_destroy().
+ *
+ * Return value: New #GHashTable
+ */
+GHashTable *
+geoclue_address_details_new ()
+{
+ return g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+}
+
+
+/**
+ * geoclue_address_details_insert:
+ * @address: #GHashTable to insert value in
+ * @key: the key to use, one of GEOCLUE_ADDRESS_KEY_*
+ * @value: value to insert into address
+ *
+ * Adds a address field into @address. Will take copies
+ * of the strings.
+ */
+void
+geoclue_address_details_insert (GHashTable *address,
+ const char *key, const char *value)
+{
+ g_hash_table_insert (address, g_strdup (key), g_strdup (value));
+}
+
+static void
+copy_address_key_and_value (char *key, char *value, GHashTable *target)
+{
+ geoclue_address_details_insert (target, key, value);
+}
+
+
+/**
+ * geoclue_address_details_copy:
+ * @source: #GHashTable to copy
+ *
+ * Deep-copies a #GHashTable.
+ *
+ * Return value: New, deep copied #GHashTable
+ */
+GHashTable *
+geoclue_address_details_copy (GHashTable *source)
+{
+ GHashTable *target;
+
+ g_assert (source != NULL);
+
+ target = geoclue_address_details_new ();
+ g_hash_table_foreach (source,
+ (GHFunc)copy_address_key_and_value,
+ target);
+ return target;
+}
+
+
+/**
+ * geoclue_address_details_set_country_from_code:
+ * @address: #GHashTable with address data
+ *
+ * Uses the "ISO 3166-1 alpha-2" list to figure out the country name matching
+ * the country code in @details, and adds the country name to details.
+ *
+ * Using this function in providers is useful even when the data source includes
+ * country name: this way names are standardized.
+ */
+void
+geoclue_address_details_set_country_from_code (GHashTable *address)
+{
+ static GHashTable *country_table = NULL;
+ const char *code;
+ const char *country = NULL;
+
+ if (!country_table) {
+ int i;
+
+ country_table = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 0; countries[i][0]; i++) {
+ g_hash_table_insert (country_table, countries[i][0], countries[i][1]);
+ }
+ }
+
+ code = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ if (code) {
+ char *upper = g_ascii_strup (code, -1);
+ country = g_hash_table_lookup (country_table, upper);
+ g_free (upper);
+ }
+
+ if (country) {
+ geoclue_address_details_insert (
+ address, GEOCLUE_ADDRESS_KEY_COUNTRY, country);
+ } else {
+ g_hash_table_remove (address, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ }
+}
+
+/**
+ * geoclue_address_details_get_accuracy_level:
+ * @address: A #GHashTable with address hash values
+ *
+ * Returns a #GeoclueAccuracy that best describes the accuracy of @address
+ *
+ * Return value: #GeoclueAccuracy
+ */
+GeoclueAccuracyLevel
+geoclue_address_details_get_accuracy_level (GHashTable *address)
+{
+ if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_STREET)) {
+ return GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY)) {
+ return GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_REGION)) {
+ return GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRY) ||
+ g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ return GEOCLUE_ACCURACY_LEVEL_NONE;
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-address-details.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_ADDRESS_DETAILS_H
+#define _GEOCLUE_ADDRESS_DETAILS_H
+
+#include <glib.h>
+
+GHashTable *geoclue_address_details_new ();
+
+GHashTable *geoclue_address_details_copy (GHashTable *source);
+
+void geoclue_address_details_insert (GHashTable *address, const char *key, const char *value);
+
+void geoclue_address_details_set_country_from_code (GHashTable *address);
+
+GeoclueAccuracyLevel geoclue_address_details_get_accuracy_level (GHashTable *address);
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-address.c - Client API for accessing GcIfaceAddress
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-address
+ * @short_description: Geoclue address client API
+ *
+ * #GeoclueAddress contains Address-related methods and signals.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeoclueAddress is created with geoclue_address_new() or
+ * geoclue_master_client_create_address(), the
+ * geoclue_address_get_address() and geoclue_address_get_address_async() methods
+ * and the address-changed signal can be used to obtain the current address.
+ *
+ * Address #GHashTable keys are defined in
+ * <ulink url="geoclue-types.html">geoclue-types.h</ulink>. See also
+ * convenience functions in
+ * <ulink url="geoclue-address-details.html">geoclue-address-details.h</ulink>.
+ */
+
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-address-bindings.h"
+
+typedef struct _GeoclueAddressPrivate {
+ int dummy;
+} GeoclueAddressPrivate;
+
+enum {
+ ADDRESS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_ADDRESS, GeoclueAddressPrivate))
+
+G_DEFINE_TYPE (GeoclueAddress, geoclue_address, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_address_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_address_parent_class)->dispose (object);
+}
+
+static void
+address_changed (DBusGProxy *proxy,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GeoclueAddress *address)
+{
+ g_signal_emit (address, signals[ADDRESS_CHANGED], 0,
+ timestamp, details, accuracy);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_address_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "AddressChanged",
+ G_TYPE_INT,
+ DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+ GEOCLUE_ACCURACY_TYPE,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "AddressChanged",
+ G_CALLBACK (address_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_address_class_init (GeoclueAddressClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeoclueAddressPrivate));
+
+ /**
+ * GeoclueAddress::address-changed:
+ * @address: the #GeoclueAddress object emitting the signal
+ * @timestamp: Time of address measurement (Unix timestamp)
+ * @details: Address details as #GHashTable.
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ *
+ * The address-changed signal is emitted each time the address changes.
+ * See <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the possible
+ * GEOCLUE_ADDRESS_KEY_* keys used in @details.
+ *
+ * Note that not all providers support signals.
+ */
+ signals[ADDRESS_CHANGED] = g_signal_new ("address-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueAddressClass, address_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+}
+
+static void
+geoclue_address_init (GeoclueAddress *address)
+{
+}
+
+/**
+ * geoclue_address_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeoclueAddress with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeoclueAddress
+ */
+GeoclueAddress *
+geoclue_address_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_ADDRESS,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_ADDRESS_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_address_get_address:
+ * @address: A #GeoclueAddress object
+ * @timestamp: Pointer to returned time of address measurement (Unix timestamp) or %NULL
+ * @details: Pointer to returned #GHashTable with address details or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains the current address. @timestamp will contain the time of
+ * the actual address measurement. @accuracy is the estimated of the
+ * accuracy of the current address information (see #GeoclueAccuracy
+ * for more details). @details is a hashtable with the address data,
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: %TRUE if there is no @error
+ */
+gboolean
+geoclue_address_get_address (GeoclueAddress *address,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (address);
+
+ if (!org_freedesktop_Geoclue_Address_get_address (provider->proxy,
+ timestamp, details,
+ accuracy, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+typedef struct _GeoclueAddressAsyncData {
+ GeoclueAddress *address;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueAddressAsyncData;
+
+static void
+get_address_async_callback (DBusGProxy *proxy,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ GeoclueAddressAsyncData *data)
+{
+ (*(GeoclueAddressCallback)data->callback) (data->address,
+ timestamp,
+ details,
+ accuracy,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueAddressCallback:
+ * @address: the #GeoclueAddress object emitting the signal
+ * @timestamp: Time of address measurement (Unix timestamp)
+ * @details: Address details as #GHashTable.
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_position_get_position_async()
+ *
+ * Callback function for geoclue_address_get_address_async().
+ */
+
+/**
+ * geoclue_address_get_address_async:
+ * @address: A #GeoclueAddress object
+ * @callback: A #GeoclueAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when current address
+ * is available or when D-Bus timeouts.
+ */
+void
+geoclue_address_get_address_async (GeoclueAddress *address,
+ GeoclueAddressCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (address);
+ GeoclueAddressAsyncData *data;
+
+ data = g_new (GeoclueAddressAsyncData, 1);
+ data->address = address;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Address_get_address_async
+ (provider->proxy,
+ (org_freedesktop_Geoclue_Address_get_address_reply) get_address_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-address.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_ADDRESS_H
+#define _GEOCLUE_ADDRESS_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-address-details.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_ADDRESS (geoclue_address_get_type ())
+#define GEOCLUE_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_ADDRESS, GeoclueAddress))
+#define GEOCLUE_IS_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_ADDRESS))
+
+#define GEOCLUE_ADDRESS_INTERFACE_NAME "org.freedesktop.Geoclue.Address"
+
+typedef struct _GeoclueAddress {
+ GeoclueProvider provider;
+} GeoclueAddress;
+
+typedef struct _GeoclueAddressClass {
+ GeoclueProviderClass provider_class;
+
+ void (* address_changed) (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy);
+} GeoclueAddressClass;
+
+GType geoclue_address_get_type (void);
+
+GeoclueAddress *geoclue_address_new (const char *service,
+ const char *path);
+
+gboolean geoclue_address_get_address (GeoclueAddress *address,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+typedef void (*GeoclueAddressCallback) (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_address_get_address_async (GeoclueAddress *address,
+ GeoclueAddressCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-error.c - Error handling
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <geoclue/geoclue-error.h>
+
+GQuark
+geoclue_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (quark == 0) {
+ quark = g_quark_from_static_string ("geoclue-error-quark");
+ }
+
+ return quark;
+}
+
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-error.h - Error handling
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_ERROR_H
+#define _GEOCLUE_ERROR_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-enum-types.h>
+
+/**
+ * GeoclueError:
+ * @GEOCLUE_ERROR_NOT_IMPLEMENTED: Method is not implemented
+ * @GEOCLUE_ERROR_NOT_AVAILABLE: Needed information is not currently
+ * available (e.g. web service did not respond)
+ * @GEOCLUE_ERROR_FAILED: Generic fatal error
+ *
+ * Error values for providers.
+ **/
+typedef enum {
+ GEOCLUE_ERROR_NOT_IMPLEMENTED,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ GEOCLUE_ERROR_FAILED,
+} GeoclueError;
+
+#define GEOCLUE_ERROR_DBUS_INTERFACE "org.freedesktop.Geoclue.Error"
+#define GEOCLUE_ERROR (geoclue_error_quark ())
+
+GQuark geoclue_error_quark (void);
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-geocode.c - Client API for accessing GcIfaceGeocode
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-geocode
+ * @short_description: Geoclue geocode client API
+ *
+ * #GeoclueGeocode contains geocoding methods.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeoclueGeocode is created with geoclue_geocode_new(), the
+ * geoclue_geocode_address_to_position(),
+ * geoclue_geocode_freeform_address_to_position() methods and their
+ * asynchronous counterparts can be used to obtain the position (coordinates)
+ * of the given address.
+ *
+ * Address #GHashTable keys are defined in
+ * <ulink url="geoclue-types.html">geoclue-types.h</ulink>. See also
+ * convenience functions in
+ * <ulink url="geoclue-address-details.html">geoclue-address-details.h</ulink>.
+ */
+
+#include <geoclue/geoclue-geocode.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-geocode-bindings.h"
+
+typedef struct _GeoclueGeocodePrivate {
+ int dummy;
+} GeoclueGeocodePrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_GEOCODE, GeoclueGeocodePrivate))
+
+G_DEFINE_TYPE (GeoclueGeocode, geoclue_geocode, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_geocode_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_geocode_parent_class)->dispose (object);
+}
+
+static void
+geoclue_geocode_class_init (GeoclueGeocodeClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GeoclueGeocodePrivate));
+}
+
+static void
+geoclue_geocode_init (GeoclueGeocode *geocode)
+{
+}
+
+/**
+ * geoclue_geocode_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeoclueGeocode with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeoclueGeocode
+ */
+GeoclueGeocode *
+geoclue_geocode_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_GEOCODE,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_GEOCODE_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_geocode_address_to_position:
+ * @geocode: A #GeoclueGeocode object
+ * @details: Hashtable with address data
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Geocodes given address to coordinates (@latitude, @longitude, @altitude).
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys usable in @details. @accuracy is a rough estimate of
+ * the accuracy of the returned position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionFields bitfield representing the
+ * validity of the returned coordinates.
+ */
+GeocluePositionFields
+geoclue_geocode_address_to_position (GeoclueGeocode *geocode,
+ GHashTable *details,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (geocode);
+ int fields;
+ double la, lo, al;
+ GeoclueAccuracy *acc;
+
+ if (!org_freedesktop_Geoclue_Geocode_address_to_position (provider->proxy,
+ details, &fields,
+ &la, &lo, &al,
+ &acc, error)){
+ return GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+typedef struct _GeoclueGeocodeAsyncData {
+ GeoclueGeocode *geocode;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueGeocodeAsyncData;
+
+static void
+address_to_position_callback (DBusGProxy *proxy,
+ GeocluePositionFields fields,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ GeoclueGeocodeAsyncData *data)
+{
+ (*(GeoclueGeocodeCallback)data->callback) (data->geocode,
+ fields,
+ latitude,
+ longitude,
+ altitude,
+ accuracy,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueGeocodeCallback:
+ * @geocode: A #GeoclueGeocode object
+ * @fields: A #GeocluePositionFields bitfield representing the validity of the position values
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror or %NULL
+ * @userdata: User data pointer
+ *
+ * Callback function for the asynchronous methods.
+ */
+
+/**
+ * geoclue_geocode_address_to_position_async:
+ * @geocode: A #Geocluegeocode object
+ * @details: A #GHashTable with address data
+ * @callback: A #GeoclueAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when the geocoded
+ * position data is available or when D-Bus timeouts.
+ *
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys usable in @details.
+ *
+ */
+void
+geoclue_geocode_address_to_position_async (GeoclueGeocode *geocode,
+ GHashTable *details,
+ GeoclueGeocodeCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (geocode);
+ GeoclueGeocodeAsyncData *data;
+
+ data = g_new (GeoclueGeocodeAsyncData, 1);
+ data->geocode = geocode;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Geocode_address_to_position_async
+ (provider->proxy,
+ details,
+ (org_freedesktop_Geoclue_Geocode_address_to_position_reply)address_to_position_callback,
+ data);
+}
+
+/**
+ * geoclue_geocode_freeform_address_to_position:
+ * @geocode: A #GeoclueGeocode object
+ * @address: freeform address
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Geocodes given address to coordinates (@latitude, @longitude, @altitude).
+ * @accuracy is a rough estimate of the accuracy of the returned position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionFields bitfield representing the
+ * validity of the returned coordinates.
+ */
+GeocluePositionFields
+geoclue_geocode_freeform_address_to_position (GeoclueGeocode *geocode,
+ const char *address,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (geocode);
+ int fields;
+ double la, lo, al;
+ GeoclueAccuracy *acc;
+
+ if (!org_freedesktop_Geoclue_Geocode_freeform_address_to_position
+ (provider->proxy,
+ address, &fields,
+ &la, &lo, &al,
+ &acc, error)) {
+ return GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+/**
+ * geoclue_geocode_freeform_address_to_position_async:
+ * @geocode: A #Geocluegeocode object
+ * @address: freeform address
+ * @callback: A #GeoclueAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when the geocoded
+ * position data is available or when D-Bus timeouts.
+ */
+void
+geoclue_geocode_freeform_address_to_position_async (GeoclueGeocode *geocode,
+ const char *address,
+ GeoclueGeocodeCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (geocode);
+ GeoclueGeocodeAsyncData *data;
+
+ data = g_new (GeoclueGeocodeAsyncData, 1);
+ data->geocode = geocode;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Geocode_freeform_address_to_position_async
+ (provider->proxy,
+ address,
+ (org_freedesktop_Geoclue_Geocode_address_to_position_reply)address_to_position_callback,
+ data);
+}
+
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-geocode.h -
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_GEOCODE_H
+#define _GEOCLUE_GEOCODE_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-address-details.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_GEOCODE (geoclue_geocode_get_type ())
+#define GEOCLUE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GEOCODE, GeoclueGeocode))
+#define GEOCLUE_IS_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GEOCODE))
+
+#define GEOCLUE_GEOCODE_INTERFACE_NAME "org.freedesktop.Geoclue.Geocode"
+
+typedef struct _GeoclueGeocode {
+ GeoclueProvider provider;
+} GeoclueGeocode;
+
+typedef struct _GeoclueGeocodeClass {
+ GeoclueProviderClass provider_class;
+} GeoclueGeocodeClass;
+
+GType geoclue_geocode_get_type (void);
+
+GeoclueGeocode *geoclue_geocode_new (const char *service,
+ const char *path);
+
+GeocluePositionFields
+geoclue_geocode_address_to_position (GeoclueGeocode *geocode,
+ GHashTable *details,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+typedef void (*GeoclueGeocodeCallback) (GeoclueGeocode *geocode,
+ GeocluePositionFields fields,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_geocode_address_to_position_async (GeoclueGeocode *geocode,
+ GHashTable *details,
+ GeoclueGeocodeCallback callback,
+ gpointer userdata);
+
+GeocluePositionFields
+geoclue_geocode_freeform_address_to_position (GeoclueGeocode *geocode,
+ const char *address,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+void
+geoclue_geocode_freeform_address_to_position_async (GeoclueGeocode *geocode,
+ const char *address,
+ GeoclueGeocodeCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-landmark.h
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_LANDMARK_H
+#define _GEOCLUE_LANDMARK_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_LANDMARK (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID))
+
+#define GEOCLUE_LANDMARK_ARRAY (dbus_g_type_get_collection ("GPtrArray", GEOCLUE_LANDMARK))
+
+typedef struct _GeoclueLandmark {
+ gint id;
+ gint rank;
+ gdouble lat;
+ gdouble lon;
+ gdouble boundary_left;
+ gdouble boundary_top;
+ gdouble boundary_right;
+ gdouble boundary_bottom;
+ gchar *name;
+ gchar *icon;
+ gchar *house;
+ gchar *road;
+ gchar *village;
+ gchar *suburb;
+ gchar *postcode;
+ gchar *city;
+ gchar *county;
+ gchar *country;
+ gchar *country_code;
+} GeoclueLandmark;
+
+G_END_DECLS
+
+#endif
--- /dev/null
+VOID:INT,INT
+VOID:INT,INT,DOUBLE,DOUBLE,DOUBLE,BOXED
+VOID:INT,INT,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,BOXED
+VOID:INT,INT,DOUBLE,DOUBLE,DOUBLE
+VOID:INT,DOUBLE,DOUBLE
+VOID:INT,POINTER,BOXED
+VOID:INT,BOXED,BOXED
+VOID:STRING,STRING,STRING,STRING
+VOID:INT,STRING
+VOID:INT,INT,INT,POINTER,POINTER
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-master-client.c - Client API for accessing the Geoclue Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-master-client
+ * @short_description: Geoclue MasterClient API
+ *
+ * #GeoclueMasterClient is part of the Geoclue public C client API. It uses
+ * D-Bus to communicate with the actual Master service.
+ *
+ * #GeoclueMasterClient is used to control the client specific behaviour
+ * of Geoclue Master. Chapter "Master provider: simple example in C" contains a
+ * more complete example, but here are the main parts:
+ *
+ * <informalexample>
+ * <programlisting>
+ * GeoclueMaster *master;
+ * GeoclueMasterClient *client;
+ * GeoclueAddress *address;
+ *
+ * ...
+ *
+ * master = geoclue_master_get_default ();
+ * client = geoclue_master_create_client (master, NULL, NULL);
+ *
+ * if (!geoclue_master_client_set_requirements (client,
+ * GEOCLUE_ACCURACY_LEVEL_NONE,
+ * 0, FALSE,
+ * GEOCLUE_RESOURCE_NETWORK,
+ * &error)) {
+ * / * handle error * /
+ * }
+ *
+ * address = geoclue_master_client_create_address (client, error);
+ * if (!address) {
+ * / * handle error * /
+ * }
+ *
+ * / * Now we can use address just like we'd use a normal address provider,
+ * but GeoclueMasterClient makes sure that underneath the provider
+ * that best matches our requirements is used * /
+ * </programlisting>
+ * </informalexample>
+ */
+
+#include <config.h>
+
+#include <glib-object.h>
+
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-master-client.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+#include "gc-iface-master-client-bindings.h"
+
+typedef struct _GeoclueMasterClientPrivate {
+ DBusGProxy *proxy;
+ char *object_path;
+} GeoclueMasterClientPrivate;
+
+enum {
+ PROP_0,
+ PROP_PATH
+};
+
+enum {
+ ADDRESS_PROVIDER_CHANGED,
+ POSITION_PROVIDER_CHANGED,
+ INVALIDATED,
+ LAST_SIGNAL
+};
+
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_MASTER_CLIENT, GeoclueMasterClientPrivate))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueMasterClient, geoclue_master_client, G_TYPE_OBJECT, geoclue_types_init (););
+
+
+typedef struct _GeoclueMasterClientAsyncData {
+ GeoclueMasterClient *client;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueMasterClientAsyncData;
+
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_master_client_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (geoclue_master_client_parent_class)->dispose (object);
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_PATH:
+ priv->object_path = g_value_dup_string (value);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+}
+
+static void
+address_provider_changed (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueMasterClient *client)
+{
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ name, description, service, path);
+}
+
+static void
+position_provider_changed (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueMasterClient *client)
+{
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ name, description, service, path);
+}
+
+static void
+proxy_destroyed (DBusGProxy *proxy,
+ gpointer user_data)
+{
+ g_signal_emit (user_data, signals[INVALIDATED], 0);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GeoclueMasterClient *client;
+ GeoclueMasterClientPrivate *priv;
+ DBusGConnection *connection;
+ GObject *object;
+ GError *error = NULL;
+
+ object = G_OBJECT_CLASS (geoclue_master_client_parent_class)->constructor (type, n_props, props);
+ client = GEOCLUE_MASTER_CLIENT (object);
+ priv = GET_PRIVATE (client);
+
+ connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!connection) {
+ g_warning ("Failed to open connection to bus: %s",
+ error->message);
+ g_error_free (error);
+
+ priv->proxy = NULL;
+ return object;
+ }
+
+ priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
+ GEOCLUE_MASTER_DBUS_SERVICE,
+ priv->object_path,
+ GEOCLUE_MASTER_CLIENT_DBUS_INTERFACE,
+ &error);
+ if (!priv->proxy) {
+ g_warning ("Failed to create proxy to %s: %s",
+ priv->object_path,
+ error->message);
+ g_error_free (error);
+
+ return object;
+ }
+
+ g_signal_connect (priv->proxy, "destroy",
+ G_CALLBACK (proxy_destroyed), object);
+
+ dbus_g_proxy_add_signal (priv->proxy, "AddressProviderChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "AddressProviderChanged",
+ G_CALLBACK (address_provider_changed),
+ object, NULL);
+
+ dbus_g_proxy_add_signal (priv->proxy, "PositionProviderChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "PositionProviderChanged",
+ G_CALLBACK (position_provider_changed),
+ object, NULL);
+ return object;
+}
+
+static void
+geoclue_master_client_class_init (GeoclueMasterClientClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+ o_class->set_property = set_property;
+ o_class->get_property = get_property;
+
+ g_type_class_add_private (klass, sizeof (GeoclueMasterClientPrivate));
+
+ g_object_class_install_property
+ (o_class, PROP_PATH,
+ g_param_spec_string ("object-path",
+ "Object path",
+ "The DBus path to the object",
+ "",
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+
+ /**
+ * GeoclueMasterClient::address-provider-changed:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ * @name: name of the new provider (e.g. "Hostip") or %NULL if there is no provider
+ * @description: a short description of the new provider or %NULL if there is no provider
+ * @service: D-Bus service name of the new provider or %NULL if there is no provider
+ * @path: D-Bus object path name of the new provider or %NULL if there is no provider
+ *
+ * The address-provider-changed signal is emitted each time the used address provider
+ * changes.
+ **/
+ signals[ADDRESS_PROVIDER_CHANGED] =
+ g_signal_new ("address-provider-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, address_provider_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /**
+ * GeoclueMasterClient::position-provider-changed:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ * @name: name of the new provider (e.g. "Hostip") or %NULL if there is no provider
+ * @description: a short description of the new provider or %NULL if there is no provider
+ * @service: D-Bus service name of the new provider or %NULL if there is no provider
+ * @path: D-Bus object path name of the new provider or %NULL if there is no provider
+ *
+ * The position-provider-changed signal is emitted each time the used position provider
+ * changes.
+ **/
+ signals[POSITION_PROVIDER_CHANGED] =
+ g_signal_new ("position-provider-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, position_provider_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /**
+ * GeoclueMasterClient::invalidated:
+ * @client: the #GeoclueMasterClient object emitting the signal
+ *
+ * The client has been invalidated. This is emitted when Geoclue Dbus
+ * services disappear unexpectedly (possibly due to a crash). Upon
+ * receiving this signal, you should unref your client and create a new
+ * one.
+ **/
+ signals[INVALIDATED] =
+ g_signal_new ("invalidated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueMasterClientClass, invalidated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+geoclue_master_client_init (GeoclueMasterClient *client)
+{
+}
+
+/**
+ * geoclue_master_client_set_requirements:
+ * @client: A #GeoclueMasterClient
+ * @min_accuracy: The required minimum accuracy as a #GeoclueAccuracyLevel.
+ * @min_time: The minimum time between update signals (currently not implemented)
+ * @require_updates: Whether the updates (signals) are required. Only applies to interfaces with signals
+ * @allowed_resources: The resources that are allowed to be used as a #GeoclueResourceFlags
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Sets the criteria that should be used when selecting the used provider
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_master_client_set_requirements (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_set_requirements
+ (priv->proxy, min_accuracy, min_time, require_updates, allowed_resources, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+set_requirements_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ (*(GeoclueSetRequirementsCallback)data->callback) (data->client,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueSetRequirementsCallback:
+ * @client: A #GeoclueMasterClient object
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_set_requirements_async()
+ *
+ * Callback function for geoclue_master_client_set_requirements_async().
+ */
+
+/**
+ * geoclue_master_client_set_requirements_async:
+ * @client: A #GeoclueMasterClient
+ * @min_accuracy: The required minimum accuracy as a #GeoclueAccuracyLevel.
+ * @min_time: The minimum time between update signals (currently not implemented)
+ * @require_updates: Whether the updates (signals) are required. Only applies to interfaces with signals
+ * @allowed_resources: The resources that are allowed to be used as a #GeoclueResourceFlags
+ * @callback: #GeoclueSetRequirementsCallback function to call when requirements have been set
+ * @userdata: User data pointer
+ *
+ * Asynchronous version of geoclue_master_client_set_requirements().
+ */
+void
+geoclue_master_client_set_requirements_async (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GeoclueSetRequirementsCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_set_requirements_async
+ (priv->proxy,
+ min_accuracy,
+ min_time,
+ require_updates,
+ allowed_resources,
+ (org_freedesktop_Geoclue_MasterClient_set_requirements_reply)set_requirements_callback,
+ data);
+}
+
+/**
+ * geoclue_master_client_create_address:
+ * @client: A #GeoclueMasterClient
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Starts the GeoclueMasterClient address provider and returns
+ * a #GeoclueAddress that uses the same D-Bus object as the #GeoclueMasterClient.
+ *
+ * Return value: New #GeoclueAddress or %NULL on error
+ */
+GeoclueAddress *
+geoclue_master_client_create_address (GeoclueMasterClient *client,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+
+ if (!org_freedesktop_Geoclue_MasterClient_address_start (priv->proxy, error)) {
+ return NULL;
+ }
+
+ return geoclue_address_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+}
+
+static void
+address_start_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (data->client);
+ GeoclueAddress *address = NULL;
+
+ if (!error) {
+ address = geoclue_address_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+ }
+
+ (*(CreateAddressCallback)data->callback) (data->client,
+ address,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * CreateAddressCallback:
+ * @client: A #GeoclueMasterClient object
+ * @address: returned #GeoclueAddress
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_create_address_async()
+ *
+ * Callback function for geoclue_master_client_create_address_async().
+ */
+
+/**
+ * geoclue_master_client_create_address_async:
+ * @client: A #GeoclueMasterClient object
+ * @callback: A #CreateAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when it has started the address provider
+ * and a #GeoclueAddress is available.
+ */
+void
+geoclue_master_client_create_address_async (GeoclueMasterClient *client,
+ CreateAddressCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_address_start_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_address_start_reply)address_start_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_create_position:
+ * @client: A #GeoclueMasterClient
+ * @error: A pointer to returned #GError or %NULL.
+ *
+ * Starts the GeoclueMasterClient position provider and returns
+ * a #GeocluePosition that uses the same D-Bus object as the #GeoclueMasterClient.
+ *
+ * Return value: New #GeocluePosition or %NULL on error
+ */
+GeocluePosition *
+geoclue_master_client_create_position (GeoclueMasterClient *client,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+
+ if (!org_freedesktop_Geoclue_MasterClient_position_start (priv->proxy, error)) {
+ return NULL;
+ }
+ return geoclue_position_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+}
+
+
+static void
+position_start_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (data->client);
+ GeocluePosition *position = NULL;
+
+ if (!error) {
+ position = geoclue_position_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path);
+ }
+
+ (*(CreatePositionCallback)data->callback) (data->client,
+ position,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * CreatePositionCallback:
+ * @client: A #GeoclueMasterClient object
+ * @position: returned #GeocluePosition
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_master_client_create_position_async()
+ *
+ * Callback function for geoclue_master_client_create_position_async().
+ */
+
+/**
+ * geoclue_master_client_create_position_async:
+ * @client: A #GeoclueMasterClient object
+ * @callback: A #CreatePositionCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when it has started the position provider
+ * and a #GeocluePosition is available.
+ */
+void
+geoclue_master_client_create_position_async (GeoclueMasterClient *client,
+ CreatePositionCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_position_start_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_position_start_reply)position_start_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_get_address_provider:
+ * @client: A #GeoclueMasterClient
+ * @name: Pointer to returned provider name or %NULL
+ * @description: Pointer to returned provider description or %NULL
+ * @service: Pointer to returned D-Bus service name or %NULL
+ * @path: Pointer to returned D-Bus object path or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Gets name and other information for the currently used address provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean geoclue_master_client_get_address_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_get_address_provider
+ (priv->proxy, name, description, service, path, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+get_provider_callback (DBusGProxy *proxy,
+ char * name,
+ char * description,
+ char * service,
+ char * path,
+ GError *error,
+ GeoclueMasterClientAsyncData *data)
+{
+
+ (*(GeoclueGetProviderCallback)data->callback) (data->client,
+ name,
+ description,
+ service,
+ path,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * geoclue_master_client_get_address_provider_async:
+ * @client: A #GeoclueMasterClient
+ * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Gets name and other information for the currently used address provider asynchronously.
+ */
+void
+geoclue_master_client_get_address_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_get_address_provider_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_get_address_provider_reply)get_provider_callback,
+ data);
+}
+
+
+/**
+ * geoclue_master_client_get_position_provider:
+ * @client: A #GeoclueMasterClient
+ * @name: Pointer to returned provider name or %NULL
+ * @description: Pointer to returned provider description or %NULL
+ * @service: Pointer to returned D-Bus service name or %NULL
+ * @path: Pointer to returned D-Bus object path or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Gets name and other information for the currently used position provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean geoclue_master_client_get_position_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GeoclueMasterClientPrivate *priv;
+
+ priv = GET_PRIVATE (client);
+ if (!org_freedesktop_Geoclue_MasterClient_get_position_provider
+ (priv->proxy, name, description, service, path, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * geoclue_master_client_get_position_provider_async:
+ * @client: A #GeoclueMasterClient
+ * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Gets name and other information for the currently used position provider asynchronously.
+ */
+void
+geoclue_master_client_get_position_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeoclueMasterClientAsyncData *data;
+
+ data = g_new (GeoclueMasterClientAsyncData, 1);
+ data->client = client;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_MasterClient_get_position_provider_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_MasterClient_get_position_provider_reply)get_provider_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-master-client.c - Client API for accessing the Geoclue Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_MASTER_CLIENT_H
+#define _GEOCLUE_MASTER_CLIENT_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-address.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_MASTER_CLIENT_DBUS_INTERFACE "org.freedesktop.Geoclue.MasterClient"
+
+#define GEOCLUE_TYPE_MASTER_CLIENT (geoclue_master_client_get_type ())
+#define GEOCLUE_MASTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_MASTER_CLIENT, GeoclueMasterClient))
+#define GEOCLUE_IS_MASTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_MASTER_CLIENT))
+
+typedef struct _GeoclueMasterClient {
+ GObject parent;
+} GeoclueMasterClient;
+
+typedef struct _GeoclueMasterClientClass {
+ GObjectClass parent_class;
+ void (* address_provider_changed) (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path);
+ void (* position_provider_changed) (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path);
+ void (* invalidated) (GeoclueMasterClient *client);
+} GeoclueMasterClientClass;
+
+GType geoclue_master_client_get_type (void);
+
+gboolean geoclue_master_client_set_requirements (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error);
+typedef void (*GeoclueSetRequirementsCallback) (GeoclueMasterClient *client,
+ GError *error,
+ gpointer userdata);
+void geoclue_master_client_set_requirements_async (GeoclueMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GeoclueSetRequirementsCallback callback,
+ gpointer userdata);
+
+GeoclueAddress *geoclue_master_client_create_address (GeoclueMasterClient *client, GError **error);
+typedef void (*CreateAddressCallback) (GeoclueMasterClient *client,
+ GeoclueAddress *address,
+ GError *error,
+ gpointer userdata);
+void geoclue_master_client_create_address_async (GeoclueMasterClient *client,
+ CreateAddressCallback callback,
+ gpointer userdata);
+
+
+GeocluePosition *geoclue_master_client_create_position (GeoclueMasterClient *client, GError **error);
+typedef void (*CreatePositionCallback) (GeoclueMasterClient *client,
+ GeocluePosition *position,
+ GError *error,
+ gpointer userdata);
+void geoclue_master_client_create_position_async (GeoclueMasterClient *client,
+ CreatePositionCallback callback,
+ gpointer userdata);
+
+gboolean geoclue_master_client_get_address_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+typedef void (*GeoclueGetProviderCallback) (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GError *error,
+ gpointer userdata);
+void geoclue_master_client_get_address_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata);
+
+gboolean geoclue_master_client_get_position_provider (GeoclueMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+void geoclue_master_client_get_position_provider_async (GeoclueMasterClient *client,
+ GeoclueGetProviderCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-master.c - Client API for accessing the Geoclue Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-master
+ * @short_description: Geoclue Master API
+ * @see_also: #GeoclueMasterClient
+ *
+ * #GeoclueMaster is part of the Geoclue public C client API. It uses
+ * D-Bus to communicate with the actual Master service.
+ *
+ * #GeoclueMaster is a singleton service, so it should not be created
+ * explicitly: instead one should use geoclue_master_get_default() to
+ * get a reference to it. It can be used to
+ * create a #GeoclueMasterClient object.
+ *
+ */
+
+#include <config.h>
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-accuracy.h>
+
+#include "gc-iface-master-bindings.h"
+
+typedef struct _GeoclueMasterPrivate {
+ DBusGProxy *proxy;
+} GeoclueMasterPrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_MASTER, GeoclueMasterPrivate))
+
+G_DEFINE_TYPE (GeoclueMaster, geoclue_master, G_TYPE_OBJECT);
+
+
+typedef struct _GeoclueMasterAsyncData {
+ GeoclueMaster *master;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueMasterAsyncData;
+
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_master_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_master_parent_class)->dispose (object);
+}
+
+static void
+geoclue_master_class_init (GeoclueMasterClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GeoclueMasterPrivate));
+}
+
+static void
+geoclue_master_init (GeoclueMaster *master)
+{
+ GeoclueMasterPrivate *priv;
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ priv = GET_PRIVATE (master);
+
+ connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!connection) {
+ g_warning ("Unable to get connection to Geoclue bus.\n%s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ priv->proxy = dbus_g_proxy_new_for_name (connection,
+ GEOCLUE_MASTER_DBUS_SERVICE,
+ GEOCLUE_MASTER_DBUS_PATH,
+ GEOCLUE_MASTER_DBUS_INTERFACE);
+}
+
+/**
+ * geoclue_master_get_default:
+ *
+ * Returns the default #GeoclueMaster object. Should be unreferenced once
+ * the client is finished with it.
+ *
+ * Return value: A reference to the default #GeoclueMaster object
+ */
+GeoclueMaster *
+geoclue_master_get_default (void)
+{
+ static GeoclueMaster *master = NULL;
+
+ if (G_UNLIKELY (master == NULL)) {
+ master = g_object_new (GEOCLUE_TYPE_MASTER, NULL);
+ g_object_add_weak_pointer (G_OBJECT (master),
+ (gpointer) &master);
+ return master;
+ }
+
+ return g_object_ref (master);
+}
+
+/**
+ * geoclue_master_create_client:
+ * @master: A #GeoclueMaster object
+ * @object_path: Pointer to returned #GeoclueMasterClient D-Bus object path or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Creates a #GeoclueMasterClient and puts the D-Bus object path in
+ * @object_path.
+ *
+ * Return Value: A new #GeoclueMasterClient or %NULL on error.
+ */
+
+GeoclueMasterClient *
+geoclue_master_create_client (GeoclueMaster *master,
+ char **object_path,
+ GError **error)
+{
+ GeoclueMasterPrivate *priv;
+ GeoclueMasterClient *client;
+ char *path;
+
+ g_return_val_if_fail (GEOCLUE_IS_MASTER (master), NULL);
+
+ priv = GET_PRIVATE (master);
+
+ if (!org_freedesktop_Geoclue_Master_create (priv->proxy,
+ &path, error)){
+ return NULL;
+ }
+
+ client = g_object_new (GEOCLUE_TYPE_MASTER_CLIENT,
+ "object-path", path,
+ NULL);
+
+ if (object_path) {
+ *object_path = path;
+ } else {
+ g_free (path);
+ }
+
+ return client;
+}
+
+static void
+create_client_callback (DBusGProxy *proxy,
+ char *path,
+ GError *error,
+ GeoclueMasterAsyncData *data)
+{
+ GeoclueMasterClient *client;
+
+ client = NULL;
+
+ if (!error) {
+ client = g_object_new (GEOCLUE_TYPE_MASTER_CLIENT,
+ "object-path", path,
+ NULL);
+ }
+
+ (*(GeoclueCreateClientCallback)data->callback) (data->master,
+ client,
+ path,
+ error,
+ data->userdata);
+
+ g_free (data);
+}
+
+void
+geoclue_master_create_client_async (GeoclueMaster *master,
+ GeoclueCreateClientCallback callback,
+ gpointer userdata)
+{
+ GeoclueMasterPrivate *priv;
+ GeoclueMasterAsyncData *data;
+
+ g_return_if_fail (GEOCLUE_IS_MASTER (master));
+
+ priv = GET_PRIVATE (master);
+ data = g_new (GeoclueMasterAsyncData, 1);
+ data->master = master;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Master_create_async
+ (priv->proxy,
+ (org_freedesktop_Geoclue_Master_create_reply)create_client_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-master.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_MASTER_H
+#define _GEOCLUE_MASTER_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-master-client.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_MASTER_DBUS_SERVICE "org.freedesktop.Geoclue.Master"
+#define GEOCLUE_MASTER_DBUS_PATH "/org/freedesktop/Geoclue/Master"
+#define GEOCLUE_MASTER_DBUS_INTERFACE "org.freedesktop.Geoclue.Master"
+
+#define GEOCLUE_TYPE_MASTER (geoclue_master_get_type ())
+#define GEOCLUE_MASTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_MASTER, GeoclueMaster))
+#define GEOCLUE_IS_MASTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_MASTER))
+
+typedef struct _GeoclueMaster {
+ GObject parent;
+} GeoclueMaster;
+
+typedef struct _GeoclueMasterClass {
+ GObjectClass parent_class;
+} GeoclueMasterClass;
+
+GType geoclue_master_get_type (void);
+
+GeoclueMaster *geoclue_master_get_default (void);
+
+GeoclueMasterClient *geoclue_master_create_client (GeoclueMaster *master,
+ char **object_path,
+ GError **error);
+typedef void (*GeoclueCreateClientCallback) (GeoclueMaster *master,
+ GeoclueMasterClient *client,
+ char *object_path,
+ GError *error,
+ gpointer userdata);
+void geoclue_master_create_client_async (GeoclueMaster *master,
+ GeoclueCreateClientCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-nmea.c - Client API for accessing GcIfaceNmea
+ *
+ * Author: Tae-Hwan Kim <the81.kim@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-nmea
+ * @short_description: Geoclue nmea client API
+ *
+ * #GeoclueNmea contains nmea-related methods and signals.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeoclueNmea is created with geoclue_nmea_new() or
+ * using geoclye_master_client_create_nmea(), the
+ * geoclue_nmea_get_nmea() and geoclue_nmea_get_nmea_async()
+ * method and the nmea-changed signal can be used to obtain the current nmea.
+ */
+
+#include <geoclue/geoclue-nmea.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-nmea-bindings.h"
+
+//#include <glib.h>
+#include <string.h>
+
+typedef struct _GeoclueNmeaPrivate {
+ int dummy;
+} GeoclueNmeaPrivate;
+
+enum {
+ NMEA_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_NMEA, GeoclueNmeaPrivate))
+
+G_DEFINE_TYPE (GeoclueNmea, geoclue_nmea, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_nmea_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_nmea_parent_class)->dispose (object);
+}
+
+static void
+nmea_changed (DBusGProxy *proxy,
+ int timestamp,
+ char *nmea_data,
+ GeoclueNmea *nmea)
+{
+ g_signal_emit (nmea, signals[NMEA_CHANGED], 0,
+ timestamp, nmea_data);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_nmea_parent_class)->constructor (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "NmeaChanged",
+ G_TYPE_INT,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "NmeaChanged",
+ G_CALLBACK (nmea_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_nmea_class_init (GeoclueNmeaClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeoclueNmeaPrivate));
+
+ signals[NMEA_CHANGED] = g_signal_new ("nmea-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueNmeaClass, nmea_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_STRING);
+}
+
+static void
+geoclue_nmea_init (GeoclueNmea *nmea)
+{
+}
+
+/**
+ * geoclue_nmea_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeoclueNmea with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeoclueNmea
+ */
+GeoclueNmea *
+geoclue_nmea_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_NMEA,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_NMEA_INTERFACE_NAME,
+ NULL);
+}
+
+gboolean
+geoclue_nmea_get_nmea (GeoclueNmea *nmea,
+ int *timestamp,
+ char **nmea_data,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (nmea);
+
+ if (!org_freedesktop_Geoclue_Nmea_get_nmea (provider->proxy,
+ timestamp,
+ nmea_data,
+ error)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+typedef struct _GeoclueNmeaAsyncData {
+ GeoclueNmea *nmea;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueNmeaAsyncData;
+
+static void
+get_nmea_async_callback (DBusGProxy *proxy,
+ int timestamp,
+ char *nmea_data,
+ GError *error,
+ GeoclueNmeaAsyncData *data)
+{
+ (*(GeoclueNmeaCallback)data->callback) (data->nmea,
+ timestamp,
+ nmea_data,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+void
+geoclue_nmea_get_nmea_async (GeoclueNmea *nmea,
+ GeoclueNmeaCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (nmea);
+ GeoclueNmeaAsyncData *data;
+
+ data = g_new (GeoclueNmeaAsyncData, 1);
+ data->nmea = nmea;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Nmea_get_nmea_async (
+ provider->proxy,
+ (org_freedesktop_Geoclue_Nmea_get_nmea_reply)get_nmea_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-nmea.h -
+ *
+ * Author: Tae-Hwan Kim <the81.kim@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_NMEA_H
+#define _GEOCLUE_NMEA_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+//#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_NMEA (geoclue_nmea_get_type ())
+#define GEOCLUE_NMEA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_NMEA, GeoclueNmea))
+#define GEOCLUE_IS_NMEA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_NMEA))
+
+#define GEOCLUE_NMEA_INTERFACE_NAME "org.freedesktop.Geoclue.Nmea"
+
+#define GEOCLUE_MAX_NMEA_DATA_SIZE (1500)
+
+typedef struct _GeoclueNmea {
+ GeoclueProvider provider;
+} GeoclueNmea;
+
+typedef struct _GeoclueNmeaClass {
+ GeoclueProviderClass provider_class;
+
+ void (* nmea_changed) (GeoclueNmea *nmea,
+ int timestamp,
+ char nmea_data[GEOCLUE_MAX_NMEA_DATA_SIZE]);
+} GeoclueNmeaClass;
+
+GType geoclue_nmea_get_type (void);
+
+GeoclueNmea *geoclue_nmea_new (const char *service,
+ const char *path);
+
+gboolean geoclue_nmea_get_nmea (GeoclueNmea *nmea,
+ int *timestamp,
+ char **nmea_data,
+ GError **error);
+
+typedef void (*GeoclueNmeaCallback) (GeoclueNmea *nmea,
+ int timestamp,
+ char *nmea_data,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_nmea_get_nmea_async (GeoclueNmea *nmea,
+ GeoclueNmeaCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-poi.c - Client API for accessing GcIfacePoi
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-poi
+ * @short_description: Geoclue poi client API
+ *
+ * #GeocluePoi contains geocoding methods.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeocluePoi is created with geoclue_poi_new(), the
+ * geoclue_poi_address_to_position(),
+ * geoclue_poi_freeform_address_to_position() methods and their
+ * asynchronous counterparts can be used to obtain the position (coordinates)
+ * of the given address.
+ *
+ * Address #GHashTable keys are defined in
+ * <ulink url="geoclue-types.html">geoclue-types.h</ulink>. See also
+ * convenience functions in
+ * <ulink url="geoclue-address-details.html">geoclue-address-details.h</ulink>.
+ */
+
+#include <geoclue/geoclue-poi.h>
+#include <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-landmark.h>
+
+#include "gc-iface-poi-bindings.h"
+
+typedef struct _GeocluePoiPrivate {
+ int dummy;
+} GeocluePoiPrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_POI, GeocluePoiPrivate))
+
+G_DEFINE_TYPE (GeocluePoi, geoclue_poi, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_poi_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_poi_parent_class)->dispose (object);
+}
+
+static void
+geoclue_poi_class_init (GeocluePoiClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GeocluePoiPrivate));
+}
+
+static void
+geoclue_poi_init (GeocluePoi *poi)
+{
+}
+
+/**
+ * geoclue_poi_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeocluePoi with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeocluePoi
+ */
+GeocluePoi *
+geoclue_poi_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_POI,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_POI_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_poi_address_to_position:
+ * @poi: A #GeocluePoi object
+ * @details: Hashtable with address data
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Pois given address to coordinates (@latitude, @longitude, @altitude).
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys usable in @details. @accuracy is a rough estimate of
+ * the accuracy of the returned position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionFields bitfield representing the
+ * validity of the returned coordinates.
+ */
+gboolean
+geoclue_poi_search_by_position (GeocluePoi *poi,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (poi);
+ if (!org_freedesktop_Geoclue_Poi_search_by_position (provider->proxy,
+ keyword, lang, country_code, limit, left, top, right, bottom, count,
+ landmark, error)){
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct _GeocluePoiAsyncData {
+ GeocluePoi *poi;
+ GCallback callback;
+ gpointer userdata;
+} GeocluePoiAsyncData;
+
+static void
+_geoclue_poi_callback (DBusGProxy *proxy,
+ int count,
+ GPtrArray *landmark,
+ GError *error,
+ GeocluePoiAsyncData *data)
+{
+
+ (*(GeocluePoiCallback)data->callback) (data->poi, count, landmark, error, data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeocluePoiCallback:
+ * @poi: A #GeocluePoi object
+ * @fields: A #GeocluePositionFields bitfield representing the validity of the position values
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror or %NULL
+ * @userdata: User data pointer
+ *
+ * Callback function for the asynchronous methods.
+ */
+
+/**
+ * geoclue_poi_address_to_position_async:
+ * @poi: A #GeocluePoi object
+ * @details: A #GHashTable with address data
+ * @callback: A #GeoclueAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when the poid
+ * position data is available or when D-Bus timeouts.
+ *
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys usable in @details.
+ *
+ */
+void
+geoclue_poi_search_by_position_async (GeocluePoi *poi,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ GeocluePoiCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (poi);
+ GeocluePoiAsyncData *data;
+
+ data = g_new (GeocluePoiAsyncData, 1);
+ data->poi = poi;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Poi_search_by_position_async
+ (provider->proxy,
+ keyword, lang, country_code, limit, left, top, right, bottom,
+ (org_freedesktop_Geoclue_Poi_search_by_position_reply)_geoclue_poi_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-poi.h -
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_POI_H
+#define _GEOCLUE_POI_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-address-details.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_POI (geoclue_poi_get_type ())
+#define GEOCLUE_POI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_POI, GeocluePoi))
+#define GEOCLUE_IS_POI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_POI))
+
+#define GEOCLUE_POI_INTERFACE_NAME "org.freedesktop.Geoclue.Poi"
+
+typedef struct _GeocluePoi {
+ GeoclueProvider provider;
+} GeocluePoi;
+
+typedef struct _GeocluePoiClass {
+ GeoclueProviderClass provider_class;
+} GeocluePoiClass;
+
+GType geoclue_poi_get_type (void);
+
+GeocluePoi *geoclue_poi_new (const char *service,
+ const char *path);
+
+gboolean
+geoclue_poi_search_by_position (GeocluePoi *poi,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error);
+
+typedef void (*GeocluePoiCallback) (GeocluePoi *poi,
+ int count,
+ GPtrArray *landmark,
+ GError *error,
+ gpointer userdata);
+
+void
+geoclue_poi_search_by_position_async (GeocluePoi *poi,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ GeocluePoiCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-position-ext.c - Client API for accessing GcIfacePosition
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-position-ext
+ * @short_description: Geoclue position & velocity client API
+ *
+ * #GeocluePositionVelocity contains position & velocity related methods and signals.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeocluePositionExt is created with geoclue_position_ext_new() or
+ * using geoclye_master_client_create_position_velocity(), the
+ * geoclue_position_ext_get_position() and geoclue_position_ext_get_position_async()
+ * method and the position-changed signal can be used to obtain the current position & velocity.
+ */
+
+#include <geoclue/geoclue-position-ext.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-position-ext-bindings.h"
+
+typedef struct _GeocluePositionExtPrivate {
+ int dummy;
+} GeocluePositionExtPrivate;
+
+enum {
+ POSITION_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_POSITION_EXT, GeocluePositionExtPrivate))
+
+G_DEFINE_TYPE (GeocluePositionExt, geoclue_position_ext, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_position_ext_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_position_ext_parent_class)->dispose (object);
+}
+
+static void
+position_changed (DBusGProxy *proxy,
+ int fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double velocity,
+ GeoclueAccuracy *accuracy,
+ GeocluePositionExt *position)
+{
+ g_signal_emit (position, signals[POSITION_CHANGED], 0, fields,
+ timestamp, latitude, longitude, altitude, speed, direction, velocity, accuracy);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_position_ext_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "PositionChanged",
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ GEOCLUE_ACCURACY_TYPE,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "PositionChanged",
+ G_CALLBACK (position_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_position_ext_class_init (GeocluePositionExtClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeocluePositionExtPrivate));
+
+ /**
+ * GeocluePosition::position--changed:
+ * @position: the #GeocluePositionExt object emitting the signal
+ * @fields: A #GeocluePositionExtFields bit field representing the validity of the position values
+ * @timestamp: Time of position measurement (Unix timestamp)
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @speed: Horizontal speed in m/s
+ * @direction: Horizontal direction in degrees
+ * @climb: Vertical speed
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ *
+ * The position-changed signal is emitted each time the position changes. Clients should note
+ * that not all providers support signals.
+ */
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeocluePositionExtClass, position_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 9,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_POINTER);
+}
+
+static void
+geoclue_position_ext_init (GeocluePositionExt *position)
+{
+}
+
+/**
+ * geoclue_position_ext_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeocluePositionExt with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeocluePositionExt
+ */
+GeocluePositionExt *
+geoclue_position_ext_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_POSITION_EXT,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_POSITION_EXT_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_position_ext_get_position:
+ * @position: A #GeocluePositionExt object
+ * @timestamp: Pointer to returned time of position measurement (Unix timestamp) or %NULL
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @speed: Pointer to returned horizontal speed or %NULL
+ * @direction: Pointer to returned horizontal direction (bearing) or %NULL
+ * @climb: Pointer to returned vertical speed or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains the current position & velocity. @timestamp will contain the time of
+ * the actual position & velocity measurement. @accuracy is a rough estimate of the
+ * accuracy of the current position & velocity.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionExtFields bitfield representing the
+ * validity of the position & velocity values.
+ */
+GeocluePositionExtFields
+geoclue_position_ext_get_position (GeocluePositionExt *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ double la, lo, al;
+ double sp, di, cl;
+ int ts, fields;
+ GeoclueAccuracy *acc;
+ if (!org_freedesktop_Geoclue_PositionExt_get_position (provider->proxy,
+ &fields, &ts,
+ &la, &lo, &al,
+ &sp, &di, &cl,
+ &acc, error)) {
+ return GEOCLUE_POSITION_EXT_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (speed != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_SPEED)) {
+ *speed = sp;
+ }
+
+ if (direction != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_DIRECTION)) {
+ *direction = di;
+ }
+
+ if (climb != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_CLIMB)) {
+ *climb = cl;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+/**
+ * geoclue_position_ext_get_last_position:
+ * @position: A #GeocluePositionExt object
+ * @timestamp: Pointer to returned time of position measurement (Unix timestamp) or %NULL
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @speed: Pointer to returned horizontal speed or %NULL
+ * @direction: Pointer to returned horizontal direction (bearing) or %NULL
+ * @climb: Pointer to returned vertical speed or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains the last position & velocity. @timestamp will contain the time of
+ * the actual position measurement. @accuracy is a rough estimate of the
+ * accuracy of the last position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionExtFields bitfield representing the
+ * validity of the position values.
+ */
+GeocluePositionExtFields
+geoclue_position_ext_get_last_position (GeocluePositionExt *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ double la, lo, al;
+ double sp, di, cl;
+ int ts, fields;
+ GeoclueAccuracy *acc;
+ if (!org_freedesktop_Geoclue_PositionExt_get_last_position (provider->proxy,
+ &fields, &ts,
+ &la, &lo, &al,
+ &sp, &di, &cl,
+ &acc, error)) {
+ return GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (speed != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_SPEED)) {
+ *speed = sp;
+ }
+
+ if (direction != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_DIRECTION)) {
+ *direction = di;
+ }
+
+ if (climb != NULL && (fields & GEOCLUE_POSITION_EXT_FIELDS_CLIMB)) {
+ *climb = cl;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+typedef struct _GeocluePositionExtAsyncData {
+ GeocluePositionExt *position;
+ GCallback callback;
+ gpointer userdata;
+} GeocluePositionExtAsyncData;
+
+static void
+get_position_async_callback (DBusGProxy *proxy,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ GeocluePositionExtAsyncData *data)
+{
+ (*(GeocluePositionExtCallback)data->callback) (data->position,
+ fields,
+ timestamp,
+ latitude,
+ longitude,
+ altitude,
+ speed,
+ direction,
+ climb,
+ accuracy,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeocluePositionExtCallback:
+ * @position: A #GeocluePositionExt object
+ * @fields: A #GeocluePositionExtFields bitfield representing the validity of the position values
+ * @timestamp: Time of position measurement (Unix timestamp)
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @speed: Horizontal speed (m/s)
+ * @direction: Horizontal direction in degrees
+ * @climb: Vertical speed
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror or %NULL
+ * @userdata: User data pointer set in geoclue_position_velocity_get_position_velocity_async()
+ *
+ * Callback function for geoclue_position_ext_get_position_async().
+ */
+
+/**
+ * geoclue_position_ext_get_position_async:
+ * @position: A #GeocluePositionExt object
+ * @callback: A #GeocluePositionExtCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when current position & velocity
+ * is available or when D-Bus timeouts.
+ */
+void
+geoclue_position_ext_get_position_async (GeocluePositionExt *position,
+ GeocluePositionExtCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ GeocluePositionExtAsyncData *data;
+
+ data = g_new (GeocluePositionExtAsyncData, 1);
+ data->position = position;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_PositionExt_get_position_async
+ (provider->proxy,
+ (org_freedesktop_Geoclue_PositionExt_get_position_reply)get_position_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-position-ext.h
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_POSITION_EXT_H
+#define _GEOCLUE_POSITION_EXT_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_POSITION_EXT (geoclue_position_ext_get_type ())
+#define GEOCLUE_POSITION_EXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_POSITION_EXT, GeocluePositionExt))
+#define GEOCLUE_IS_POSITION_EXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_POSITION_EXT))
+
+#define GEOCLUE_POSITION_EXT_INTERFACE_NAME "org.freedesktop.Geoclue.PositionExt"
+
+typedef struct _GeocluePositionExt {
+ GeoclueProvider provider;
+} GeocluePositionExt;
+
+typedef struct _GeocluePositionExtClass {
+ GeoclueProviderClass provider_class;
+
+ void (* position_changed) (GeocluePositionExt *position,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy);
+} GeocluePositionExtClass;
+
+GType geoclue_position_ext_get_type (void);
+
+GeocluePositionExt *geoclue_position_ext_new (const char *service,
+ const char *path);
+
+GeocluePositionExtFields geoclue_position_ext_get_position (GeocluePositionExt *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+GeocluePositionExtFields geoclue_position_ext_get_last_position (GeocluePositionExt *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ double *speed,
+ double *direction,
+ double *climb,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+typedef void (*GeocluePositionExtCallback) (GeocluePositionExt *position,
+ GeocluePositionExtFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_position_ext_get_position_async (GeocluePositionExt *position,
+ GeocluePositionExtCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-position.c - Client API for accessing GcIfacePosition
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-position
+ * @short_description: Geoclue position client API
+ *
+ * #GeocluePosition contains position-related methods and signals.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeocluePosition is created with geoclue_position_new() or
+ * using geoclye_master_client_create_position(), the
+ * geoclue_position_get_position() and geoclue_position_get_position_async()
+ * method and the position-changed signal can be used to obtain the current position.
+ */
+
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-position-bindings.h"
+
+typedef struct _GeocluePositionPrivate {
+ int dummy;
+} GeocluePositionPrivate;
+
+enum {
+ POSITION_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_POSITION, GeocluePositionPrivate))
+
+G_DEFINE_TYPE (GeocluePosition, geoclue_position, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_position_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_position_parent_class)->dispose (object);
+}
+
+static void
+position_changed (DBusGProxy *proxy,
+ int fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GeocluePosition *position)
+{
+ g_signal_emit (position, signals[POSITION_CHANGED], 0, fields,
+ timestamp, latitude, longitude, altitude, accuracy);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_position_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "PositionChanged",
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ GEOCLUE_ACCURACY_TYPE,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "PositionChanged",
+ G_CALLBACK (position_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_position_class_init (GeocluePositionClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeocluePositionPrivate));
+
+ /**
+ * GeocluePosition::position-changed:
+ * @position: the #GeocluePosition object emitting the signal
+ * @fields: A #GeocluePositionFields bitfield representing the validity of the position values
+ * @timestamp: Time of position measurement (Unix timestamp)
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ *
+ * The position-changed signal is emitted each time the position changes. Clients should note
+ * that not all providers support signals.
+ */
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeocluePositionClass, position_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 6,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_POINTER);
+}
+
+static void
+geoclue_position_init (GeocluePosition *position)
+{
+}
+
+/**
+ * geoclue_position_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeocluePosition with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeocluePosition
+ */
+GeocluePosition *
+geoclue_position_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_POSITION,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_POSITION_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_position_get_position:
+ * @position: A #GeocluePosition object
+ * @timestamp: Pointer to returned time of position measurement (Unix timestamp) or %NULL
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains the current position. @timestamp will contain the time of
+ * the actual position measurement. @accuracy is a rough estimate of the
+ * accuracy of the current position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionFields bitfield representing the
+ * validity of the position values.
+ */
+GeocluePositionFields
+geoclue_position_get_position (GeocluePosition *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ double la, lo, al;
+ int ts, fields;
+ GeoclueAccuracy *acc;
+ if (!org_freedesktop_Geoclue_Position_get_position (provider->proxy,
+ &fields, &ts,
+ &la, &lo, &al,
+ &acc, error)) {
+ return GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+/**
+ * geoclue_position_get_last_position:
+ * @position: A #GeocluePosition object
+ * @timestamp: Pointer to returned time of position measurement (Unix timestamp) or %NULL
+ * @latitude: Pointer to returned latitude in degrees or %NULL
+ * @longitude: Pointer to returned longitude in degrees or %NULL
+ * @altitude: Pointer to returned altitude in meters or %NULL
+ * @accuracy: Pointer to returned #GeoclueAccuracy or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains the last position. @timestamp will contain the time of
+ * the actual position measurement. @accuracy is a rough estimate of the
+ * accuracy of the last position.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeocluePositionFields bitfield representing the
+ * validity of the position values.
+ */
+GeocluePositionFields
+geoclue_position_get_last_position (GeocluePosition *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ double la, lo, al;
+ int ts, fields;
+ GeoclueAccuracy *acc;
+ if (!org_freedesktop_Geoclue_Position_get_last_position (provider->proxy,
+ &fields, &ts,
+ &la, &lo, &al,
+ &acc, error)) {
+ return GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (latitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)) {
+ *latitude = la;
+ }
+
+ if (longitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ *longitude = lo;
+ }
+
+ if (altitude != NULL && (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)) {
+ *altitude = al;
+ }
+
+ if (accuracy != NULL) {
+ *accuracy = acc;
+ }
+
+ return fields;
+}
+
+typedef struct _GeocluePositionAsyncData {
+ GeocluePosition *position;
+ GCallback callback;
+ gpointer userdata;
+} GeocluePositionAsyncData;
+
+static void
+get_position_async_callback (DBusGProxy *proxy,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ GeocluePositionAsyncData *data)
+{
+ (*(GeocluePositionCallback)data->callback) (data->position,
+ fields,
+ timestamp,
+ latitude,
+ longitude,
+ altitude,
+ accuracy,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeocluePositionCallback:
+ * @position: A #GeocluePosition object
+ * @fields: A #GeocluePositionFields bitfield representing the validity of the position values
+ * @timestamp: Time of position measurement (Unix timestamp)
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @altitude: Altitude in meters
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror or %NULL
+ * @userdata: User data pointer set in geoclue_position_get_position_async()
+ *
+ * Callback function for geoclue_position_get_position_async().
+ */
+
+/**
+ * geoclue_position_get_position_async:
+ * @position: A #GeocluePosition object
+ * @callback: A #GeocluePositionCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when current position
+ * is available or when D-Bus timeouts.
+ */
+void
+geoclue_position_get_position_async (GeocluePosition *position,
+ GeocluePositionCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (position);
+ GeocluePositionAsyncData *data;
+
+ data = g_new (GeocluePositionAsyncData, 1);
+ data->position = position;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Position_get_position_async
+ (provider->proxy,
+ (org_freedesktop_Geoclue_Position_get_position_reply)get_position_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-position.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_POSITION_H
+#define _GEOCLUE_POSITION_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_POSITION (geoclue_position_get_type ())
+#define GEOCLUE_POSITION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_POSITION, GeocluePosition))
+#define GEOCLUE_IS_POSITION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_POSITION))
+
+#define GEOCLUE_POSITION_INTERFACE_NAME "org.freedesktop.Geoclue.Position"
+
+typedef struct _GeocluePosition {
+ GeoclueProvider provider;
+} GeocluePosition;
+
+typedef struct _GeocluePositionClass {
+ GeoclueProviderClass provider_class;
+
+ void (* position_changed) (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy);
+} GeocluePositionClass;
+
+GType geoclue_position_get_type (void);
+
+GeocluePosition *geoclue_position_new (const char *service,
+ const char *path);
+
+GeocluePositionFields geoclue_position_get_position (GeocluePosition *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+GeocluePositionFields geoclue_position_get_last_position (GeocluePosition *position,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+typedef void (*GeocluePositionCallback) (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_position_get_position_async (GeocluePosition *position,
+ GeocluePositionCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-provider.c - Client object for accessing Geoclue Providers
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-provider
+ * @short_description: Common client API for Geoclue providers
+ *
+ * #GeoclueProvider contains the methods and signals common to all Geoclue
+ * providers. It is part of the public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * A #GeoclueProvider is not explicitly created. Instead any provider
+ * object can be cast to #GeoclueProvider. Using a #GeocluePosition as
+ * example here:
+ * <informalexample>
+ * <programlisting>
+ * GeocluePosition *pos;
+ * char *name;
+ * GError *error;
+ *
+ * pos = geoclue_position_new ("org.freedesktop.Geoclue.Providers.Example",
+ * "/org/freedesktop/Geoclue/Providers/Example");
+ *
+ * if (geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (pos),
+ * &name, NULL, &error)) {
+ * g_print ("name = %s", name);
+ * }
+ * </programlisting>
+ * </informalexample>
+ *
+ * #GeoclueProvider can be used to obtain generic
+ * information about the provider and to set provider
+ * options.
+ */
+
+#include <geoclue/geoclue-provider.h>
+#include "gc-iface-geoclue-bindings.h"
+
+typedef struct _GeoclueProviderAsyncData {
+ GeoclueProvider *provider;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueProviderAsyncData;
+
+typedef struct _GeoclueProviderPrivate {
+ DBusGProxy *geoclue_proxy;
+
+ char *service;
+ char *path;
+ char *interface;
+} GeoclueProviderPrivate;
+
+enum {
+ PROP_0,
+ PROP_SERVICE,
+ PROP_PATH,
+ PROP_INTERFACE
+};
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_PROVIDER, GeoclueProviderPrivate))
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GeoclueProvider, geoclue_provider, G_TYPE_OBJECT, geoclue_types_init (););
+
+#define GEOCLUE_INTERFACE_NAME "org.freedesktop.Geoclue"
+
+
+static void
+status_changed (DBusGProxy *proxy,
+ GeoclueStatus status,
+ GeoclueProvider *provider)
+{
+ g_signal_emit (provider, signals[STATUS_CHANGED], 0, status);
+}
+
+static void
+add_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Could not reference provider: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+remove_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Could not unreference provider: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->service);
+ g_free (priv->path);
+ g_free (priv->interface);
+
+ G_OBJECT_CLASS (geoclue_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (object);
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ org_freedesktop_Geoclue_remove_reference_async (priv->geoclue_proxy,
+ remove_reference_callback,
+ NULL);
+ if (priv->geoclue_proxy) {
+ g_object_unref (priv->geoclue_proxy);
+ priv->geoclue_proxy = NULL;
+ }
+
+ if (provider->proxy) {
+ g_object_unref (provider->proxy);
+ provider->proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (geoclue_provider_parent_class)->dispose (object);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+ GeoclueProviderPrivate *priv;
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ object = G_OBJECT_CLASS (geoclue_provider_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+ priv = GET_PRIVATE (provider);
+
+ // There is a crash due to DBUS_BUS_SESSION
+ //connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+
+ if (connection == NULL) {
+ g_printerr ("Failed to open connection to bus: %s\n",
+ error->message);
+ g_error_free (error);
+ provider->proxy = NULL;
+ priv->geoclue_proxy = NULL;
+
+ return object;
+ }
+
+ /* proxy for the requested interface */
+ provider->proxy = dbus_g_proxy_new_for_name (connection,
+ priv->service, priv->path,
+ priv->interface);
+
+ /* proxy for org.freedesktop.Geoclue */
+ priv->geoclue_proxy = dbus_g_proxy_new_for_name (connection,
+ priv->service, priv->path,
+ GEOCLUE_INTERFACE_NAME);
+ org_freedesktop_Geoclue_add_reference_async (priv->geoclue_proxy,
+ add_reference_callback,
+ NULL);
+ dbus_g_proxy_add_signal (priv->geoclue_proxy, "StatusChanged",
+ G_TYPE_INT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->geoclue_proxy, "StatusChanged",
+ G_CALLBACK (status_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_SERVICE:
+ priv->service = g_value_dup_string (value);
+ break;
+
+ case PROP_PATH:
+ priv->path = g_value_dup_string (value);
+ break;
+
+ case PROP_INTERFACE:
+ priv->interface = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+geoclue_provider_class_init (GeoclueProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+ o_class->set_property = set_property;
+ o_class->get_property = get_property;
+
+ g_type_class_add_private (klass, sizeof (GeoclueProviderPrivate));
+
+ g_object_class_install_property
+ (o_class, PROP_SERVICE,
+ g_param_spec_string ("service", "Service",
+ "The D-Bus service this object represents",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+ g_object_class_install_property
+ (o_class, PROP_PATH,
+ g_param_spec_string ("path", "Path",
+ "The D-Bus path to this provider",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+ g_object_class_install_property
+ (o_class, PROP_INTERFACE,
+ g_param_spec_string ("interface", "Interface",
+ "The D-Bus interface implemented by the object",
+ "", G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME));
+
+ /**
+ * GeoclueProvider::status-changed:
+ * @provider: the provider object emitting the signal
+ * @status: New provider status as #GeoclueStatus
+ *
+ * The status-changed signal is emitted each time the provider
+ * status changes
+ **/
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+
+}
+
+static void
+geoclue_provider_init (GeoclueProvider *provider)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ provider->proxy = NULL;
+ priv->geoclue_proxy = NULL;
+}
+
+/**
+ * geoclue_provider_get_status:
+ * @provider: A #GeoclueProvider object
+ * @status: Pointer for returned status as #GeoclueStatus
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Obtains the current status of the provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_provider_get_status (GeoclueProvider *provider,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ int i;
+
+ if (status == NULL) {
+ return TRUE;
+ }
+
+ if (!org_freedesktop_Geoclue_get_status (priv->geoclue_proxy,
+ &i, error)) {
+ return FALSE;
+ }
+ *status = i;
+ return TRUE;
+}
+
+static void
+get_status_async_callback (DBusGProxy *proxy,
+ GeoclueStatus status,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderStatusCallback)data->callback) (data->provider,
+ status,
+ error,
+ data->userdata);
+ g_free (data);
+
+}
+
+/**
+ * GeoclueProviderStatusCallback:
+ * @provider: A #GeoclueProvider object
+ * @status: A #GeoclueStatus
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_get_status_async()
+ *
+ * Callback function for geoclue_provider_get_status_async().
+ */
+
+/**
+ * geoclue_provider_get_status_async:
+ * @provider: A #GeoclueProvider object
+ * @callback: A #GeoclueProviderStatusCallback function that will be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_get_status(). Function returns
+ * (essentially) immediately and calls @callback when status is available or
+ * when there is an error.
+ */
+void
+geoclue_provider_get_status_async (GeoclueProvider *provider,
+ GeoclueProviderStatusCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_get_status_async
+ (priv->geoclue_proxy,
+ (org_freedesktop_Geoclue_get_status_reply)get_status_async_callback,
+ data);
+}
+
+
+/**
+ * geoclue_provider_set_options:
+ * @provider: A #GeoclueProvider object
+ * @options: A #GHashTable containing the options
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Sets the options on the provider.
+ *
+ * Return value: %TRUE if setting options succeeded
+ */
+gboolean
+geoclue_provider_set_options (GeoclueProvider *provider,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (options == NULL) {
+ return TRUE;
+ }
+
+ return org_freedesktop_Geoclue_set_options (priv->geoclue_proxy,
+ options, error);
+}
+
+static void
+set_options_async_callback (DBusGProxy *proxy,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderOptionsCallback)data->callback) (data->provider,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueProviderOptionsCallback:
+ * @provider: A #GeoclueProvider object
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_set_options_async()
+ *
+ * Callback function for geoclue_provider_set_options_async().
+ */
+
+/**
+ * geoclue_provider_set_options_async:
+ * @provider: A #GeoclueProvider object
+ * @options: A #GHashTable of options
+ * @callback: A #GeoclueProviderOptionsCallback function that will be called when options are set
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_set_options(). Function returns
+ * (essentially) immediately and calls @callback when options have been set or
+ * when there is an error.
+ */
+void
+geoclue_provider_set_options_async (GeoclueProvider *provider,
+ GHashTable *options,
+ GeoclueProviderOptionsCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_set_options_async
+ (priv->geoclue_proxy,
+ options,
+ (org_freedesktop_Geoclue_set_options_reply)set_options_async_callback,
+ data);
+}
+
+/**
+ * geoclue_provider_get_provider_info:
+ * @provider: A #GeoclueProvider object
+ * @name: Pointer for returned provider name or %NULL
+ * @description: Pointer for returned provider description or %NULL
+ * @error: Pointer for returned #GError or %NULL
+ *
+ * Obtains name and a short description of the provider.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+geoclue_provider_get_provider_info (GeoclueProvider *provider,
+ char **name,
+ char **description,
+ GError **error)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return org_freedesktop_Geoclue_get_provider_info (priv->geoclue_proxy,
+ name, description,
+ error);
+}
+
+static void
+get_provider_info_async_callback (DBusGProxy *proxy,
+ char *name,
+ char *description,
+ GError *error,
+ GeoclueProviderAsyncData *data)
+{
+ (*(GeoclueProviderInfoCallback)data->callback) (data->provider,
+ name,
+ description,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueProviderInfoCallback:
+ * @provider: A #GeoclueProvider object
+ * @name: Name of the provider
+ * @description: one-line description of the provider
+ * @error: Error as #GError or %NULL
+ * @userdata: User data pointer set in geoclue_provider_get_provider_info_async()
+ *
+ * Callback function for geoclue_provider_get_provider_info_async().
+ */
+
+/**
+ * geoclue_provider_get_provider_info_async:
+ * @provider: A #GeoclueProvider object
+ * @callback: A #GeoclueProviderInfoCallback function that will be called when info is available
+ * @userdata: pointer for user specified data
+ *
+ * Asynchronous version of geoclue_provider_get_provider_info(). Function returns
+ * (essentially) immediately and calls @callback when info is available or
+ * when there is an error.
+ */
+void
+geoclue_provider_get_provider_info_async (GeoclueProvider *provider,
+ GeoclueProviderInfoCallback callback,
+ gpointer userdata)
+{
+ GeoclueProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueProviderAsyncData *data;
+
+ data = g_new (GeoclueProviderAsyncData, 1);
+ data->provider = provider;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_get_provider_info_async
+ (priv->geoclue_proxy,
+ (org_freedesktop_Geoclue_get_provider_info_reply)get_provider_info_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-provider.h - Client object for accessing Geoclue Providers
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_PROVIDER_H
+#define _GEOCLUE_PROVIDER_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_PROVIDER (geoclue_provider_get_type ())
+#define GEOCLUE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_PROVIDER, GeoclueProvider))
+#define GEOCLUE_IS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_PROVIDER))
+
+typedef struct _GeoclueProvider {
+ GObject object;
+
+ DBusGProxy *proxy;
+} GeoclueProvider;
+
+typedef struct _GeoclueProviderClass {
+ GObjectClass object_class;
+
+ void (*status_changed) (GeoclueProvider *provider,
+ GeoclueStatus status);
+} GeoclueProviderClass;
+
+GType geoclue_provider_get_type (void);
+
+gboolean geoclue_provider_get_status (GeoclueProvider *provider,
+ GeoclueStatus *status,
+ GError **error);
+typedef void (*GeoclueProviderStatusCallback) (GeoclueProvider *provider,
+ GeoclueStatus status,
+ GError *error,
+ gpointer userdata);
+void geoclue_provider_get_status_async (GeoclueProvider *provider,
+ GeoclueProviderStatusCallback callback,
+ gpointer userdata);
+
+gboolean geoclue_provider_get_provider_info (GeoclueProvider *provider,
+ char **name,
+ char **description,
+ GError **error);
+typedef void (*GeoclueProviderInfoCallback) (GeoclueProvider *provider,
+ char *name,
+ char *description,
+ GError *error,
+ gpointer userdata);
+void geoclue_provider_get_provider_info_async (GeoclueProvider *provider,
+ GeoclueProviderInfoCallback callback,
+ gpointer userdata);
+
+gboolean geoclue_provider_set_options (GeoclueProvider *provider,
+ GHashTable *options,
+ GError **error);
+typedef void (*GeoclueProviderOptionsCallback) (GeoclueProvider *provider,
+ GError *error,
+ gpointer userdata);
+void geoclue_provider_set_options_async (GeoclueProvider *provider,
+ GHashTable *options,
+ GeoclueProviderOptionsCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-reverse-geocode.c - Client API for accessing GcIfaceReverseGeocode
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-reverse-geocode
+ * @short_description: Geoclue reverse geocode client API
+ *
+ * #GeoclueReverseGeocode contains reverse geocoding methods.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeoclueReverseGeocode is created with
+ * geoclue_reverse_geocode_new(), the
+ * geoclue_reverse_geocode_position_to_address() and
+ * geoclue_reverse_geocode_position_to_address_async() method can be used to
+ * obtain the address of a known position.
+ */
+
+#include <geoclue/geoclue-reverse-geocode.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-reverse-geocode-bindings.h"
+
+typedef struct _GeoclueReverseGeocodePrivate {
+ int dummy;
+} GeoclueReverseGeocodePrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_REVERSE_GEOCODE, GeoclueReverseGeocodePrivate))
+
+G_DEFINE_TYPE (GeoclueReverseGeocode, geoclue_reverse_geocode, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_reverse_geocode_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_reverse_geocode_parent_class)->dispose (object);
+}
+
+static void
+geoclue_reverse_geocode_class_init (GeoclueReverseGeocodeClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GeoclueReverseGeocodePrivate));
+}
+
+static void
+geoclue_reverse_geocode_init (GeoclueReverseGeocode *geocode)
+{
+}
+
+/**
+ * geoclue_reverse_geocode_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeoclueReverseGeocode with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeoclueReverseGeocode
+ */
+GeoclueReverseGeocode *
+geoclue_reverse_geocode_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_REVERSE_GEOCODE,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_REVERSE_GEOCODE_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_reverse_geocode_position_to_address:
+ * @geocode: A #GeoclueReverseGeocode object
+ * @latitude: latitude in degrees
+ * @longitude: longitude in degrees
+ * @position_accuracy: Accuracy of the given latitude and longitude
+ * @details: Pointer to returned #GHashTable with address details or %NULL
+ * @address_accuracy: Pointer to accuracy of the returned address or %NULL
+ * @error: Pointer to returned #Gerror or %NULL
+ *
+ * Obtains an address for the position defined by @latitude and @longitude.
+ * @details is a #GHashTable with the returned address data, see
+ * <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the hashtable keys.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL. If accuracy of the position is not known, an accuracy with
+ * GeoclueAccuracyLevel GEOCLUE_ACCURACY_DETAILED should be used.
+ *
+ * Return value: %TRUE if there is no @error
+ */
+gboolean
+geoclue_reverse_geocode_position_to_address (GeoclueReverseGeocode *geocode,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **details,
+ GeoclueAccuracy **address_accuracy,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (geocode);
+
+ return org_freedesktop_Geoclue_ReverseGeocode_position_to_address
+ (provider->proxy, latitude, longitude, position_accuracy,
+ details, address_accuracy, error);
+}
+
+
+typedef struct _GeoclueRevGeocodeAsyncData {
+ GeoclueReverseGeocode *revgeocode;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueRevGeocodeAsyncData;
+
+static void
+position_to_address_callback (DBusGProxy *proxy,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ GeoclueRevGeocodeAsyncData *data)
+{
+ (*(GeoclueReverseGeocodeCallback)data->callback) (data->revgeocode,
+ details,
+ accuracy,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueReverseGeocodeCallback:
+ * @revgeocode: A #GeoclueReverseGeocode object
+ * @details: Address details as #GHashTable.
+ * @accuracy: Accuracy of measurement as #GeoclueAccuracy
+ * @error: Error as #Gerror (may be %NULL)
+ * @userdata: User data pointer set in geoclue_reverse_geocode_position_to_address_async()
+ *
+ * Callback function for geoclue_reverse_geocode_position_to_address_async().
+ *
+ * see <ulink url="geoclue-types.html">geoclue-types.h</ulink> for the
+ * hashtable keys used in @details.
+ */
+
+/**
+ * geoclue_reverse_geocode_position_to_address_async:
+ * @geocode: A #GeoclueReverseGeocode object
+ * @latitude: Latitude in degrees
+ * @longitude: Longitude in degrees
+ * @accuracy: Accuracy of the given position as #GeoclueAccuracy
+ * @callback: A #GeoclueAddressCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when the reverse-geocoded
+ * address data is available or when D-Bus timeouts.
+ */
+void
+geoclue_reverse_geocode_position_to_address_async (GeoclueReverseGeocode *revgeocode,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *accuracy,
+ GeoclueReverseGeocodeCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (revgeocode);
+ GeoclueRevGeocodeAsyncData *data;
+
+ data = g_new (GeoclueRevGeocodeAsyncData, 1);
+ data->revgeocode = revgeocode;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_ReverseGeocode_position_to_address_async
+ (provider->proxy,
+ latitude,
+ longitude,
+ accuracy,
+ (org_freedesktop_Geoclue_ReverseGeocode_position_to_address_reply)position_to_address_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-reverse-geocode.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_REVERSE_GEOCODE_H
+#define _GEOCLUE_REVERSE_GEOCODE_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_REVERSE_GEOCODE (geoclue_reverse_geocode_get_type ())
+#define GEOCLUE_REVERSE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_REVERSE_GEOCODE, GeoclueReverseGeocode))
+#define GEOCLUE_IS_REVERSE_GEOCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GEOCODE_REVERSE))
+
+#define GEOCLUE_REVERSE_GEOCODE_INTERFACE_NAME "org.freedesktop.Geoclue.ReverseGeocode"
+
+typedef struct _GeoclueReverseGeocode {
+ GeoclueProvider provider;
+} GeoclueReverseGeocode;
+
+typedef struct _GeoclueReverseGeocodeClass {
+ GeoclueProviderClass provider_class;
+} GeoclueReverseGeocodeClass;
+
+GType geoclue_reverse_geocode_get_type (void);
+
+GeoclueReverseGeocode *geoclue_reverse_geocode_new (const char *service,
+ const char *path);
+
+gboolean
+geoclue_reverse_geocode_position_to_address (GeoclueReverseGeocode *revgeocode,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **details,
+ GeoclueAccuracy **address_accuracy,
+ GError **error);
+
+typedef void (*GeoclueReverseGeocodeCallback) (GeoclueReverseGeocode *revgeocode,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_reverse_geocode_position_to_address_async (GeoclueReverseGeocode *revgeocode,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *accuracy,
+ GeoclueReverseGeocodeCallback callback,
+ gpointer userdata);
+
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * gc-iface-satellite.c - GInterface for org.freedesktop.Geoclue.Satellite
+ *
+ * Author: Sagnho Park <sangho.g.park@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_SATELLITE_INFO_H
+#define _GEOCLUE_SATELLITE_INFO_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_SATELLITE_INFO (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID))
+#define GEOCLUE_SATELLITE_INFO_ARRAY (dbus_g_type_get_collection ("GPtrArray", GEOCLUE_SATELLITE_INFO))
+
+G_END_DECLS
+
+#endif
+
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-satellite.c - Client API for accessing GcIfaceSatellite
+ *
+ * Author: Sagnho Park <sangho.g.park@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <geoclue/geoclue-satellite.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-satellite-bindings.h"
+
+typedef struct _GeoclueSatellitePrivate {
+ int dummy;
+} GeoclueSatellitePrivate;
+
+enum {
+ SATELLITE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_SATELLITE, GeoclueSatellitePrivate))
+
+G_DEFINE_TYPE (GeoclueSatellite, geoclue_satellite, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_satellite_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_satellite_parent_class)->dispose (object);
+}
+
+static void
+satellite_changed (DBusGProxy *proxy,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info,
+ GeoclueSatellite *satellite)
+{
+ g_signal_emit (satellite, signals[SATELLITE_CHANGED], 0, timestamp, satellite_used, satellite_visible,
+ used_prn,sat_info);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_satellite_parent_class)->constructor (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "SatelliteChanged",
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ DBUS_TYPE_G_INT_ARRAY,
+ GEOCLUE_SATELLITE_INFO_ARRAY,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "SatelliteChanged",
+ G_CALLBACK (satellite_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_satellite_class_init (GeoclueSatelliteClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeoclueSatellitePrivate));
+
+ signals[SATELLITE_CHANGED] = g_signal_new ("satellite-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueSatelliteClass, satellite_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_INT_POINTER_POINTER,
+ G_TYPE_NONE, 5,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_POINTER, G_TYPE_POINTER);
+}
+
+static void
+geoclue_satellite_init (GeoclueSatellite *satellite)
+{
+}
+
+GeoclueSatellite *
+geoclue_satellite_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_SATELLITE,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_SATELLITE_INTERFACE_NAME,
+ NULL);
+}
+
+gboolean
+geoclue_satellite_get_satellite (GeoclueSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (satellite);
+ if (!org_freedesktop_Geoclue_Satellite_get_satellite (provider->proxy,
+ timestamp, satellite_used, satellite_visible,
+ used_prn, sat_info, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+geoclue_satellite_get_last_satellite (GeoclueSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (satellite);
+ if (!org_freedesktop_Geoclue_Satellite_get_last_satellite (provider->proxy,
+ timestamp, satellite_used, satellite_visible,
+ used_prn, sat_info, error)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+typedef struct _GeoclueSatelliteAsyncData {
+ GeoclueSatellite *satellite;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueSatelliteAsyncData;
+
+static void
+get_satellite_async_callback (DBusGProxy *proxy,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info,
+ GError *error,
+ GeoclueSatelliteAsyncData *data)
+{
+ (*(GeoclueSatelliteCallback)data->callback) (data->satellite,
+ timestamp,
+ satellite_used,
+ satellite_visible,
+ used_prn,
+ sat_info,
+ error,
+ data->userdata);
+
+ g_free (data);
+}
+
+void
+geoclue_satellite_get_satellite_async (GeoclueSatellite *satellite,
+ GeoclueSatelliteCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (satellite);
+ GeoclueSatelliteAsyncData *data;
+
+ data = g_new (GeoclueSatelliteAsyncData, 1);
+ data->satellite = satellite;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Satellite_get_satellite_async (provider->proxy,
+ (org_freedesktop_Geoclue_Satellite_get_satellite_reply)get_satellite_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-satellite.h -
+ *
+ * Author: Sagnho Park <sangho.g.park@samsung.com>, Youngae Kang <youngae.kang@samsung.com>,
+ * Yunhan Kim <yhan.kim@samsung.com>, Genie Kim <daejins.kim@samsung.com>
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_SATELLITE_H
+#define _GEOCLUE_SATELLITE_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-satellite-info.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_SATELLITE (geoclue_satellite_get_type ())
+#define GEOCLUE_SATELLITE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_SATELLITE, GeoclueSatellite))
+#define GEOCLUE_IS_SATELLITE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_SATELLITE))
+
+#define GEOCLUE_SATELLITE_INTERFACE_NAME "org.freedesktop.Geoclue.Satellite"
+
+typedef struct _GeoclueSatellite {
+ GeoclueProvider provider;
+} GeoclueSatellite;
+
+typedef struct _GeoclueSatelliteClass {
+ GeoclueProviderClass provider_class;
+
+ void (* satellite_changed) (GeoclueSatellite *satellite,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info);
+} GeoclueSatelliteClass;
+
+GType geoclue_satellite_get_type (void);
+
+GeoclueSatellite *geoclue_satellite_new (const char *service,
+ const char *path);
+
+gboolean geoclue_satellite_get_satellite (GeoclueSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+
+gboolean geoclue_satellite_get_last_satellite (GeoclueSatellite *satellite,
+ int *timestamp,
+ int *satellite_used,
+ int *satellite_visible,
+ GArray **used_prn,
+ GPtrArray **sat_info,
+ GError **error);
+
+typedef void (*GeoclueSatelliteCallback) (GeoclueSatellite *satellite,
+ int timestamp,
+ int satellite_used,
+ int satellite_visible,
+ GArray *used_prn,
+ GPtrArray *sat_info,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_satellite_get_satellite_async (GeoclueSatellite *satellite,
+ GeoclueSatelliteCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-types.c -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <geoclue/geoclue-marshal.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include <geoclue/geoclue-satellite.h>
+#include <geoclue/geoclue-error.h>
+
+void
+geoclue_types_init (void)
+{
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_BOXED,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_BOXED,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_BOXED,
+ G_TYPE_BOXED,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_STRING,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (geoclue_marshal_VOID__INT_INT_INT_POINTER_POINTER,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ DBUS_TYPE_G_INT_ARRAY,
+ GEOCLUE_SATELLITE_INFO_ARRAY,
+ G_TYPE_INVALID);
+
+ dbus_g_error_domain_register (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_DBUS_INTERFACE,
+ GEOCLUE_TYPE_ERROR);
+
+
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-types.h - Types for Geoclue
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_TYPES_H
+#define _GEOCLUE_TYPES_H
+
+#include <geoclue/geoclue-error.h>
+
+/**
+ * SECTION:geoclue-types
+ * @short_description: Type definitions and defines useful for Geoclue clients
+ **/
+
+
+/**
+ * GeoclueStatus
+ *
+ * defines the provider status
+ **/
+typedef enum {
+ GEOCLUE_STATUS_ERROR,
+ GEOCLUE_STATUS_UNAVAILABLE,
+ GEOCLUE_STATUS_ACQUIRING,
+ GEOCLUE_STATUS_AVAILABLE
+} GeoclueStatus;
+
+/**
+ * GeoclueAccuracyLevel:
+ *
+ * Enum values used to define the approximate accuracy of
+ * Position or Address information.
+ **/
+typedef enum {
+ GEOCLUE_ACCURACY_LEVEL_NONE = 0,
+ GEOCLUE_ACCURACY_LEVEL_COUNTRY,
+ GEOCLUE_ACCURACY_LEVEL_REGION,
+ GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ GEOCLUE_ACCURACY_LEVEL_POSTALCODE,
+ GEOCLUE_ACCURACY_LEVEL_STREET,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+} GeoclueAccuracyLevel;
+
+/**
+ * GeocluePositionFields:
+ *
+ * #GeocluePositionFields is a bitfield that defines the validity of
+ * Position values.
+ *
+ * Example:
+ * <informalexample>
+ * <programlisting>
+ * GeocluePositionFields fields;
+ * fields = geoclue_position_get_position (. . .);
+ *
+ * if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ * fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ * g_print("latitude and longitude are valid");
+ * }
+ * </programlisting>
+ * </informalexample>
+ **/
+typedef enum {
+ GEOCLUE_POSITION_FIELDS_NONE = 0,
+ GEOCLUE_POSITION_FIELDS_LATITUDE = 1 << 0,
+ GEOCLUE_POSITION_FIELDS_LONGITUDE = 1 << 1,
+ GEOCLUE_POSITION_FIELDS_ALTITUDE = 1 << 2
+} GeocluePositionFields;
+
+/**
+ * GeoclueVelocityFields:
+ *
+ * GeoclueVelocityFields is a bitfield that defines the validity of
+ * Velocity values.
+ **/
+typedef enum {
+ GEOCLUE_VELOCITY_FIELDS_NONE = 0,
+ GEOCLUE_VELOCITY_FIELDS_SPEED = 1 << 0,
+ GEOCLUE_VELOCITY_FIELDS_DIRECTION = 1 << 1,
+ GEOCLUE_VELOCITY_FIELDS_CLIMB = 1 << 2
+} GeoclueVelocityFields;
+
+/**
+ * GeocluePositionExtFields:
+ *
+ * GeocluePositionExtFields is a bitfield that defines the validity of
+ * Position & Velocity values.
+ **/
+typedef enum {
+ GEOCLUE_POSITION_EXT_FIELDS_NONE = 0,
+ GEOCLUE_POSITION_EXT_FIELDS_LATITUDE = 1 << 0,
+ GEOCLUE_POSITION_EXT_FIELDS_LONGITUDE = 1 << 1,
+ GEOCLUE_POSITION_EXT_FIELDS_ALTITUDE = 1 << 2,
+ GEOCLUE_POSITION_EXT_FIELDS_SPEED = 1 << 3,
+ GEOCLUE_POSITION_EXT_FIELDS_DIRECTION = 1 << 4,
+ GEOCLUE_POSITION_EXT_FIELDS_CLIMB = 1 << 5
+} GeocluePositionExtFields;
+
+/**
+ * GEOCLUE_ADDRESS_KEY_COUNTRYCODE:
+ *
+ * A key for address hashtables. The hash value should be a ISO 3166 two
+ * letter country code.
+ *
+ * The used hash keys match the elements of XEP-0080 (XMPP protocol
+ * extension for user location), see
+ * <ulink url="http://www.xmpp.org/extensions/xep-0080.html">
+ * http://www.xmpp.org/extensions/xep-0080.html</ulink>
+ */
+#define GEOCLUE_ADDRESS_KEY_COUNTRYCODE "countrycode"
+/**
+ * GEOCLUE_ADDRESS_KEY_COUNTRY:
+ *
+ * A key for address hashtables. The hash value should be a name of a country.
+ */
+#define GEOCLUE_ADDRESS_KEY_COUNTRY "country"
+/**
+ * GEOCLUE_ADDRESS_KEY_REGION:
+ *
+ * A key for address hashtables. The hash value should be a name of an
+ * administrative region of a nation, e.g. province or
+ * US state.
+ */
+#define GEOCLUE_ADDRESS_KEY_REGION "region"
+/**
+ * GEOCLUE_ADDRESS_KEY_LOCALITY:
+ *
+ * A key for address hashtables. The hash value should be a name of a town
+ * or city.
+ */
+#define GEOCLUE_ADDRESS_KEY_LOCALITY "locality"
+/**
+ * GEOCLUE_ADDRESS_KEY_AREA:
+ *
+ * A key for address hashtables. The hash value should be a name of an
+ * area, such as neighborhood or campus.
+ */
+#define GEOCLUE_ADDRESS_KEY_AREA "area"
+/**
+ * GEOCLUE_ADDRESS_KEY_POSTALCODE:
+ *
+ * A key for address hashtables. The hash value should be a code used for
+ * postal delivery.
+ */
+#define GEOCLUE_ADDRESS_KEY_POSTALCODE "postalcode"
+/**
+ * GEOCLUE_ADDRESS_KEY_STREET:
+ *
+ * A key for address hashtables. The hash value should be a partial or full street
+ * address.
+ */
+#define GEOCLUE_ADDRESS_KEY_STREET "street"
+
+/**
+ * GEOCLUE_LANDMARK_KEY_COUNTRYCODE:
+ *
+ * A key for landmark hashtables. The hash value should be a ISO 3166 two
+ * letter country code.
+ *
+ * The used hash keys match the elements of XEP-0080 (XMPP protocol
+ * extension for user location), see
+ * <ulink url="http://www.xmpp.org/extensions/xep-0080.html">
+ * http://www.xmpp.org/extensions/xep-0080.html</ulink>
+ */
+#define GEOCLUE_LANDMARK_KEY_COUNTRYCODE GEOCLUE_ADDRESS_KEY_COUNTRYCODE
+/**
+ * GEOCLUE_LANDMARK_KEY_ID:
+ *
+ * A key for landmark hashtables. The hash value should be an id of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_ID "id"
+/**
+ * GEOCLUE_LANDMARK_KEY_RANK:
+ *
+ * A key for landmark hashtables. The hash value should be a rank of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_RANK "rank"
+/**
+ * GEOCLUE_LANDMARK_KEY_LAT:
+ *
+ * A key for landmark hashtables. The hash value should be a latitude of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_LAT "lat"
+/**
+ * GEOCLUE_LANDMARK_KEY_LON:
+ *
+ * A key for landmark hashtables. The hash value should be a longitude of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_LON "lon"
+/**
+ * GEOCLUE_LANDMARK_KEY_BOUNDINGBOX:
+ *
+ * A key for landmark hashtables. The hash value should be a bounding box of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_BOUNDINGBOX "boundingbox"
+/**
+ * GEOCLUE_LANDMARK_KEY_NAME:
+ *
+ * A key for landmark hashtables. The hash value should be a display name of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_NAME "display_name"
+/**
+ * GEOCLUE_LANDMARK_KEY_HOUSE:
+ *
+ * A key for landmark hashtables. The hash value should be a house of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_HOUSE "house"
+/**
+ * GEOCLUE_LANDMARK_KEY_ROAD:
+ *
+ * A key for landmark hashtables. The hash value should be a road of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_ROAD "road"
+/**
+ * GEOCLUE_LANDMARK_KEY_VILLAGE:
+ *
+ * A key for landmark hashtables. The hash value should be a village of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_VILLAGE "village"
+/**
+ * GEOCLUE_LANDMARK_KEY_SUBURB:
+ *
+ * A key for landmark hashtables. The hash value should be a suburb of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_SUBURB "suburb"
+/**
+ * GEOCLUE_LANDMARK_KEY_POSTCODE:
+ *
+ * A key for landmark hashtables. The hash value should be a postcode of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_POSTCODE "postcode"
+/**
+ * GEOCLUE_LANDMARK_KEY_CITY:
+ *
+ * A key for landmark hashtables. The hash value should be a city of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_CITY "city"
+/**
+ * GEOCLUE_LANDMARK_KEY_COUNTY:
+ *
+ * A key for landmark hashtables. The hash value should be a county of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_COUNTY "county"
+/**
+ * GEOCLUE_LANDMARK_KEY_ICON:
+ *
+ * A key for landmark hashtables. The hash value should be an icon path of a landmark.
+ */
+#define GEOCLUE_LANDMARK_KEY_ICON "icon"
+/**
+ * GEOCLUE_LANDMARK_KEY_COUNTRY:
+ *
+ * A key for landmark hashtables. The hash value should be a name of a country.
+ */
+#define GEOCLUE_LANDMARK_KEY_COUNTRY GEOCLUE_ADDRESS_KEY_COUNTRY
+/**
+ * GEOCLUE_LANDMARK_KEY_REGION:
+ *
+ * A key for landmark hashtables. The hash value should be a name of an
+ * administrative region of a nation, e.g. province or
+ * US state.
+ */
+#define GEOCLUE_LANDMARK_KEY_REGION GEOCLUE_ADDRESS_KEY_REGION
+/**
+ * GEOCLUE_LANDMARK_KEY_LOCALITY:
+ *
+ * A key for landmark hashtables. The hash value should be a name of a town
+ * or city.
+ */
+#define GEOCLUE_LANDMARK_KEY_LOCALITY GEOCLUE_ADDRESS_KEY_LOCALITY
+/**
+ * GEOCLUE_LANDMARK_KEY_AREA:
+ *
+ * A key for landmark hashtables. The hash value should be a name of an
+ * area, such as neighborhood or campus.
+ */
+#define GEOCLUE_LANDMARK_KEY_AREA GEOCLUE_ADDRESS_KEY_AREA
+/**
+ * GEOCLUE_LANDMARK_KEY_POSTALCODE:
+ *
+ * A key for landmark hashtables. The hash value should be a code used for
+ * postal delivery.
+ */
+#define GEOCLUE_LANDMARK_KEY_POSTALCODE GEOCLUE_ADDRESS_KEY_POSTALCODE
+/**
+ * GEOCLUE_LANDMARK_KEY_STREET:
+ *
+ * A key for landmark hashtables. The hash value should be a partial or full street
+ * address.
+ */
+#define GEOCLUE_LANDMARK_KEY_STREET GEOCLUE_ADDRESS_KEY_STREET
+
+
+/**
+ * GeoclueResourceFlags:
+ *
+ * bitfield that represents a set of physical resources.
+ *
+ **/
+typedef enum _GeoclueResourceFlags {
+ GEOCLUE_RESOURCE_NONE = 0,
+ GEOCLUE_RESOURCE_NETWORK = 1 << 0,
+ GEOCLUE_RESOURCE_CELL = 1 << 1,
+ GEOCLUE_RESOURCE_GPS = 1 << 2,
+
+ GEOCLUE_RESOURCE_ALL = (1 << 10) - 1
+} GeoclueResourceFlags;
+
+
+/**
+ * GeoclueNetworkStatus:
+ *
+ * Enumeration for current network status.
+ *
+ **/
+typedef enum {
+ GEOCLUE_CONNECTIVITY_UNKNOWN,
+ GEOCLUE_CONNECTIVITY_OFFLINE,
+ GEOCLUE_CONNECTIVITY_ACQUIRING,
+ GEOCLUE_CONNECTIVITY_ONLINE,
+} GeoclueNetworkStatus;
+
+
+
+void geoclue_types_init (void);
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-velocity.c - Client API for accessing GcIfaceVelocity
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * SECTION:geoclue-velocity
+ * @short_description: Geoclue velocity client API
+ *
+ * #GeoclueVelocity contains velocity-related methods and signals.
+ * It is part of the Geoclue public C client API which uses D-Bus
+ * to communicate with the actual provider.
+ *
+ * After a #GeoclueVelocity is created with
+ * geoclue_velocity_new(), the
+ * geoclue_velocity_get_velocity() method and the VelocityChanged-signal
+ * can be used to obtain the current velocity.
+ */
+
+#include <geoclue/geoclue-velocity.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include "gc-iface-velocity-bindings.h"
+
+typedef struct _GeoclueVelocityPrivate {
+ int dummy;
+} GeoclueVelocityPrivate;
+
+enum {
+ VELOCITY_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVASTE ((o), GEOCLUE_TYPE_VELOCITY, GeoclueVelocityPrivate))
+
+G_DEFINE_TYPE (GeoclueVelocity, geoclue_velocity, GEOCLUE_TYPE_PROVIDER);
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_velocity_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ G_OBJECT_CLASS (geoclue_velocity_parent_class)->dispose (object);
+}
+
+static void
+velocity_changed (DBusGProxy *proxy,
+ int fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueVelocity *velocity)
+{
+ g_signal_emit (velocity, signals[VELOCITY_CHANGED], 0, fields,
+ timestamp, speed, direction, climb);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object;
+ GeoclueProvider *provider;
+
+ object = G_OBJECT_CLASS (geoclue_velocity_parent_class)->constructor
+ (type, n_props, props);
+ provider = GEOCLUE_PROVIDER (object);
+
+ dbus_g_proxy_add_signal (provider->proxy, "VelocityChanged",
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (provider->proxy, "VelocityChanged",
+ G_CALLBACK (velocity_changed),
+ object, NULL);
+
+ return object;
+}
+
+static void
+geoclue_velocity_class_init (GeoclueVelocityClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+ o_class->constructor = constructor;
+
+ g_type_class_add_private (klass, sizeof (GeoclueVelocityPrivate));
+
+ /**
+ * GeoclueVelocity::velocity-changed:
+ * @velocity: the #GeoclueVelocity object emitting the signal
+ * @fields: A #GeoclueVelocityFields bitfield representing the validity of the velocity values
+ * @timestamp: Time of velocity measurement (Unix timestamp)
+ * @speed: horizontal speed
+ * @direction: horizontal direction (bearing)
+ * @climb: vertical speed
+ *
+ * The geoclue-changed signal is emitted each time the velocity changes.
+ *
+ * Note that not all providers support signals.
+ */
+ signals[VELOCITY_CHANGED] = g_signal_new ("velocity-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GeoclueVelocityClass, velocity_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE,
+ G_TYPE_NONE, 5,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE);
+}
+
+/**
+ * geoclue_velocity_new:
+ * @service: D-Bus service name
+ * @path: D-Bus path name
+ *
+ * Creates a #GeoclueVelocity with given D-Bus service name and path.
+ *
+ * Return value: Pointer to a new #GeoclueVelocity
+ */
+static void
+geoclue_velocity_init (GeoclueVelocity *velocity)
+{
+}
+
+GeoclueVelocity *
+geoclue_velocity_new (const char *service,
+ const char *path)
+{
+ return g_object_new (GEOCLUE_TYPE_VELOCITY,
+ "service", service,
+ "path", path,
+ "interface", GEOCLUE_VELOCITY_INTERFACE_NAME,
+ NULL);
+}
+
+/**
+ * geoclue_velocity_get_velocity:
+ * @velocity: A #GeoclueVelocity object
+ * @timestamp: Pointer to returned time of velocity measurement (unix timestamp) or %NULL
+ * @speed: Pointer to returned horizontal speed or %NULL
+ * @direction: Pointer to returned horizontal direction (bearing) or %NULL
+ * @climb: Pointer to returned vertical speed or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Obtains the current velocity. @timestamp will contain the time of
+ * the actual velocity measurement.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeoclueVelocityFields bitfield representing the
+ * validity of the velocity values.
+ */
+GeoclueVelocityFields
+geoclue_velocity_get_velocity (GeoclueVelocity *velocity,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (velocity);
+ double sp, di, cl;
+ int ts, fields;
+
+ if (!org_freedesktop_Geoclue_Velocity_get_velocity (provider->proxy,
+ &fields, &ts,
+ &sp, &di, &cl,
+ error)) {
+ return GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (speed != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_SPEED)) {
+ *speed = sp;
+ }
+
+ if (direction != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION)) {
+ *direction = di;
+ }
+
+ if (climb != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)) {
+ *climb = cl;
+ }
+
+ return fields;
+}
+
+/**
+ * geoclue_velocity_get_last_velocity:
+ * @velocity: A #GeoclueVelocity object
+ * @timestamp: Pointer to returned time of velocity measurement (unix timestamp) or %NULL
+ * @speed: Pointer to returned horizontal speed or %NULL
+ * @direction: Pointer to returned horizontal direction (bearing) or %NULL
+ * @climb: Pointer to returned vertical speed or %NULL
+ * @error: Pointer to returned #GError or %NULL
+ *
+ * Obtains the last velocity. @timestamp will contain the time of
+ * the actual velocity measurement.
+ *
+ * If the caller is not interested in some values, the pointers can be
+ * left %NULL.
+ *
+ * Return value: A #GeoclueVelocityFields bitfield representing the
+ * validity of the velocity values.
+ */
+GeoclueVelocityFields
+geoclue_velocity_get_last_velocity (GeoclueVelocity *velocity,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (velocity);
+ double sp, di, cl;
+ int ts, fields;
+
+ if (!org_freedesktop_Geoclue_Velocity_get_last_velocity (provider->proxy,
+ &fields, &ts,
+ &sp, &di, &cl,
+ error)) {
+ return GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+
+ if (timestamp != NULL) {
+ *timestamp = ts;
+ }
+
+ if (speed != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_SPEED)) {
+ *speed = sp;
+ }
+
+ if (direction != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION)) {
+ *direction = di;
+ }
+
+ if (climb != NULL && (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)) {
+ *climb = cl;
+ }
+
+ return fields;
+}
+
+typedef struct _GeoclueVelocityAsyncData {
+ GeoclueVelocity *velocity;
+ GCallback callback;
+ gpointer userdata;
+} GeoclueVelocityAsyncData;
+
+static void
+get_velocity_async_callback (DBusGProxy *proxy,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GError *error,
+ GeoclueVelocityAsyncData *data)
+{
+ (*(GeoclueVelocityCallback)data->callback) (data->velocity,
+ fields,
+ timestamp,
+ speed,
+ direction,
+ climb,
+ error,
+ data->userdata);
+ g_free (data);
+}
+
+/**
+ * GeoclueVelocityCallback:
+ * @velocity: A #GeoclueVelocity object
+ * @fields: A #GeoclueVelocityFields bitfield representing the validity of the velocity values
+ * @timestamp: Time of velocity measurement (unix timestamp)
+ * @speed: Horizontal speed
+ * @direction: Horizontal direction (bearing)
+ * @climb: Vertical speed
+ * @error: Error as #GError (may be %NULL)
+ * @userdata: User data pointer set in geoclue_velocity_get_velocity_async()
+ *
+ * Callback function for geoclue_velocity_get_velocity_async().
+ */
+
+/**
+ * geoclue_velocity_get_velocity_async:
+ * @velocity: A #GeoclueVelocity object
+ * @callback: A #GeoclueVelocityCallback function that should be called when return values are available
+ * @userdata: pointer for user specified data
+ *
+ * Function returns (essentially) immediately and calls @callback when current velocity
+ * is available or when D-Bus timeouts.
+ */
+void
+geoclue_velocity_get_velocity_async (GeoclueVelocity *velocity,
+ GeoclueVelocityCallback callback,
+ gpointer userdata)
+{
+ GeoclueProvider *provider = GEOCLUE_PROVIDER (velocity);
+ GeoclueVelocityAsyncData *data;
+
+ data = g_new (GeoclueVelocityAsyncData, 1);
+ data->velocity = velocity;
+ data->callback = G_CALLBACK (callback);
+ data->userdata = userdata;
+
+ org_freedesktop_Geoclue_Velocity_get_velocity_async
+ (provider->proxy,
+ (org_freedesktop_Geoclue_Velocity_get_velocity_reply)get_velocity_async_callback,
+ data);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-velocity.h -
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_VELOCITY_H
+#define _GEOCLUE_VELOCITY_H
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_VELOCITY (geoclue_velocity_get_type ())
+#define GEOCLUE_VELOCITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_VELOCITY, GeoclueVelocity))
+#define GEOCLUE_IS_VELOCITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_VELOCITY))
+
+#define GEOCLUE_VELOCITY_INTERFACE_NAME "org.freedesktop.Geoclue.Velocity"
+
+typedef struct _GeoclueVelocity {
+ GeoclueProvider provider;
+} GeoclueVelocity;
+
+typedef struct _GeoclueVelocityClass {
+ GeoclueProviderClass provider_class;
+
+ void (* velocity_changed) (GeoclueVelocity *velocity,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb);
+} GeoclueVelocityClass;
+
+GType geoclue_velocity_get_type (void);
+
+GeoclueVelocity *geoclue_velocity_new (const char *service,
+ const char *path);
+
+GeoclueVelocityFields geoclue_velocity_get_velocity (GeoclueVelocity *velocity,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error);
+
+GeoclueVelocityFields geoclue_velocity_get_last_velocity (GeoclueVelocity *velocity,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error);
+
+typedef void (*GeoclueVelocityCallback) (GeoclueVelocity *velocity,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GError *error,
+ gpointer userdata);
+
+void geoclue_velocity_get_velocity_async (GeoclueVelocity *velocity,
+ GeoclueVelocityCallback callback,
+ gpointer userdata);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+# -*- mode: makefile -*-
+
+####################################
+# Everything below here is generic #
+####################################
+
+if GTK_DOC_USE_LIBTOOL
+GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+GTKDOC_RUN = $(LIBTOOL) --mode=execute
+else
+GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+GTKDOC_RUN =
+endif
+
+# We set GPATH here; this gives us semantics for GNU make
+# which are more like other make's VPATH, when it comes to
+# whether a source that is a target of one rule is then
+# searched for in VPATH/GPATH.
+#
+GPATH = $(srcdir)
+
+TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
+
+EXTRA_DIST = \
+ $(content_files) \
+ $(HTML_IMAGES) \
+ $(DOC_MAIN_SGML_FILE) \
+ $(DOC_MODULE)-sections.txt \
+ $(DOC_MODULE)-overrides.txt
+
+DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \
+ pdf-build.stamp \
+ $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp \
+ $(srcdir)/pdf.stamp
+
+SCANOBJ_FILES = \
+ $(DOC_MODULE).args \
+ $(DOC_MODULE).hierarchy \
+ $(DOC_MODULE).interfaces \
+ $(DOC_MODULE).prerequisites \
+ $(DOC_MODULE).signals
+
+REPORT_FILES = \
+ $(DOC_MODULE)-undocumented.txt \
+ $(DOC_MODULE)-undeclared.txt \
+ $(DOC_MODULE)-unused.txt
+
+CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS)
+
+if ENABLE_GTK_DOC
+if GTK_DOC_BUILD_HTML
+HTML_BUILD_STAMP=html-build.stamp
+else
+HTML_BUILD_STAMP=
+endif
+if GTK_DOC_BUILD_PDF
+PDF_BUILD_STAMP=pdf-build.stamp
+else
+PDF_BUILD_STAMP=
+endif
+
+all-local: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+else
+all-local:
+endif
+
+docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+
+$(REPORT_FILES): sgml-build.stamp
+
+#### scan ####
+
+scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB)
+ @echo 'gtk-doc: Scanning header files'
+ @-chmod -R u+w $(srcdir)
+ @cd $(srcdir) && \
+ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
+ @if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \
+ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
+ else \
+ cd $(srcdir) ; \
+ for i in $(SCANOBJ_FILES) ; do \
+ test -f $$i || touch $$i ; \
+ done \
+ fi
+ @touch scan-build.stamp
+
+$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
+ @true
+
+#### templates ####
+
+tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt
+ @echo 'gtk-doc: Rebuilding template files'
+ @-chmod -R u+w $(srcdir)
+ @cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS)
+ @touch tmpl-build.stamp
+
+tmpl.stamp: tmpl-build.stamp
+ @true
+
+$(srcdir)/tmpl/*.sgml:
+ @true
+
+#### xml ####
+
+sgml-build.stamp: tmpl.stamp $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files)
+ @echo 'gtk-doc: Building XML'
+ @-chmod -R u+w $(srcdir)
+ @cd $(srcdir) && \
+ gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
+ @touch sgml-build.stamp
+
+sgml.stamp: sgml-build.stamp
+ @true
+
+#### html ####
+
+html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
+ @echo 'gtk-doc: Building HTML'
+ @-chmod -R u+w $(srcdir)
+ @rm -rf $(srcdir)/html
+ @mkdir $(srcdir)/html
+ @mkhtml_options=""; \
+ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \
+ if test "$(?)" = "0"; then \
+ mkhtml_options=--path="$(srcdir)"; \
+ fi; \
+ cd $(srcdir)/html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+ @test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
+ @echo 'gtk-doc: Fixing cross-references'
+ @cd $(srcdir) && gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
+ @touch html-build.stamp
+
+#### pdf ####
+
+pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
+ @echo 'gtk-doc: Building PDF'
+ @-chmod -R u+w $(srcdir)
+ @rm -rf $(srcdir)/$(DOC_MODULE).pdf
+ @mkpdf_imgdirs=""; \
+ if test "x$(HTML_IMAGES)" != "x"; then \
+ for img in $(HTML_IMAGES); do \
+ part=`dirname $$img`; \
+ echo $$mkpdf_imgdirs | grep >/dev/null "\-\-imgdir=$$part "; \
+ if test $$? != 0; then \
+ mkpdf_imgdirs="$$mkpdf_imgdirs --imgdir=$$part"; \
+ fi; \
+ done; \
+ fi; \
+ cd $(srcdir) && gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_imgdirs $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS)
+ @touch pdf-build.stamp
+
+##############
+
+clean-local:
+ rm -f *~ *.bak
+ rm -rf .libs
+
+distclean-local:
+ cd $(srcdir) && \
+ rm -rf xml $(REPORT_FILES) $(DOC_MODULE).pdf \
+ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
+
+maintainer-clean-local: clean
+ cd $(srcdir) && rm -rf xml html
+
+install-data-local:
+ @installfiles=`echo $(srcdir)/html/*`; \
+ if test "$$installfiles" = '$(srcdir)/html/*'; \
+ then echo '-- Nothing to install' ; \
+ else \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ $(mkinstalldirs) $${installdir} ; \
+ for i in $$installfiles; do \
+ echo '-- Installing '$$i ; \
+ $(INSTALL_DATA) $$i $${installdir}; \
+ done; \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \
+ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \
+ mv -f $${installdir}/$(DOC_MODULE).devhelp \
+ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp; \
+ fi; \
+ $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \
+ fi
+
+uninstall-local:
+ @if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ rm -rf $${installdir}
+
+#
+# Require gtk-doc when making dist
+#
+if ENABLE_GTK_DOC
+dist-check-gtkdoc:
+else
+dist-check-gtkdoc:
+ @echo "*** gtk-doc must be installed and enabled in order to make dist"
+ @false
+endif
+
+dist-hook: dist-check-gtkdoc dist-hook-local
+ mkdir $(distdir)/tmpl
+ mkdir $(distdir)/html
+ -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl
+ cp $(srcdir)/html/* $(distdir)/html
+ -cp $(srcdir)/$(DOC_MODULE).pdf $(distdir)/
+ -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/
+ -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/
+ cd $(distdir) && rm -f $(DISTCLEANFILES)
+ $(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html
+
+.PHONY : dist-hook-local docs
--- /dev/null
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+%.xml: %-full.xml
+ $(XSLT) -o $@ $(top_srcdir)/docs/tools/spec-strip-docs.xsl $<
+
+noinst_DATA = \
+ gc-iface-geoclue.xml \
+ gc-iface-position.xml \
+ gc-iface-position-ext.xml \
+ gc-iface-nmea.xml \
+ gc-iface-address.xml \
+ gc-iface-geocode.xml \
+ gc-iface-master.xml \
+ gc-iface-master-client.xml \
+ gc-iface-reverse-geocode.xml \
+ gc-iface-velocity.xml \
+ gc-iface-satellite.xml \
+ gc-iface-poi.xml
+
+BUILT_SOURCES = $(noinst_DATA)
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ gc-iface-geoclue-full.xml \
+ gc-iface-position-full.xml \
+ gc-iface-position-ext-full.xml \
+ gc-iface-nmea-full.xml \
+ gc-iface-address-full.xml \
+ gc-iface-geocode-full.xml \
+ gc-iface-master-full.xml \
+ gc-iface-master-client-full.xml \
+ gc-iface-reverse-geocode-full.xml \
+ gc-iface-velocity-full.xml \
+ gc-iface-satellite-full.xml \
+ gc-iface-poi-full.xml
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Address">
+ <method name="GetAddress">
+ <arg type="i" name="timestamp" direction="out" />
+
+ <arg name="address" type="a{ss}" direction="out" />
+
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <signal name="AddressChanged">
+ <arg type="i" name="timestamp" />
+ <arg type="a{ss}" name="address" />
+ <arg type="(idd)" name="accuracy" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue">
+ <doc:doc>
+ <doc:para>Geoclue interface contains methods
+ and signals common to all providers (and all providers
+ must implement at least this interface).</doc:para>
+ </doc:doc>
+
+ <method name="GetProviderInfo">
+ <arg type="s" name="Name" direction="out">
+ <doc:doc>
+ <doc:summary>The provider name</doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="Description" direction="out">
+ <doc:doc>
+ <doc:summary>Short description of the provider</doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="GetStatus">
+ <arg type="i" name="status" direction="out" >
+ <doc:doc>
+ <doc:summary>Current provider status, as GeoclueStatus</doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <signal name="StatusChanged">
+ <arg type="i" name="status" direction="out">
+ <doc:doc>
+ <doc:summary>Current provider status, as GeoclueStatus</doc:summary>
+ </doc:doc>
+ </arg>
+ </signal>
+
+ <method name="SetOptions">
+ <arg type="a{ss}" name="options" direction="in" />
+ </method>
+
+ <method name="AddReference">
+ <doc:doc>
+ <doc:description>Increase the reference count on the provider.
+ Provider may shutdown if reference count reaches zero, so
+ using AddReference()/RemoveReference is important for clients needing server
+ persistence -- basically any client that uses SetOptions() or connects to
+ signals.</doc:description>
+ </doc:doc>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+
+ <method name="RemoveReference">
+ <doc:doc>
+ <doc:description>Decrease the reference count on the provider</doc:description>
+ </doc:doc>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+ </interface>
+</node>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Geocode">
+
+ <method name="AddressToPosition">
+ <arg name="address" type="a{ss}" direction="in" />
+ <arg name="fields" type="i" direction="out" />
+ <arg name="latitude" type="d" direction="out" />
+ <arg name="longitude" type="d" direction="out" />
+ <arg name="altitude" type="d" direction="out" />
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <method name="FreeformAddressToPosition">
+ <arg name="address" type="s" direction="in" />
+ <arg name="fields" type="i" direction="out" />
+ <arg name="latitude" type="d" direction="out" />
+ <arg name="longitude" type="d" direction="out" />
+ <arg name="altitude" type="d" direction="out" />
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+ <interface name="org.freedesktop.Geoclue.MasterClient">
+ <method name="SetRequirements">
+ <arg name="accuracy_level" type="i" direction="in" />
+ <arg name="time" type="i" direction="in" />
+ <arg name="require_updates" type="b" direction="in" />
+ <arg name="allowed_resources" type="i" direction="in" />
+ </method>
+
+ <method name="AddressStart"/>
+ <method name="PositionStart"/>
+
+ <method name="GetAddressProvider">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </method>
+ <method name="GetPositionProvider">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </method>
+
+ <signal name="AddressProviderChanged">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </signal>
+ <signal name="PositionProviderChanged">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue.Master">
+ <method name="Create">
+ <arg type="o" name="path" direction="out" />
+ </method>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue.Nmea">
+ <doc:doc>
+ <doc:para>Nmea interface contains a method
+ and a signal for querying current coordinates.</doc:para>
+ </doc:doc>
+
+ <method name="GetNmea">
+ <arg type="i" name="timestamp" direction="out" />
+ <arg type="s" name="nmea_data" direction="out" />
+ </method>
+
+ <signal name="NmeaChanged">
+ <arg type="i" name="timestamp" />
+ <arg type="s" name="nmea_data" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Poi">
+
+ <method name="SearchByPosition">
+ <arg name="keyword" type="s" direction="in" />
+ <arg name="lang" type="s" direction="in" />
+ <arg name="country_code" type="s" direction="in" />
+ <arg name="limit" type="i" direction="in" />
+ <arg name="left" type="d" direction="in" />
+ <arg name="top" type="d" direction="in" />
+ <arg name="right" type="d" direction="in" />
+ <arg name="bottom" type="d" direction="in" />
+ <arg name="count" type="i" direction="out" />
+ <arg name="landmark" type="a(iiddddddsssssssssss)" direction="out" />
+ </method>
+
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue.PositionExt">
+ <doc:doc>
+ <doc:para>Position / Velocity interface contains a method
+ and a signal for querying current coordinates.</doc:para>
+ </doc:doc>
+
+ <method name="GetPosition">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+
+ <arg type="d" name="latitude" direction="out" />
+ <arg type="d" name="longitude" direction="out" />
+ <arg type="d" name="altitude" direction="out" />
+
+ <arg type="d" name="speed" direction="out" />
+ <arg type="d" name="direction" direction="out" />
+ <arg type="d" name="climb" direction="out" />
+
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <method name="GetLastPosition">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+
+ <arg type="d" name="latitude" direction="out" />
+ <arg type="d" name="longitude" direction="out" />
+ <arg type="d" name="altitude" direction="out" />
+
+ <arg type="d" name="speed" direction="out" />
+ <arg type="d" name="direction" direction="out" />
+ <arg type="d" name="climb" direction="out" />
+
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <signal name="PositionChanged">
+ <arg type="i" name="fields" />
+ <arg type="i" name="timestamp" />
+ <arg type="d" name="latitude" />
+ <arg type="d" name="longitude" />
+ <arg type="d" name="altitude" />
+ <arg type="d" name="speed" />
+ <arg type="d" name="direction" />
+ <arg type="d" name="climb" />
+ <arg type="(idd)" name="accuracy" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.Geoclue.Position">
+ <doc:doc>
+ <doc:para>Position interface contains a method
+ and a signal for querying current coordinates.</doc:para>
+ </doc:doc>
+
+ <method name="GetPosition">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+
+ <arg type="d" name="latitude" direction="out" />
+ <arg type="d" name="longitude" direction="out" />
+ <arg type="d" name="altitude" direction="out" />
+
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <method name="GetLastPosition">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+
+ <arg type="d" name="latitude" direction="out" />
+ <arg type="d" name="longitude" direction="out" />
+ <arg type="d" name="altitude" direction="out" />
+
+ <arg name="accuracy" type="(idd)" direction="out" />
+ </method>
+
+ <signal name="PositionChanged">
+ <arg type="i" name="fields" />
+ <arg type="i" name="timestamp" />
+ <arg type="d" name="latitude" />
+ <arg type="d" name="longitude" />
+ <arg type="d" name="altitude" />
+
+ <arg type="(idd)" name="accuracy" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.ReverseGeocode">
+ <method name="PositionToAddress">
+ <arg name="latitude" type="d" direction="in" />
+ <arg name="longitude" type="d" direction="in" />
+ <arg name="position_accuracy" type="(idd)" direction="in" />
+
+ <arg type="a{ss}" name="address" direction="out" />
+ <arg name="address_accuracy" type="(idd)" direction="out" />
+ </method>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Satellite">
+ <method name="GetSatellite">
+ <arg type="i" name="timestamp" direction="out" />
+ <arg type="i" name="satellite_used" direction="out" />
+ <arg type="i" name="satellite_visible" direction="out" />
+ <arg type="ai" name="used_prn" direction="out" />
+ <arg type="a(iiii)" name="sat_info" direction="out" />
+ </method>
+
+ <method name="GetLastSatellite">
+ <arg type="i" name="timestamp" direction="out" />
+ <arg type="i" name="satellite_used" direction="out" />
+ <arg type="i" name="satellite_visible" direction="out" />
+ <arg type="ai" name="used_prn" direction="out" />
+ <arg type="a(iiii)" name="sat_info" direction="out" />
+ </method>
+
+ <signal name="SatelliteChanged">
+ <arg type="i" name="timestamp" />
+ <arg type="i" name="satellite_used" />
+ <arg type="i" name="satellite_visible" />
+ <arg type="ai" name="used_prn" />
+ <arg type="a(iiii)" name="sat_info" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Velocity">
+ <method name="GetVelocity">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+ <arg type="d" name="speed" direction="out" />
+ <arg type="d" name="direction" direction="out" />
+ <arg type="d" name="climb" direction="out" />
+ </method>
+
+ <method name="GetLastVelocity">
+ <arg type="i" name="fields" direction="out" />
+ <arg type="i" name="timestamp" direction="out" />
+ <arg type="d" name="speed" direction="out" />
+ <arg type="d" name="direction" direction="out" />
+ <arg type="d" name="climb" direction="out" />
+ </method>
+
+ <signal name="VelocityChanged">
+ <arg type="i" name="fields" />
+ <arg type="i" name="timestamp" />
+ <arg type="d" name="speed" />
+ <arg type="d" name="direction" />
+ <arg type="d" name="climb" />
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+#sbs-git:slp/pkgs/g/geoclue geoclue 0.12.0 607dc26233fecdf2370e5a0b5eab4031f979fc0a
+Name: geoclue
+Summary: Geoinformation service
+Version: 0.12.0_28
+Release: 0
+Group: TO_BE/FILLED_IN
+License: TO BE FILLED IN
+Source0: geoclue-%{version}.tar.gz
+BuildRequires: which
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(gconf-2.0)
+BuildRequires: pkgconfig(libsoup-2.4)
+BuildRequires: pkgconfig(libxslt)
+
+
+%description
+Geographic information framework GeoClue provides applications access to various geographical information
+ sources using a D-Bus API or a C library.
+ .
+ This package contains the master server for GeoClue.
+
+%package -n libgeoclue
+Summary: C API for GeoClue
+Group: TO_BE/FILLED
+Requires: %{name} = %{version}-%{release}
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description -n libgeoclue
+libgeoclue is a convenience wrapper for the GeoClue service, and
+the recommended way to use GeoClue in the C language.
+
+%package -n libgeoclue-devel
+Summary: C API for GeoClue (development files)
+Group: TO_BE/FILLED
+Requires: libgeoclue = %{version}-%{release}
+
+%description -n libgeoclue-devel
+libgeoclue is a convenience wrapper for the GeoClue service, and
+the recommended way to use GeoClue in the C language.
+
+%package -n geoclue-nominatim
+Summary: Geocode server for GeoClue (OpenStreetMap)
+Group: TO_BE/FILLED
+Requires: %{name} = %{version}-%{release}
+
+%description -n geoclue-nominatim
+GeoClue provides applications access to various geographical information
+sources using a D-Bus API or a C library.
+.
+This package provides a tool to search osm data by name and address and to generate synthetic addresses of osm points (reverse geocoding)
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+export CFLAGS+=" -Wall -g -fPIC"
+export LDFLAGS+=" -Wl,-z,defs -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--hash-style=both"
+
+./autogen.sh
+./configure --disable-static --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-system-bus=yes --disable-gypsy --disable-lbs --disable-xps
+
+#make %{?jobs:-j%jobs}
+make
+
+%install
+rm -rf %{buildroot}
+%make_install
+rm -rf %{buildroot}/usr/bin/geoclue-test-gui
+
+
+%post -n libgeoclue -p /sbin/ldconfig
+
+%postun -n libgeoclue -p /sbin/ldconfig
+
+%files
+/usr/libexec/geoclue-master
+/usr/share/dbus-1/services/org.freedesktop.Geoclue.Master.service
+
+%files -n libgeoclue
+%manifest libgeoclue.manifest
+/usr/lib/libgeoclue.so*
+
+%files -n libgeoclue-devel
+/usr/include/*
+/usr/lib/pkgconfig/*
+
+%files -n geoclue-nominatim
+/usr/share/dbus-1/services/org.freedesktop.Geoclue.Providers.Nominatim.service
+/usr/share/geoclue-providers/geoclue-nominatim.provider
+/usr/libexec/geoclue-nominatim
--- /dev/null
+SUBDIRS = $(PROVIDER_SUBDIRS)
+
+DIST_SUBDIRS = $(PROVIDER_SUBDIRS) $(NO_BUILD_PROVIDERS)
--- /dev/null
+libexec_PROGRAMS = geoclue-example
+
+geoclue_example_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_example_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_example_SOURCES = \
+ geoclue-example.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-example.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Example.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-example.c - Example provider which doesn't do anything.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+} GeoclueExample;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueExampleClass;
+
+#define GEOCLUE_TYPE_EXAMPLE (geoclue_example_get_type ())
+#define GEOCLUE_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_EXAMPLE, GeoclueExample))
+
+static void geoclue_example_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueExample, geoclue_example, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_example_position_init))
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+print_option (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ g_print (" %s - %s\n", key, value);
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ g_print ("Options received---\n");
+ g_hash_table_foreach (options, print_option, NULL);
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueExample *example = GEOCLUE_EXAMPLE (provider);
+
+ g_main_loop_quit (example->loop);
+}
+
+static void
+geoclue_example_class_init (GeoclueExampleClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_example_init (GeoclueExample *example)
+{
+ gc_provider_set_details (GC_PROVIDER (example),
+ "org.freedesktop.Geoclue.Providers.Example",
+ "/org/freedesktop/Geoclue/Providers/Example",
+ "Example", "Example provider");
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ *timestamp = time (NULL);
+
+ /* We're not emitting location details here because we don't want
+ geoclue to accidently use this as a source */
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ return TRUE;
+}
+
+static void
+geoclue_example_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+emit_position_signal (gpointer data)
+{
+ GeoclueExample *example = data;
+ GeoclueAccuracy *accuracy;
+
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (example),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL), 0.0, 0.0, 0.0, accuracy);
+
+ geoclue_accuracy_free (accuracy);
+
+ return TRUE;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueExample *example;
+
+ g_type_init ();
+
+ example = g_object_new (GEOCLUE_TYPE_EXAMPLE, NULL);
+
+ g_timeout_add (5000, emit_position_signal, example);
+
+ example->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (example->loop);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Example Provider
+Service=org.freedesktop.Geoclue.Providers.Example
+Path=/org/freedesktop/Geoclue/Providers/Example
+Interfaces=org.freedesktop.Geoclue.Position
+Provides=ProvidesUpdates
+Accuracy=None
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Example
+Exec=@libexecdir@/geoclue-example
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-geonames
+
+NOINST_H_FILES = \
+ geoclue-geonames.h
+
+geoclue_geonames_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-geonames.c
+
+geoclue_geonames_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_geonames_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-geonames.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Geonames.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-geonames.c - A geonames.org-based "Geocode" and
+ * "Reverse geocode" provider
+ *
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/*
+ * The used web service APIs are documented at
+ * http://www.geonames.org/export/
+ *
+ * Geonames currently does not support street level geocoding. There
+ * is a street level reverse geocoder in beta, but it's US only.
+ * http://www.geonames.org/export/reverse-geocoding.html
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <dbus/dbus-glib-bindings.h>
+
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-address-details.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-geocode.h>
+#include <geoclue/gc-iface-reverse-geocode.h>
+#include "geoclue-geonames.h"
+
+
+#define GEOCLUE_GEONAMES_DBUS_SERVICE "org.freedesktop.Geoclue.Providers.Geonames"
+#define GEOCLUE_GEONAMES_DBUS_PATH "/org/freedesktop/Geoclue/Providers/Geonames"
+
+#define REV_GEOCODE_STREET_URL "http://ws.geonames.org/findNearestAddress"
+#define REV_GEOCODE_PLACE_URL "http://ws.geonames.org/findNearby"
+#define GEOCODE_PLACE_URL "http://ws.geonames.org/search"
+#define GEOCODE_POSTALCODE_URL "http://ws.geonames.org/postalCodeSearch"
+
+#define POSTALCODE_LAT "//geonames/code/lat"
+#define POSTALCODE_LON "//geonames/code/lng"
+
+#define GEONAME_LAT "//geonames/geoname/lat"
+#define GEONAME_LON "//geonames/geoname/lng"
+#define GEONAME_NAME "//geonames/geoname/name"
+#define GEONAME_COUNTRY "//geonames/geoname/countryName"
+#define GEONAME_ADMIN1 "//geonames/geoname/adminName1"
+#define GEONAME_COUNTRYCODE "//geonames/geoname/countryCode"
+#define GEONAME_FEATURE_CLASS "//geonames/geoname/fcl"
+
+#define ADDRESS_STREETNO "//geonames/address/streetNumber"
+#define ADDRESS_STREET "//geonames/address/street"
+#define ADDRESS_POSTALCODE "//geonames/address/postalcode"
+#define ADDRESS_ADMIN2 "//geonames/address/adminName2"
+#define ADDRESS_ADMIN1 "//geonames/address/adminName1"
+#define ADDRESS_COUNTRY "//geonames/geoname/countryName"
+#define ADDRESS_COUNTRYCODE "//geonames/geoname/countryCode"
+
+
+static void geoclue_geonames_init (GeoclueGeonames *obj);
+static void geoclue_geonames_geocode_init (GcIfaceGeocodeClass *iface);
+static void geoclue_geonames_reverse_geocode_init (GcIfaceReverseGeocodeClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGeonames, geoclue_geonames, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_GEOCODE,
+ geoclue_geonames_geocode_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_REVERSE_GEOCODE,
+ geoclue_geonames_reverse_geocode_init))
+
+
+/* Geoclue interface implementation */
+
+static gboolean
+geoclue_geonames_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assumption that we are available so long as the
+ providers requirements are met: ie network is up */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGeonames *obj = GEOCLUE_GEONAMES (provider);
+
+ g_main_loop_quit (obj->loop);
+}
+
+
+/* Geocode interface implementation */
+
+static gboolean
+geoclue_geonames_address_to_position (GcIfaceGeocode *iface,
+ GHashTable *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGeonames *obj = GEOCLUE_GEONAMES (iface);
+ gchar *countrycode, *locality, *postalcode;
+
+ countrycode = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ locality = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY);
+ postalcode = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE);
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ if (countrycode && postalcode) {
+ if (!gc_web_service_query (obj->postalcode_geocoder, error,
+ "postalcode", postalcode,
+ "country", countrycode,
+ "maxRows", "1",
+ "style", "FULL",
+ (char *)0)) {
+ return FALSE;
+ }
+ if (gc_web_service_get_double (obj->postalcode_geocoder,
+ latitude, POSTALCODE_LAT) &&
+ gc_web_service_get_double (obj->postalcode_geocoder,
+ longitude, POSTALCODE_LON)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_POSTALCODE,
+ 0, 0);
+ }
+ } else if (countrycode && locality) {
+ if (!gc_web_service_query (obj->place_geocoder, error,
+ "name", locality,
+ "country", countrycode,
+ "maxRows", "1",
+ "style", "FULL",
+ (char *)0)) {
+ return FALSE;
+ }
+ if (gc_web_service_get_double (obj->place_geocoder,
+ latitude, GEONAME_LAT) &&
+ gc_web_service_get_double (obj->place_geocoder,
+ longitude, GEONAME_LON)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0, 0);
+ }
+ }
+ if (*accuracy == NULL) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ return TRUE;
+}
+
+static gboolean
+geoclue_geonames_freeform_address_to_position (GcIfaceGeocode *iface,
+ const char *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGeonames *obj = GEOCLUE_GEONAMES (iface);
+
+ if (fields) {
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ }
+
+ if (address) {
+ if (!gc_web_service_query (obj->place_geocoder, error,
+ "q", address,
+ "maxRows", "1",
+ "style", "FULL",
+ (char *)0)) {
+ return FALSE;
+ }
+ if (gc_web_service_get_double (obj->place_geocoder,
+ latitude, GEONAME_LAT) &&
+ gc_web_service_get_double (obj->place_geocoder,
+ longitude, GEONAME_LON)) {
+ if (fields) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+ if (accuracy) {
+ char *fclass = NULL;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ /* this is crude but should cover most results from geonames */
+ if (gc_web_service_get_string (obj->place_geocoder,
+ &fclass, GEONAME_FEATURE_CLASS)) {
+ if (g_strcmp0 (fclass, "A") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }else if (g_strcmp0 (fclass, "P") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ }
+ g_free (fclass);
+ }
+ *accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ }
+ }
+
+ if (accuracy && *accuracy == NULL) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ }
+ return TRUE;
+}
+
+/* ReverseGeocode interface implementation */
+
+static gboolean
+geoclue_geonames_position_to_address (GcIfaceReverseGeocode *iface,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **address,
+ GeoclueAccuracy **address_accuracy,
+ GError **error)
+{
+ GeoclueGeonames *obj = GEOCLUE_GEONAMES (iface);
+ gchar lat[G_ASCII_DTOSTR_BUF_SIZE];
+ gchar lon[G_ASCII_DTOSTR_BUF_SIZE];
+ gchar *locality = NULL;
+ gchar *region = NULL;
+ gchar *country = NULL;
+ gchar *countrycode = NULL;
+ GeoclueAccuracyLevel in_acc = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+
+ if (!address) {
+ return TRUE;
+ }
+ g_ascii_dtostr (lat, G_ASCII_DTOSTR_BUF_SIZE, latitude);
+ g_ascii_dtostr (lon, G_ASCII_DTOSTR_BUF_SIZE, longitude);
+ if (!gc_web_service_query (obj->rev_place_geocoder, error,
+ "lat", lat,
+ "lng", lon,
+ "featureCode","PPL", /* http://www.geonames.org/export/codes.html*/
+ "featureCode","PPLA",
+ "featureCode","PPLC",
+ "featureCode","PPLG",
+ "featureCode","PPLL",
+ "featureCode","PPLR",
+ "featureCode","PPLS",
+ "maxRows", "1",
+ "style", "FULL",
+ (char *)0)) {
+ return FALSE;
+ }
+
+ if (position_accuracy) {
+ geoclue_accuracy_get_details (position_accuracy, &in_acc, NULL, NULL);
+ }
+
+ *address = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_COUNTRY &&
+ gc_web_service_get_string (obj->rev_place_geocoder,
+ &countrycode, GEONAME_COUNTRYCODE)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ countrycode);
+ g_free (countrycode);
+ geoclue_address_details_set_country_from_code (*address);
+ }
+ if (!g_hash_table_lookup (*address, GEOCLUE_ADDRESS_KEY_COUNTRY) &&
+ in_acc >= GEOCLUE_ACCURACY_LEVEL_COUNTRY &&
+ gc_web_service_get_string (obj->rev_place_geocoder,
+ &country, GEONAME_COUNTRY)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ country);
+ g_free (country);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_REGION &&
+ gc_web_service_get_string (obj->rev_place_geocoder,
+ ®ion, GEONAME_ADMIN1)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_REGION,
+ region);
+ g_free (region);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_LOCALITY &&
+ gc_web_service_get_string (obj->rev_place_geocoder,
+ &locality, GEONAME_NAME)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ locality);
+ g_free (locality);
+ }
+
+ if (address_accuracy) {
+ GeoclueAccuracyLevel level = geoclue_address_details_get_accuracy_level (*address);
+ *address_accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ return TRUE;
+}
+
+static void
+geoclue_geonames_finalize (GObject *obj)
+{
+ ((GObjectClass *) geoclue_geonames_parent_class)->finalize (obj);
+}
+
+static void
+geoclue_geonames_dispose (GObject *obj)
+{
+ GeoclueGeonames *self = (GeoclueGeonames *) obj;
+
+ if (self->place_geocoder) {
+ g_object_unref (self->place_geocoder);
+ self->place_geocoder = NULL;
+ }
+
+ if (self->postalcode_geocoder) {
+ g_object_unref (self->postalcode_geocoder);
+ self->postalcode_geocoder = NULL;
+ }
+
+ if (self->rev_place_geocoder) {
+ g_object_unref (self->rev_place_geocoder);
+ self->rev_place_geocoder = NULL;
+ }
+
+ if (self->rev_street_geocoder) {
+ g_object_unref (self->rev_street_geocoder);
+ self->rev_street_geocoder = NULL;
+ }
+
+ ((GObjectClass *) geoclue_geonames_parent_class)->dispose (obj);
+}
+
+/* Initialization */
+
+static void
+geoclue_geonames_class_init (GeoclueGeonamesClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_geonames_get_status;
+
+ o_class->finalize = geoclue_geonames_finalize;
+ o_class->dispose = geoclue_geonames_dispose;
+}
+
+static void
+geoclue_geonames_init (GeoclueGeonames *obj)
+{
+ gc_provider_set_details (GC_PROVIDER (obj),
+ GEOCLUE_GEONAMES_DBUS_SERVICE,
+ GEOCLUE_GEONAMES_DBUS_PATH,
+ "Geonames", "Geonames provider");
+
+ obj->place_geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->place_geocoder,
+ GEOCODE_PLACE_URL);
+
+ obj->postalcode_geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->postalcode_geocoder,
+ GEOCODE_POSTALCODE_URL);
+
+ obj->rev_place_geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->rev_place_geocoder,
+ REV_GEOCODE_PLACE_URL);
+
+ obj->rev_street_geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->rev_street_geocoder,
+ REV_GEOCODE_STREET_URL);
+}
+
+
+static void
+geoclue_geonames_geocode_init (GcIfaceGeocodeClass *iface)
+{
+ iface->address_to_position = geoclue_geonames_address_to_position;
+ iface->freeform_address_to_position =
+ geoclue_geonames_freeform_address_to_position;
+}
+
+static void
+geoclue_geonames_reverse_geocode_init (GcIfaceReverseGeocodeClass *iface)
+{
+ iface->position_to_address = geoclue_geonames_position_to_address;
+}
+
+int
+main()
+{
+ GeoclueGeonames *obj;
+
+ g_type_init();
+ obj = g_object_new (GEOCLUE_TYPE_GEONAMES, NULL);
+ obj->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (obj->loop);
+
+ g_main_loop_unref (obj->loop);
+ g_object_unref (obj);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-geonames.h - A Geocode/ReverseGeocode provider for geonames.org
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_GEONAMES
+#define _GEOCLUE_GEONAMES
+
+#include <glib-object.h>
+#include <geoclue/gc-web-service.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_GEONAMES (geoclue_geonames_get_type ())
+
+#define GEOCLUE_GEONAMES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GEONAMES, GeoclueGeonames))
+#define GEOCLUE_GEONAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_GEONAMES, GeoclueGeonamesClass))
+#define GEOCLUE_IS_GEONAMES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GEONAMES))
+#define GEOCLUE_IS_GEONAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_GEONAMES))
+
+typedef struct _GeoclueGeonames {
+ GcProvider parent;
+ GMainLoop *loop;
+
+ GcWebService *place_geocoder;
+ GcWebService *postalcode_geocoder;
+
+ GcWebService *rev_street_geocoder;
+ GcWebService *rev_place_geocoder;
+} GeoclueGeonames;
+
+typedef struct _GeoclueGeonamesClass {
+ GcProviderClass parent_class;
+} GeoclueGeonamesClass;
+
+GType geoclue_geonames_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+[Geoclue Provider]
+Name=Geonames Provider
+Service=org.freedesktop.Geoclue.Providers.Geonames
+Path=/org/freedesktop/Geoclue/Providers/Geonames
+Requires=RequiresNetwork
+Accuracy=Postalcode
+Interfaces=org.freedesktop.Geoclue.Geocode;org.freedesktop.Geoclue.ReverseGeocode
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Geonames
+Exec=@libexecdir@/geoclue-geonames
--- /dev/null
+libexec_PROGRAMS = geoclue-gpsd
+
+geoclue_gpsd_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GPSD_CFLAGS)
+
+geoclue_gpsd_LDFLAGS = \
+ -Wl,--warn-unresolved-symbols
+
+geoclue_gpsd_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GPSD_LIBS) \
+ -lm \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gpsd_SOURCES = \
+ geoclue-gpsd.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gpsd.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gpsd.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-gpsd.c - Geoclue Position backend for gpsd
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/* TODO:
+ *
+ * call to gps_set_callback blocks for a long time if
+ * BT device is not present.
+ *
+ **/
+
+#include <config.h>
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <gps.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct gps_data_t gps_data;
+typedef struct gps_fix_t gps_fix;
+
+/* only listing used tags */
+typedef enum {
+ NMEA_NONE,
+ NMEA_GSA,
+ NMEA_GGA,
+ NMEA_GSV,
+ NMEA_RMC
+} NmeaTag;
+
+typedef struct {
+ GcProvider parent;
+
+ char *host;
+ char *port;
+
+ gps_data *gpsdata;
+
+ gps_fix *last_fix;
+
+ GeoclueStatus last_status;
+ GeocluePositionFields last_pos_fields;
+ GeoclueAccuracy *last_accuracy;
+ GeoclueVelocityFields last_velo_fields;
+
+ GMainLoop *loop;
+} GeoclueGpsd;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGpsdClass;
+
+static void geoclue_gpsd_position_init(GcIfacePositionClass * iface);
+static void geoclue_gpsd_velocity_init(GcIfaceVelocityClass * iface);
+
+#define GEOCLUE_TYPE_GPSD (geoclue_gpsd_get_type ())
+#define GEOCLUE_GPSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSD, GeoclueGpsd))
+
+G_DEFINE_TYPE_WITH_CODE(GeoclueGpsd, geoclue_gpsd, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_POSITION, geoclue_gpsd_position_init)
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_VELOCITY, geoclue_gpsd_velocity_init))
+
+static void geoclue_gpsd_stop_gpsd(GeoclueGpsd * self);
+static gboolean geoclue_gpsd_start_gpsd(GeoclueGpsd * self);
+
+/* defining global GeoclueGpsd because gpsd does not support "user_data"
+ * pointers in callbacks */
+GeoclueGpsd *gpsd;
+
+/* Geoclue interface */
+static gboolean get_status(GcIfaceGeoclue * gc, GeoclueStatus * status, GError ** error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(gc);
+
+ *status = gpsd->last_status;
+ return TRUE;
+}
+
+static void shutdown(GcProvider * provider)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(provider);
+
+ g_main_loop_quit(gpsd->loop);
+}
+
+static void geoclue_gpsd_set_status(GeoclueGpsd * self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+
+ /* make position and velocity invalid if no fix */
+ if (status != GEOCLUE_STATUS_AVAILABLE) {
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+ g_debug("status changed [%d]", status);
+ gc_iface_geoclue_emit_status_changed(GC_IFACE_GEOCLUE(self), status);
+ }
+}
+
+static gboolean set_options(GcIfaceGeoclue * gc, GHashTable * options, GError ** error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(gc);
+ char *port, *host;
+ gboolean changed = FALSE;
+
+ host = g_hash_table_lookup(options, "org.freedesktop.Geoclue.GPSHost");
+ port = g_hash_table_lookup(options, "org.freedesktop.Geoclue.GPSPort");
+
+ if (port == NULL) {
+ port = DEFAULT_GPSD_PORT;
+ }
+
+ /* new values? */
+ if (g_strcmp0(host, gpsd->host) != 0 || g_strcmp0(port, gpsd->port) != 0) {
+ changed = TRUE;
+ }
+
+ if (!changed) {
+ return TRUE;
+ }
+
+ /* update private values with new ones, restart gpsd */
+ g_free(gpsd->port);
+ gpsd->port = NULL;
+ g_free(gpsd->host);
+ gpsd->host = NULL;
+
+ geoclue_gpsd_stop_gpsd(gpsd);
+
+ if (host == NULL) {
+ return TRUE;
+ }
+
+ gpsd->port = g_strdup(port);
+ gpsd->host = g_strdup(host);
+ if (!geoclue_gpsd_start_gpsd(gpsd)) {
+ geoclue_gpsd_set_status(gpsd, GEOCLUE_STATUS_ERROR);
+ g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "Gpsd not found");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void finalize(GObject * object)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(object);
+
+ geoclue_gpsd_stop_gpsd(gpsd);
+ g_free(gpsd->last_fix);
+ geoclue_accuracy_free(gpsd->last_accuracy);
+
+ g_free(gpsd->port);
+ if (gpsd->host) {
+ g_free(gpsd->host);
+ }
+
+ ((GObjectClass *) geoclue_gpsd_parent_class)->finalize(object);
+}
+
+static void geoclue_gpsd_class_init(GeoclueGpsdClass * klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static gboolean equal_or_nan(double a, double b)
+{
+ if (isnan(a) && isnan(b)) {
+ return TRUE;
+ }
+ return a == b;
+}
+
+static void geoclue_gpsd_update_position(GeoclueGpsd * gpsd)
+{
+ if (gpsd->last_status != GEOCLUE_STATUS_AVAILABLE)
+ return;
+
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+ if (isnan(fix->time) == 0) {
+ last_fix->time = fix->time;
+ }
+ if (equal_or_nan(fix->latitude, last_fix->latitude) && equal_or_nan(fix->longitude, last_fix->longitude)
+ && equal_or_nan(fix->altitude, last_fix->altitude)) {
+ return;
+ }
+ /* save values */
+ if (fix->mode >= MODE_2D && isnan(fix->latitude) == 0) {
+ last_fix->latitude = fix->latitude;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->longitude) == 0) {
+ last_fix->longitude = fix->longitude;
+ }
+ if (fix->mode == MODE_3D && isnan(fix->altitude) == 0) {
+ last_fix->altitude = fix->altitude;
+ }
+
+ if (isnan(fix->epx) == 0) {
+ last_fix->epx = fix->epx;
+ }
+ if (isnan(fix->epy) == 0) {
+ last_fix->epy = fix->epy;
+ }
+ if (isnan(fix->epv) == 0) {
+ last_fix->epv = fix->epv;
+ }
+ geoclue_accuracy_set_details(gpsd->last_accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ sqrt(pow(last_fix->epx, 2) + pow(last_fix->epy, 2)), fix->epv);
+ gpsd->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ gpsd->last_pos_fields |= (isnan(fix->latitude)) ? 0 : GEOCLUE_POSITION_FIELDS_LATITUDE;
+ gpsd->last_pos_fields |= (isnan(fix->longitude)) ? 0 : GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ gpsd->last_pos_fields |= (isnan(fix->altitude)) ? 0 : GEOCLUE_POSITION_FIELDS_ALTITUDE;
+
+ g_debug
+ ("Update position: %lf, %lf, %lf, fields:0x%x, Accuracy level: %d, hori:%lf vert:%lf",
+ last_fix->latitude, last_fix->longitude, last_fix->altitude,
+ gpsd->last_pos_fields, GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ sqrt(pow(last_fix->epx, 2) + pow(last_fix->epy, 2)), fix->epv);
+ gc_iface_position_emit_position_changed(GC_IFACE_POSITION(gpsd),
+ gpsd->last_pos_fields,
+ (int)(last_fix->time + 0.5),
+ last_fix->latitude,
+ last_fix->longitude, last_fix->altitude, gpsd->last_accuracy);
+
+}
+
+static void geoclue_gpsd_update_velocity(GeoclueGpsd * gpsd)
+{
+ if (gpsd->last_status != GEOCLUE_STATUS_AVAILABLE)
+ return;
+
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+ if (isnan(fix->time) == 0) {
+ last_fix->time = fix->time;
+ }
+ if (equal_or_nan(fix->track, last_fix->track) && equal_or_nan(fix->speed, last_fix->speed)
+ && equal_or_nan(fix->climb, last_fix->climb)) {
+ return;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->track) == 0) {
+ last_fix->track = fix->track;
+ }
+ if (fix->mode >= MODE_2D && isnan(fix->speed) == 0) {
+ last_fix->speed = fix->speed;
+ }
+ if (fix->mode >= MODE_3D && isnan(fix->climb) == 0) {
+ last_fix->climb = fix->climb;
+ }
+
+ g_debug("Update velocity: %lf, %lf, %lf", last_fix->track, last_fix->speed, last_fix->climb);
+ gpsd->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ gpsd->last_velo_fields |= (isnan(last_fix->track)) ? 0 : GEOCLUE_VELOCITY_FIELDS_DIRECTION;
+ gpsd->last_velo_fields |= (isnan(last_fix->speed)) ? 0 : GEOCLUE_VELOCITY_FIELDS_SPEED;
+ gpsd->last_velo_fields |= (isnan(last_fix->climb)) ? 0 : GEOCLUE_VELOCITY_FIELDS_CLIMB;
+
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY(gpsd), gpsd->last_velo_fields,
+ (int)(last_fix->time + 0.5), last_fix->speed, last_fix->track, last_fix->climb);
+}
+
+static void geoclue_gpsd_update_status(GeoclueGpsd * gpsd)
+{
+ GeoclueStatus status;
+
+ /* gpsdata->online is supposedly always up-to-date */
+ if (gpsd->gpsdata->online <= 0) {
+ status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else if (gpsd->gpsdata->set & STATUS_SET) {
+ gpsd->gpsdata->set &= ~(STATUS_SET);
+ if (gpsd->gpsdata->status > 0) {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ } else {
+ status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ } else {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ return;
+ }
+
+ geoclue_gpsd_set_status(gpsd, status);
+}
+
+static void gpsd_raw_hook(gps_data * gpsdata, char *message, size_t len)
+{
+ if (gpsdata == NULL)
+ return;
+
+ geoclue_gpsd_update_status(gpsd);
+ geoclue_gpsd_update_position(gpsd);
+ geoclue_gpsd_update_velocity(gpsd);
+}
+
+static void geoclue_gpsd_stop_gpsd(GeoclueGpsd * self)
+{
+ if (self->gpsdata) {
+ gps_close(self->gpsdata);
+ self->gpsdata = NULL;
+ }
+}
+
+static gboolean geoclue_gpsd_start_gpsd(GeoclueGpsd * self)
+{
+ self->gpsdata = gps_open(self->host, self->port);
+ if (self->gpsdata) {
+ gps_stream(self->gpsdata, WATCH_ENABLE | WATCH_NEWSTYLE, NULL);
+ gps_set_raw_hook(self->gpsdata, gpsd_raw_hook);
+ return TRUE;
+ } else {
+ g_warning("gps_open() failed, is gpsd running (host=%s,port=%s)?", self->host, self->port);
+ return FALSE;
+ }
+}
+
+gboolean gpsd_poll(gpointer data)
+{
+ GeoclueGpsd *self = (GeoclueGpsd *) data;
+ if (self->gpsdata) {
+ if (gps_poll(self->gpsdata) < 0) {
+ geoclue_gpsd_set_status(self, GEOCLUE_STATUS_ERROR);
+ geoclue_gpsd_stop_gpsd(self);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void geoclue_gpsd_init(GeoclueGpsd * self)
+{
+ self->gpsdata = NULL;
+ self->last_fix = g_new0(gps_fix, 1);
+
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ self->last_accuracy = geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_provider_set_details(GC_PROVIDER(self),
+ "org.freedesktop.Geoclue.Providers.Gpsd",
+ "/org/freedesktop/Geoclue/Providers/Gpsd", "Gpsd", "Gpsd provider");
+
+ self->port = g_strdup(DEFAULT_GPSD_PORT);
+ self->host = g_strdup("localhost");
+
+ geoclue_gpsd_set_status(self, GEOCLUE_STATUS_ACQUIRING);
+ if (!geoclue_gpsd_start_gpsd(self)) {
+ geoclue_gpsd_set_status(self, GEOCLUE_STATUS_ERROR);
+ }
+}
+
+static gboolean
+get_position(GcIfacePosition * gc,
+ GeocluePositionFields * fields,
+ int *timestamp,
+ double *latitude, double *longitude, double *altitude, GeoclueAccuracy ** accuracy, GError ** error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(gc);
+
+ *timestamp = (int)(gpsd->last_fix->time + 0.5);
+ *latitude = gpsd->last_fix->latitude;
+ *longitude = gpsd->last_fix->longitude;
+ *altitude = gpsd->last_fix->altitude;
+ *fields = gpsd->last_pos_fields;
+ *accuracy = geoclue_accuracy_copy(gpsd->last_accuracy);
+
+ return TRUE;
+}
+
+static void geoclue_gpsd_position_init(GcIfacePositionClass * iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity(GcIfaceVelocity * gc,
+ GeoclueVelocityFields * fields, int *timestamp, double *speed, double *direction, double *climb, GError ** error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD(gc);
+
+ *timestamp = (int)(gpsd->last_fix->time + 0.5);
+ *speed = gpsd->last_fix->speed;
+ *direction = gpsd->last_fix->track;
+ *climb = gpsd->last_fix->climb;
+ *fields = gpsd->last_velo_fields;
+
+ return TRUE;
+}
+
+static void geoclue_gpsd_velocity_init(GcIfaceVelocityClass * iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int main(int argc, char **argv)
+{
+ g_type_init();
+
+ gpsd = g_object_new(GEOCLUE_TYPE_GPSD, NULL);
+
+ gpsd->loop = g_main_loop_new(NULL, TRUE);
+ g_timeout_add(500, gpsd_poll, (gpointer) gpsd);
+
+ g_main_loop_run(gpsd->loop);
+
+ g_main_loop_unref(gpsd->loop);
+ g_object_unref(gpsd);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=GPSd
+Service=org.freedesktop.Geoclue.Providers.Gpsd
+Path=/org/freedesktop/Geoclue/Providers/Gpsd
+Requires=RequiresGPS
+Provides=ProvidesUpdates
+Accuracy=Detailed
+Interfaces=org.freedesktop.Geoclue.Position;org.freedesktop.Geoclue.Velocity
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Gpsd
+Exec=@libexecdir@/geoclue-gpsd
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-gsmloc
+
+nodist_geoclue_gsmloc_SOURCES = \
+ ofono-marshal.c \
+ ofono-marshal.h \
+ ofono-manager-bindings.h \
+ ofono-modem-bindings.h \
+ ofono-network-registration-bindings.h \
+ ofono-network-operator-bindings.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_gsmloc_SOURCES)
+
+geoclue_gsmloc_SOURCES = \
+ mcc.h \
+ geoclue-gsmloc.c \
+ geoclue-gsmloc-ofono.c \
+ geoclue-gsmloc-ofono.h
+
+
+geoclue_gsmloc_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_gsmloc_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gsmloc.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gsmloc.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ ofono-marshal.list \
+ ofono-manager.xml \
+ ofono-modem.xml \
+ ofono-network-operator.xml \
+ ofono-network-registration.xml \
+ $(service_in_files) \
+ $(providers_DATA)
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+DISTCLEANFILES = \
+ $(service_DATA)
+
+%-bindings.h: stamp-%-bindings.h
+ @true
+stamp-%-bindings.h: %.xml
+ $(DBUS_BINDING_TOOL) --mode=glib-client $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+ofono-marshal.h: ofono-marshal.list $(GLIB_GENMARSHAL)
+ $(GLIB_GENMARSHAL) $< --header --prefix=ofono_marshal > $@
+ofono-marshal.c: ofono-marshal.list ofono-marshal.h $(GLIB_GENMARSHAL)
+ echo "#include \"ofono-marshal.h\"" > $@ \
+ && $(GLIB_GENMARSHAL) --prefix=ofono_marshal $(srcdir)/ofono-marshal.list --body >> $@
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-gsmloc-ofono.c - oFono abstraction for gsmloc provider
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "geoclue-gsmloc-ofono.h"
+
+/* generated ofono bindings */
+#include "ofono-marshal.h"
+#include "ofono-manager-bindings.h"
+#include "ofono-modem-bindings.h"
+#include "ofono-network-registration-bindings.h"
+#include "ofono-network-operator-bindings.h"
+
+G_DEFINE_TYPE (GeoclueGsmlocOfono, geoclue_gsmloc_ofono, G_TYPE_OBJECT)
+#define GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_GSMLOC_OFONO, GeoclueGsmlocOfonoPrivate))
+
+typedef struct _GeoclueGsmlocOfonoPrivate {
+ DBusGProxy *ofono_manager;
+ GList *modems;
+ gboolean available;
+} GeoclueGsmlocOfonoPrivate;
+
+enum {
+ NETWORK_DATA_CHANGED,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = {0};
+
+enum {
+ PROP_0,
+ PROP_AVAILABLE,
+};
+
+static void emit_network_data_changed (GeoclueGsmlocOfono *ofono);
+
+
+typedef struct _NetOp {
+ GeoclueGsmlocOfono *ofono;
+ DBusGProxy *proxy;
+
+ char *mcc;
+ char *mnc;
+} NetOp;
+
+typedef struct _Modem {
+ GeoclueGsmlocOfono *ofono;
+ DBusGProxy *proxy;
+ DBusGProxy *netreg_proxy;
+ GList *netops;
+
+ char *lac;
+ char *cid;
+} Modem;
+
+static gboolean
+net_op_set_mnc (NetOp *op, const char *mnc)
+{
+ if (g_strcmp0 (op->mnc, mnc) == 0) {
+ return FALSE;
+ }
+
+ g_free (op->mnc);
+ op->mnc = g_strdup (mnc);
+ return TRUE;
+}
+
+static gboolean
+net_op_set_mcc (NetOp *op, const char *mcc)
+{
+ if (g_strcmp0 (op->mcc, mcc) == 0) {
+ return FALSE;
+ }
+
+ g_free (op->mcc);
+ op->mcc = g_strdup (mcc);
+ return TRUE;
+}
+
+static void
+net_op_property_changed_cb (DBusGProxy *proxy,
+ char *name,
+ GValue *value,
+ NetOp *op)
+{
+ if (g_strcmp0 ("MobileNetworkCode", name) == 0) {
+ if (net_op_set_mnc (op, g_value_get_string (value))) {
+ emit_network_data_changed (op->ofono);
+ }
+ } else if (g_strcmp0 ("MobileCountryCode", name) == 0) {
+ if (net_op_set_mcc (op, g_value_get_string (value))) {
+ emit_network_data_changed (op->ofono);
+ }
+ }
+}
+
+static void
+net_op_free (NetOp *op)
+{
+ g_free (op->mcc);
+ g_free (op->mnc);
+
+ if (op->proxy) {
+ dbus_g_proxy_disconnect_signal (op->proxy, "PropertyChanged",
+ G_CALLBACK (net_op_property_changed_cb),
+ op);
+ g_object_unref (op->proxy);
+ }
+
+ g_slice_free (NetOp, op);
+}
+
+static gboolean
+modem_set_lac (Modem *modem, const char *lac)
+{
+ if (g_strcmp0 (modem->lac, lac) == 0) {
+ return FALSE;
+ }
+
+ g_free (modem->lac);
+ modem->lac = g_strdup (lac);
+ return TRUE;
+}
+
+static gboolean
+modem_set_cid (Modem *modem, const char *cid)
+{
+ if (g_strcmp0 (modem->cid, cid) == 0) {
+ return FALSE;
+ }
+
+ g_free (modem->cid);
+ modem->cid = g_strdup (cid);
+ return TRUE;
+}
+
+static void
+get_netop_properties_cb (DBusGProxy *proxy,
+ GHashTable *props,
+ GError *error,
+ NetOp *op)
+{
+ GValue *mnc_val, *mcc_val;
+
+ if (error) {
+ g_warning ("oFono NetworkOperator.GetProperties failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ mnc_val = g_hash_table_lookup (props, "MobileNetworkCode");
+ mcc_val = g_hash_table_lookup (props, "MobileCountryCode");
+ if (mnc_val && mcc_val) {
+ gboolean changed;
+ changed = net_op_set_mcc (op, g_value_get_string (mcc_val));
+ changed = net_op_set_mnc (op, g_value_get_string (mnc_val)) || changed;
+
+ if (changed) {
+ emit_network_data_changed (op->ofono);
+ }
+ }
+}
+
+static void
+modem_set_net_ops (Modem *modem, GPtrArray *ops)
+{
+ int i;
+ GList *list;
+
+ for (list = modem->netops; list; list = list->next) {
+ net_op_free ((NetOp*)list->data);
+ }
+ g_list_free (modem->netops);
+ modem->netops = NULL;
+
+ if (ops->len == 0) {
+ return;
+ }
+
+ for (i = 0; i < ops->len; i++) {
+ const char* op_path;
+ NetOp *op;
+
+ op_path = g_ptr_array_index (ops, i);
+ op = g_slice_new0 (NetOp);
+ op->ofono = modem->ofono;
+ op->proxy = dbus_g_proxy_new_from_proxy (modem->proxy,
+ "org.ofono.NetworkOperator",
+ op_path);
+ if (!op->proxy) {
+ g_warning ("failed to find the oFono NetworkOperator '%s'", op_path);
+ } else {
+ modem->netops = g_list_prepend (modem->netops, op);
+ org_ofono_NetworkOperator_get_properties_async (op->proxy,
+ (org_ofono_NetworkOperator_get_properties_reply)get_netop_properties_cb,
+ op);
+ dbus_g_proxy_add_signal (op->proxy,"PropertyChanged",
+ G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (op->proxy, "PropertyChanged",
+ G_CALLBACK (net_op_property_changed_cb),
+ op, NULL);
+ }
+ }
+}
+
+static void
+net_reg_get_properties_cb (DBusGProxy *proxy,
+ GHashTable *props,
+ GError *error,
+ Modem *modem)
+{
+ GValue *lac_val, *cid_val, *ops_val;
+
+ if (error) {
+ g_warning ("oFono NetworkRegistration.GetProperties failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ lac_val = g_hash_table_lookup (props, "LocationAreaCode");
+ cid_val = g_hash_table_lookup (props, "CellId");
+ ops_val = g_hash_table_lookup (props, "AvailableOperators");
+
+ if (lac_val && cid_val) {
+ gboolean changed;
+ char *str;
+
+ str = g_strdup_printf ("%u", g_value_get_uint (lac_val));
+ changed = modem_set_lac (modem, str);
+ g_free (str);
+ str = g_strdup_printf ("%u", g_value_get_uint (cid_val));
+ changed = modem_set_cid (modem, str) || changed;
+ g_free (str);
+
+ if (changed) {
+ emit_network_data_changed (modem->ofono);
+ }
+ }
+
+ if (ops_val) {
+ GPtrArray *ops;
+
+ ops = g_value_get_boxed (ops_val);
+ modem_set_net_ops (modem, ops);
+ }
+}
+
+static void
+netreg_property_changed_cb (DBusGProxy *proxy,
+ char *name,
+ GValue *value,
+ Modem *modem)
+{
+ char *str;
+
+ if (g_strcmp0 ("LocationAreaCode", name) == 0) {
+ str = g_strdup_printf ("%u", g_value_get_uint (value));
+ if (modem_set_lac (modem, str)) {
+ emit_network_data_changed (modem->ofono);
+ }
+ g_free (str);
+ } else if (g_strcmp0 ("CellId", name) == 0) {
+ str = g_strdup_printf ("%u", g_value_get_uint (value));
+ if (modem_set_cid (modem, str)) {
+ emit_network_data_changed (modem->ofono);
+ }
+ g_free (str);
+ } else if (g_strcmp0 ("AvailableOperators", name) == 0) {
+ modem_set_net_ops (modem, g_value_get_boxed (value));
+ }
+}
+
+static void
+modem_set_net_reg (Modem *modem, gboolean net_reg)
+{
+ GList *netops;
+
+ g_free (modem->cid);
+ modem->cid = NULL;
+ g_free (modem->lac);
+ modem->lac = NULL;
+
+ if (modem->netreg_proxy) {
+ dbus_g_proxy_disconnect_signal (modem->netreg_proxy, "PropertyChanged",
+ G_CALLBACK (netreg_property_changed_cb),
+ modem);
+ g_object_unref (modem->netreg_proxy);
+ modem->netreg_proxy = NULL;
+ }
+
+ for (netops = modem->netops; netops; netops = netops->next) {
+ net_op_free ((NetOp*)netops->data);
+ }
+ g_list_free (modem->netops);
+ modem->netops = NULL;
+
+ if (net_reg) {
+ modem->netreg_proxy = dbus_g_proxy_new_from_proxy (modem->proxy,
+ "org.ofono.NetworkRegistration",
+ dbus_g_proxy_get_path (modem->proxy));
+ if (!modem->netreg_proxy) {
+ g_warning ("failed to find the oFono NetworkRegistration '%s'",
+ dbus_g_proxy_get_path (modem->proxy));
+ } else {
+ org_ofono_NetworkRegistration_get_properties_async (modem->netreg_proxy,
+ (org_ofono_NetworkRegistration_get_properties_reply)net_reg_get_properties_cb,
+ modem);
+ dbus_g_proxy_add_signal (modem->netreg_proxy,"PropertyChanged",
+ G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (modem->netreg_proxy, "PropertyChanged",
+ G_CALLBACK (netreg_property_changed_cb),
+ modem, NULL);
+ }
+ }
+}
+
+static void
+modem_set_interfaces (Modem *modem, char **ifaces)
+{
+ int i = 0;
+
+ while (ifaces[i]) {
+ if (g_strcmp0 ("org.ofono.NetworkRegistration", ifaces[i]) == 0) {
+ if (!modem->netreg_proxy) {
+ modem_set_net_reg (modem, TRUE);
+ }
+ return;
+ }
+ i++;
+ }
+ modem_set_net_reg (modem, FALSE);
+}
+
+static void
+modem_property_changed_cb (DBusGProxy *proxy,
+ char *name,
+ GValue *value,
+ Modem *modem)
+{
+ if (g_strcmp0 ("Interfaces", name) == 0) {
+ modem_set_interfaces (modem, g_value_get_boxed (value));
+ emit_network_data_changed (modem->ofono);
+ }
+}
+
+static void
+modem_get_properties_cb (DBusGProxy *proxy,
+ GHashTable *props,
+ GError *error,
+ Modem *modem)
+{
+ GValue *val;
+
+ if (error) {
+ g_warning ("oFono Modem.GetProperties failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ val = g_hash_table_lookup (props, "Interfaces");
+ modem_set_interfaces (modem, g_value_get_boxed (val));
+}
+
+static void
+modem_free (Modem *modem)
+{
+ GList *netops;
+
+ g_free (modem->cid);
+ g_free (modem->lac);
+
+ if (modem->netreg_proxy) {
+ dbus_g_proxy_disconnect_signal (modem->netreg_proxy, "PropertyChanged",
+ G_CALLBACK (netreg_property_changed_cb),
+ modem);
+ g_object_unref (modem->netreg_proxy);
+ }
+
+ if (modem->proxy) {
+ dbus_g_proxy_disconnect_signal (modem->proxy, "PropertyChanged",
+ G_CALLBACK (modem_property_changed_cb),
+ modem);
+ g_object_unref (modem->proxy);
+ }
+
+ for (netops = modem->netops; netops; netops = netops->next) {
+ net_op_free ((NetOp*)netops->data);
+ }
+ g_list_free (modem->netops);
+
+ g_slice_free (Modem, modem);
+}
+
+
+static void
+emit_network_data_changed (GeoclueGsmlocOfono *ofono)
+{
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+ const char *mcc, *mnc, *lac, *cid;
+ GList *modems, *netops;
+
+ mcc = mnc = lac = cid = NULL;
+
+ /* find the first complete cell data we have */
+ for (modems = priv->modems; modems; modems = modems->next) {
+ Modem *modem = (Modem*)modems->data;
+
+ if (modem->lac && modem->cid) {
+ for (netops = modem->netops; netops; netops = netops->next) {
+ NetOp *netop = (NetOp*)netops->data;
+
+ if (netop->mnc && netop->mcc) {
+ mcc = netop->mcc;
+ mnc = netop->mnc;
+ lac = modem->lac;
+ cid = modem->cid;
+ break;
+ }
+ }
+ }
+ if (cid) {
+ break;
+ }
+ }
+
+ g_signal_emit (ofono, signals[NETWORK_DATA_CHANGED], 0,
+ mcc, mnc, lac, cid);
+}
+
+
+static void
+geoclue_gsmloc_ofono_set_modems (GeoclueGsmlocOfono *ofono, GPtrArray *modems)
+{
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+ int i;
+ GList *mlist;
+
+ /* empty current modem list */
+ for (mlist = priv->modems; mlist; mlist = mlist->next) {
+ modem_free ((Modem*)mlist->data);
+ }
+ g_list_free (priv->modems);
+ priv->modems = NULL;
+
+ if (!modems || modems->len == 0) {
+ return;
+ }
+
+ for (i = 0; i < modems->len; i++) {
+ const char* str;
+ Modem *modem;
+
+ str = (const char*)g_ptr_array_index (modems, i);
+
+ modem = g_slice_new0 (Modem);
+ modem->ofono = ofono;
+ modem->lac = NULL;
+ modem->cid = NULL;
+ modem->proxy = dbus_g_proxy_new_from_proxy (priv->ofono_manager,
+ "org.ofono.Modem",
+ str);
+ if (!modem->proxy) {
+ g_warning ("failed to find the oFono Modem '%s'", str);
+ } else {
+ priv->modems = g_list_prepend (priv->modems, modem);
+ org_ofono_Modem_get_properties_async (modem->proxy,
+ (org_ofono_Manager_get_properties_reply)modem_get_properties_cb,
+ modem);
+ dbus_g_proxy_add_signal (modem->proxy,"PropertyChanged",
+ G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (modem->proxy, "PropertyChanged",
+ G_CALLBACK (modem_property_changed_cb),
+ modem, NULL);
+ }
+ }
+}
+
+
+static void
+geoclue_gsmloc_ofono_get_property (GObject *obj, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GeoclueGsmlocOfono *ofono = GEOCLUE_GSMLOC_OFONO (obj);
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+
+ switch (property_id) {
+ case PROP_AVAILABLE:
+ g_value_set_boolean (value, priv->available);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
+ }
+}
+
+static void
+manager_get_properties_cb (DBusGProxy *proxy,
+ GHashTable *props,
+ GError *error,
+ GeoclueGsmlocOfono *ofono)
+{
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+ GValue *val;
+ GPtrArray *modems = NULL;
+
+ if (error) {
+ if(error->code != DBUS_GERROR_SERVICE_UNKNOWN) {
+ g_warning ("oFono Manager.GetProperties failed: %s", error->message);
+ }
+ g_error_free (error);
+ return;
+ }
+
+ val = g_hash_table_lookup (props, "Modems");
+ if (val) {
+ modems = (GPtrArray*)g_value_get_boxed (val);
+ }
+ geoclue_gsmloc_ofono_set_modems (ofono, modems);
+
+ priv->available = TRUE;
+}
+
+static void
+manager_property_changed_cb (DBusGProxy *proxy,
+ char *name,
+ GValue *value,
+ GeoclueGsmlocOfono *ofono)
+{
+ if (g_strcmp0 ("Modems", name) == 0) {
+ GPtrArray *modems;
+
+ modems = (GPtrArray*)g_value_get_boxed (value);
+ geoclue_gsmloc_ofono_set_modems (ofono, modems);
+ }
+}
+
+static void
+geoclue_gsmloc_ofono_dispose (GObject *obj)
+{
+ GeoclueGsmlocOfono *ofono = GEOCLUE_GSMLOC_OFONO (obj);
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+ GList *mlist;
+
+ if (priv->ofono_manager) {
+ dbus_g_proxy_disconnect_signal (priv->ofono_manager, "PropertyChanged",
+ G_CALLBACK (manager_property_changed_cb),
+ ofono);
+ g_object_unref (priv->ofono_manager);
+ priv->ofono_manager = NULL;
+ }
+
+ if (priv->modems) {
+ for (mlist = priv->modems; mlist; mlist = mlist->next) {
+ modem_free ((Modem*)mlist->data);
+ }
+ g_list_free (priv->modems);
+ priv->modems = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gsmloc_ofono_parent_class)->dispose (obj);
+}
+
+static void
+geoclue_gsmloc_ofono_class_init (GeoclueGsmlocOfonoClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *)klass;
+ GParamSpec *pspec;
+
+ g_type_class_add_private (klass, sizeof (GeoclueGsmlocOfonoPrivate));
+
+ o_class->dispose = geoclue_gsmloc_ofono_dispose;
+ o_class->get_property = geoclue_gsmloc_ofono_get_property;
+
+ dbus_g_object_register_marshaller (ofono_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_STRING,
+ G_TYPE_VALUE,
+ G_TYPE_INVALID);
+
+ signals[NETWORK_DATA_CHANGED] = g_signal_new (
+ "network-data-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ ofono_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ pspec = g_param_spec_boolean ("available",
+ "Available",
+ "Is oFono available",
+ FALSE,
+ G_PARAM_READABLE);
+ g_object_class_install_property (o_class, PROP_AVAILABLE, pspec);
+}
+
+static void
+geoclue_gsmloc_ofono_init (GeoclueGsmlocOfono *ofono)
+{
+ GeoclueGsmlocOfonoPrivate *priv = GET_PRIVATE (ofono);
+ DBusGConnection *system_bus;
+
+ priv->modems = NULL;
+ priv->available = FALSE;
+
+ system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!system_bus) {
+ g_warning ("failed to connect to DBus system bus");
+ return;
+ }
+
+ priv->ofono_manager =
+ dbus_g_proxy_new_for_name (system_bus,
+ "org.ofono",
+ "/",
+ "org.ofono.Manager");
+
+ org_ofono_Manager_get_properties_async (priv->ofono_manager,
+ (org_ofono_Manager_get_properties_reply)manager_get_properties_cb,
+ ofono);
+ dbus_g_proxy_add_signal (priv->ofono_manager,"PropertyChanged",
+ G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->ofono_manager, "PropertyChanged",
+ G_CALLBACK (manager_property_changed_cb),
+ ofono, NULL);
+}
+
+GeoclueGsmlocOfono*
+geoclue_gsmloc_ofono_new (void)
+{
+ return (g_object_new (GEOCLUE_TYPE_GSMLOC_OFONO, NULL));
+}
--- /dev/null
+#ifndef _GEOCLUE_GSMLOC_OFONO
+#define _GEOCLUE_GSMLOC_OFONO
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_GSMLOC_OFONO geoclue_gsmloc_ofono_get_type()
+
+#define GEOCLUE_GSMLOC_OFONO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC_OFONO, GeoclueGsmlocOfono))
+
+#define GEOCLUE_GSMLOC_OFONO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_GSMLOC_OFONO, GeoclueGsmlocOfonoClass))
+
+#define GEOCLUE_IS_GSMLOC_OFONO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GSMLOC_OFONO))
+
+#define GEOCLUE_IS_GSMLOC_OFONO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_GSMLOC_OFONO))
+
+#define GEOCLUE_GSMLOC_OFONO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCLUE_TYPE_GSMLOC_OFONO, GeoclueGsmlocOfonoClass))
+
+typedef struct {
+ GObject parent;
+} GeoclueGsmlocOfono;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ void (*network_data_changed) (GeoclueGsmlocOfono *ofono,
+ char *mcc, char *mnc,
+ char *lac, char *cid);
+} GeoclueGsmlocOfonoClass;
+
+GType geoclue_gsmloc_ofono_get_type (void);
+
+GeoclueGsmlocOfono* geoclue_gsmloc_ofono_new (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-gsmloc.c - A GSM cell based Position provider
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+ /**
+ * Gsmloc provider is a position and address provider that uses GSM cell
+ * location and the webservice http://www.opencellid.org/ (a similar service
+ * used to live at gsmloc.org, hence the name). The web service does not
+ * provide any address data: that is done with a
+ * "mobile country code -> ISO country code" lookup table: as a result address
+ * will only ever have country code and country fields.
+ *
+ * Gsmloc requires the telephony stack oFono to work -- more IMSI data
+ * sources could be added fairly easily.
+ **/
+
+#include <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+/* ofono implementation */
+#include "geoclue-gsmloc-ofono.h"
+
+/* country code list */
+#include "mcc.h"
+
+#define GEOCLUE_DBUS_SERVICE_GSMLOC "org.freedesktop.Geoclue.Providers.Gsmloc"
+#define GEOCLUE_DBUS_PATH_GSMLOC "/org/freedesktop/Geoclue/Providers/Gsmloc"
+
+#define OPENCELLID_URL "http://www.opencellid.org/cell/get"
+#define OPENCELLID_LAT "/rsp/cell/@lat"
+#define OPENCELLID_LON "/rsp/cell/@lon"
+#define OPENCELLID_CID "/rsp/cell/@cellId"
+
+#define GEOCLUE_TYPE_GSMLOC (geoclue_gsmloc_get_type ())
+#define GEOCLUE_GSMLOC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC, GeoclueGsmloc))
+
+typedef struct _GeoclueGsmloc GeoclueGsmloc;
+
+struct _GeoclueGsmloc {
+ GcProvider parent;
+ GMainLoop *loop;
+ GcWebService *web_service;
+
+ GeoclueGsmlocOfono *ofono;
+
+ /* current data */
+ char *mcc;
+ char *mnc;
+ char *lac;
+ char *cid;
+ GeocluePositionFields last_position_fields;
+ GeoclueAccuracyLevel last_accuracy_level;
+ double last_lat;
+ double last_lon;
+
+ GHashTable *address;
+};
+
+typedef struct _GeoclueGsmlocClass {
+ GcProviderClass parent_class;
+} GeoclueGsmlocClass;
+
+
+static void geoclue_gsmloc_init (GeoclueGsmloc *gsmloc);
+static void geoclue_gsmloc_position_init (GcIfacePositionClass *iface);
+static void geoclue_gsmloc_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGsmloc, geoclue_gsmloc, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gsmloc_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_gsmloc_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_gsmloc_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (iface);
+ gboolean ofono_available;
+
+ g_object_get (gsmloc->ofono, "available", &ofono_available, NULL);
+
+ if (!ofono_available) {
+ *status = GEOCLUE_STATUS_ERROR;
+ } else if (!gsmloc->mcc || !gsmloc->mnc ||
+ !gsmloc->lac || !gsmloc->cid) {
+ *status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else {
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (provider);
+ g_main_loop_quit (gsmloc->loop);
+}
+
+static gboolean
+geoclue_gsmloc_query_opencellid (GeoclueGsmloc *gsmloc)
+{
+ double lat, lon;
+ GeocluePositionFields fields = GEOCLUE_POSITION_FIELDS_NONE;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (gsmloc->mcc && gsmloc->mnc &&
+ gsmloc->lac && gsmloc->cid) {
+
+ if (gc_web_service_query (gsmloc->web_service, NULL,
+ "mcc", gsmloc->mcc,
+ "mnc", gsmloc->mnc,
+ "lac", gsmloc->lac,
+ "cellid", gsmloc->cid,
+ (char *)0)) {
+
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lat, OPENCELLID_LAT)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lon, OPENCELLID_LON)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (fields != GEOCLUE_POSITION_FIELDS_NONE) {
+ char *retval_cid;
+ /* if cellid is not present, location is for the local area code.
+ * the accuracy might be an overstatement -- I have no idea how
+ * big LACs typically are */
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ if (gc_web_service_get_string (gsmloc->web_service,
+ &retval_cid, OPENCELLID_CID)) {
+ if (retval_cid && strlen (retval_cid) != 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ g_free (retval_cid);
+ }
+ }
+ }
+ }
+
+ if (fields != gsmloc->last_position_fields ||
+ (fields != GEOCLUE_POSITION_FIELDS_NONE &&
+ (lat != gsmloc->last_lat ||
+ lon != gsmloc->last_lon ||
+ level != gsmloc->last_accuracy_level))) {
+ GeoclueAccuracy *acc;
+
+ /* position changed */
+
+ gsmloc->last_position_fields = fields;
+ gsmloc->last_accuracy_level = level;
+ gsmloc->last_lat = lat;
+ gsmloc->last_lon = lon;
+
+ acc = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0.0, 0.0);
+ gc_iface_position_emit_position_changed (GC_IFACE_POSITION (gsmloc),
+ fields,
+ time (NULL),
+ lat, lon, 0.0,
+ acc);
+ geoclue_accuracy_free (acc);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+geoclue_gsmloc_update_address (GeoclueGsmloc *gsmloc)
+{
+ char *countrycode = NULL;
+ const char *old_countrycode;
+ gboolean changed = FALSE;
+ GeoclueAccuracy *acc;
+
+ if (gsmloc->mcc) {
+ gint64 i;
+ i = g_ascii_strtoll (gsmloc->mcc, NULL, 10);
+ if (i > 0 && i < 800 && mcc_country_codes[i]) {
+ countrycode = mcc_country_codes[i];
+ }
+ }
+
+ old_countrycode = g_hash_table_lookup (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ if (g_strcmp0 (old_countrycode, countrycode) != 0) {
+ changed = TRUE;
+ }
+
+ if (countrycode) {
+ g_hash_table_insert (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE, g_strdup (countrycode));
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0.0, 0.0);
+ } else {
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ }
+ geoclue_address_details_set_country_from_code (gsmloc->address);
+
+ if (changed) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (gsmloc),
+ time (NULL),
+ gsmloc->address,
+ acc);
+
+ }
+ geoclue_accuracy_free (acc);
+}
+static void
+geoclue_gsmloc_set_cell (GeoclueGsmloc *gsmloc,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid)
+{
+ g_free (gsmloc->mcc);
+ g_free (gsmloc->mnc);
+ g_free (gsmloc->lac);
+ g_free (gsmloc->cid);
+
+ gsmloc->mcc = g_strdup (mcc);
+ gsmloc->mnc = g_strdup (mnc);
+ gsmloc->lac = g_strdup (lac);
+ gsmloc->cid = g_strdup (cid);
+
+ geoclue_gsmloc_update_address (gsmloc);
+ geoclue_gsmloc_query_opencellid (gsmloc);
+}
+
+static void
+network_data_changed_cb (gpointer connection_manager,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid,
+ GeoclueGsmloc *gsmloc)
+{
+ if (g_strcmp0 (mcc, gsmloc->mcc) != 0 ||
+ g_strcmp0 (mnc, gsmloc->mnc) != 0 ||
+ g_strcmp0 (lac, gsmloc->lac) != 0 ||
+ g_strcmp0 (cid, gsmloc->cid) != 0) {
+
+ /* new cell data, do a opencellid lookup */
+ geoclue_gsmloc_set_cell (gsmloc, mcc, mnc, lac, cid);
+ }
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_gsmloc_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc;
+
+ gsmloc = (GEOCLUE_GSMLOC (iface));
+
+ if (gsmloc->last_position_fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ /* re-query in case there was a network problem */
+ geoclue_gsmloc_query_opencellid (gsmloc);
+ }
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ if (fields) {
+ *fields = gsmloc->last_position_fields;
+ }
+ if (latitude) {
+ *latitude = gsmloc->last_lat;
+ }
+ if (longitude) {
+ *longitude = gsmloc->last_lon;
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+static gboolean
+geoclue_gsmloc_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *obj = GEOCLUE_GSMLOC (iface);
+
+ if (address) {
+ *address = geoclue_address_details_copy (obj->address);
+ }
+ if (accuracy) {
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (g_hash_table_lookup (obj->address, GEOCLUE_ADDRESS_KEY_COUNTRY)) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ *accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ return TRUE;
+}
+
+
+static void
+geoclue_gsmloc_dispose (GObject *obj)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (obj);
+
+ if (gsmloc->ofono) {
+ g_signal_handlers_disconnect_by_func (gsmloc->ofono,
+ network_data_changed_cb,
+ gsmloc);
+ g_object_unref (gsmloc->ofono);
+ gsmloc->ofono = NULL;
+ }
+
+ if (gsmloc->address) {
+ g_hash_table_destroy (gsmloc->address);
+ gsmloc->address = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gsmloc_parent_class)->dispose (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_gsmloc_class_init (GeoclueGsmlocClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_gsmloc_get_status;
+
+ o_class->dispose = geoclue_gsmloc_dispose;
+}
+
+static void
+geoclue_gsmloc_init (GeoclueGsmloc *gsmloc)
+{
+ gsmloc->address = geoclue_address_details_new ();
+
+ gc_provider_set_details (GC_PROVIDER (gsmloc),
+ GEOCLUE_DBUS_SERVICE_GSMLOC,
+ GEOCLUE_DBUS_PATH_GSMLOC,
+ "Gsmloc", "GSM cell based position provider");
+
+ gsmloc->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (gsmloc->web_service, OPENCELLID_URL);
+
+ geoclue_gsmloc_set_cell (gsmloc, NULL, NULL, NULL, NULL);
+
+ gsmloc->address = geoclue_address_details_new ();
+
+ /* init ofono*/
+ gsmloc->ofono = geoclue_gsmloc_ofono_new ();
+ g_signal_connect (gsmloc->ofono, "network-data-changed",
+ G_CALLBACK (network_data_changed_cb), gsmloc);
+}
+
+static void
+geoclue_gsmloc_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_gsmloc_get_position;
+}
+
+static void
+geoclue_gsmloc_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_gsmloc_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeoclueGsmloc *o = g_object_new (GEOCLUE_TYPE_GSMLOC, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Gsmloc
+Service=org.freedesktop.Geoclue.Providers.Gsmloc
+Path=/org/freedesktop/Geoclue/Providers/Gsmloc
+Accuracy=Postalcode
+Requires=RequiresNetwork, RequiresCell
+Provides=ProvidesUpdates
+Interfaces=org.freedesktop.Geoclue.Position, org.freedesktop.Geoclue.Address
--- /dev/null
+/* Mobile country code list from
+ * "LIST OF MOBILE COUNTRY OR GEOGRAPHICAL AREA CODES"
+ * (http://www.itu.int/publ/T-SP-E.212A-2007)
+ * combined with ISO 3166-1 alpha-2 list for two letter country codes
+ */
+
+char *mcc_country_codes[] = {
+ NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 100 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 200 */
+ NULL,
+ NULL,
+ NULL,
+ "NL",
+ NULL,
+ "BE",
+ NULL,
+ "FR",
+ NULL,
+ NULL,
+ NULL,
+ "MC",
+ "AD",
+ "ES",
+ NULL,
+ "HU",
+ NULL,
+ "BA",
+ "HR",
+ "RS",
+ NULL,
+ "IT",
+ NULL,
+ NULL,
+ "VA",
+ "RO",
+ NULL,
+ "CH",
+ NULL,
+ "CZ",
+ "SK",
+ "AT",
+ NULL,
+ "GB",
+ "GB",
+ NULL,
+ NULL,
+ "DK",
+ NULL,
+ "SE",
+ NULL,
+ "NO",
+ NULL,
+ "FI",
+ NULL,
+ "LT",
+ "LV",
+ "EE",
+ NULL,
+ "RU",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "UA",
+ NULL,
+ "BY",
+ NULL,
+ "MD",
+ "PL",
+ NULL,
+ "DE",
+ NULL,
+ NULL,
+ NULL,
+ "GI",
+ NULL,
+ "PT",
+ NULL,
+ "LU",
+ NULL,
+ "IE",
+ NULL,
+ "IS",
+ NULL,
+ "AL",
+ NULL,
+ "MT",
+ NULL,
+ "CY",
+ NULL,
+ "GE",
+ "AM",
+ "BG",
+ NULL,
+ "TR",
+ NULL,
+ "FO",
+ NULL,
+ "GL",
+ NULL,
+ "SM",
+ "SI",
+ "MK",
+ "LI",
+ NULL,
+ "ME",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "CA",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "PM",
+ NULL,
+ "US",
+ "US",
+ "US",
+ "US",
+ "US",
+ "US",
+ "US",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "PR",
+ NULL,
+ "VI",
+ NULL,
+ "MX",
+ NULL,
+ NULL,
+ NULL,
+ "JM",
+ NULL,
+ "MQ",
+ NULL,
+ "BB",
+ NULL,
+ "AG",
+ NULL,
+ "KY",
+ NULL,
+ "VG",
+ NULL,
+ "BM",
+ NULL,
+ "GD",
+ NULL,
+ "MS",
+ NULL,
+ "KN",
+ NULL,
+ "LC",
+ NULL,
+ "VC",
+ NULL,
+ "AN",
+ "AW",
+ "BS",
+ "AI",
+ "DM",
+ NULL,
+ "CU",
+ NULL,
+ "DO",
+ NULL,
+ "HT",
+ NULL,
+ "TT",
+ NULL,
+ "TC",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "AZ",
+ "KZ",
+ "BT",
+ NULL,
+ "IN",
+ "IN",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "PK",
+ NULL,
+ "AF",
+ "LK",
+ "MM",
+ "LB",
+ "JO",
+ "SY",
+ "IQ",
+ "KW",
+ "SA",
+ "YE",
+ "OM",
+ NULL,
+ "AE",
+ "IL",
+ "BH",
+ "QA",
+ "MN",
+ "NP",
+ "AE",
+ "AE",
+ "IR",
+ NULL,
+ "UZ",
+ NULL,
+ "TJ",
+ "KG",
+ "TM",
+ NULL,
+ "JP",
+ "JP",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "KR",
+ NULL,
+ "VN",
+ NULL,
+ "HK",
+ "MO",
+ "KH",
+ "LA",
+ NULL,
+ NULL,
+ "CN",
+ "CN",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "TW",
+ "KP",
+ NULL,
+ NULL,
+ "BD",
+ NULL,
+ "MV",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 500 */
+ NULL,
+ "MY",
+ NULL,
+ NULL,
+ "AU",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ID",
+ NULL,
+ NULL,
+ NULL,
+ "TL",
+ "PH",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "TH",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "SG",
+ NULL,
+ NULL,
+ "BN",
+ NULL,
+ "NZ",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "NR",
+ "PG",
+ NULL,
+ "TO",
+ "SB",
+ "VU",
+ "FJ",
+ "WF",
+ "AS",
+ "KI",
+ "NC",
+ "PF",
+ "CK",
+ "WS",
+ "FM",
+ "MH",
+ "PW",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 600 */
+ NULL,
+ "EG",
+ "DZ",
+ "MA",
+ "TN",
+ "LY",
+ "GM",
+ "SN",
+ "MR",
+ "ML",
+ "GN",
+ "CI",
+ "BF",
+ "NE",
+ "TG",
+ "BJ",
+ "MU",
+ "LR",
+ "SL",
+ "GH",
+ "NG",
+ "TD",
+ "CF",
+ "CM",
+ "CV",
+ "ST",
+ "GQ",
+ "GA",
+ "CG",
+ "CD",
+ "AO",
+ "GW",
+ "SC",
+ "SD",
+ "RW",
+ "ET",
+ "SO",
+ "DJ",
+ "KE",
+ "TZ",
+ "UG",
+ "BI",
+ "MZ",
+ NULL,
+ "ZM",
+ "MG",
+ "TF",
+ "ZW",
+ "NA",
+ "MW",
+ "LS",
+ "BW",
+ "SZ",
+ "KM",
+ "ZA",
+ NULL,
+ "ER",
+ NULL,
+ NULL,
+ NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 700 */
+ NULL,
+ "BZ",
+ NULL,
+ "GT",
+ NULL,
+ "SV",
+ NULL,
+ "HN",
+ NULL,
+ "NI",
+ NULL,
+ "CR",
+ NULL,
+ "PA",
+ NULL,
+ "PE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "AR",
+ NULL,
+ "BR",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "CL",
+ NULL,
+ "CO",
+ NULL,
+ "VE",
+ NULL,
+ "BO",
+ NULL,
+ "GY",
+ NULL,
+ "EC",
+ NULL,
+ "GF",
+ NULL,
+ "PY",
+ NULL,
+ "SR",
+ NULL,
+ "UY",
+ NULL,
+ "FK",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 799 */
+};
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/" >
+ <interface name="org.ofono.Manager">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ </interface>
+</node>
--- /dev/null
+VOID:STRING,BOXED
+VOID:STRING,STRING,STRING,STRING
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ofono.Modem">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ </interface>
+</node>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ofono.NetworkOperator">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ </method>
+ <method name="Register"/>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ </interface>
+</node>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ofono.NetworkRegistration">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ </method>
+ <method name="Register"/>
+ <method name="Deregister"/>
+ <method name="ProposeScan">
+ <arg type="ao" direction="out"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ </interface>
+</node>
+
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Gsmloc
+Exec=@libexecdir@/geoclue-gsmloc
--- /dev/null
+libexec_PROGRAMS = geoclue-gypsy
+
+geoclue_gypsy_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GYPSY_CFLAGS)
+
+geoclue_gypsy_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GYPSY_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gypsy_SOURCES = \
+ geoclue-gypsy.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gypsy.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gypsy.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-gypsy.c - Geoclue backend for Gypsy which provides the Position.
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <gypsy/gypsy-control.h>
+#include <gypsy/gypsy-device.h>
+#include <gypsy/gypsy-position.h>
+#include <gypsy/gypsy-course.h>
+#include <gypsy/gypsy-accuracy.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct {
+ GcProvider parent;
+
+ char *device_name;
+
+ GypsyControl *control;
+ GypsyDevice *device;
+ GypsyPosition *position;
+ GypsyCourse *course;
+ GypsyAccuracy *acc;
+
+ GMainLoop *loop;
+
+ int timestamp;
+
+ GeoclueStatus status;
+
+ /* Cached so we don't have to make D-Bus method calls all the time */
+ GypsyPositionFields position_fields;
+ double latitude;
+ double longitude;
+ double altitude;
+
+ GypsyCourseFields course_fields;
+ double speed;
+ double direction;
+ double climb;
+
+ GeoclueAccuracy *accuracy;
+} GeoclueGypsy;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGypsyClass;
+
+static void geoclue_gypsy_position_init (GcIfacePositionClass *iface);
+static void geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GYPSY (geoclue_gypsy_get_type ())
+#define GEOCLUE_GYPSY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GYPSY, GeoclueGypsy))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGypsy, geoclue_gypsy, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gypsy_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gypsy_velocity_init))
+
+
+/* GcIfaceGeoclue methods */
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+
+ *status = gypsy->status;
+
+ return TRUE;
+}
+
+
+/* Compare the two fields and return TRUE if they have changed */
+static gboolean
+compare_field (GypsyPositionFields fields_a,
+ double value_a,
+ GypsyPositionFields fields_b,
+ double value_b,
+ GypsyPositionFields field)
+{
+ /* If both fields are valid, compare the values */
+ if ((fields_a & field) && (fields_b & field)) {
+ if (value_a == value_b) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+
+ /* Otherwise return if both the fields set are the same */
+ return ((fields_a & field) != (fields_b & field));
+}
+
+static GeocluePositionFields
+gypsy_position_to_geoclue (GypsyPositionFields fields)
+{
+ GeocluePositionFields gc_fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LATITUDE) ? GEOCLUE_POSITION_FIELDS_LATITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LONGITUDE) ? GEOCLUE_POSITION_FIELDS_LONGITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_ALTITUDE) ? GEOCLUE_POSITION_FIELDS_ALTITUDE : 0;
+
+ return gc_fields;
+}
+
+static GeoclueVelocityFields
+gypsy_course_to_geoclue (GypsyCourseFields fields)
+{
+ GeoclueVelocityFields gc_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_SPEED) ? GEOCLUE_VELOCITY_FIELDS_SPEED : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_DIRECTION) ? GEOCLUE_VELOCITY_FIELDS_DIRECTION : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_CLIMB) ? GEOCLUE_VELOCITY_FIELDS_CLIMB : 0;
+
+ return gc_fields;
+}
+
+static void
+position_changed (GypsyPosition *position,
+ GypsyPositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ g_print ("Gypsy position changed\n");
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->position_fields, gypsy->latitude,
+ fields, latitude, GYPSY_POSITION_FIELDS_LATITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LATITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LATITUDE;
+ gypsy->latitude = latitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->longitude,
+ fields, longitude, GYPSY_POSITION_FIELDS_LONGITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LONGITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LONGITUDE;
+ gypsy->longitude = longitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->altitude,
+ fields, altitude, GYPSY_POSITION_FIELDS_ALTITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_ALTITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_ALTITUDE;
+ gypsy->altitude = altitude;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ g_print ("Emitting signal\n");
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+course_changed (GypsyCourse *course,
+ GypsyCourseFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->course_fields, gypsy->speed,
+ fields, speed, GYPSY_COURSE_FIELDS_SPEED)) {
+ if (fields & GYPSY_COURSE_FIELDS_SPEED) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_SPEED;
+ gypsy->speed = speed;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->direction,
+ fields, direction, GYPSY_COURSE_FIELDS_DIRECTION)) {
+ if (fields & GYPSY_COURSE_FIELDS_DIRECTION) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_DIRECTION;
+ gypsy->direction = direction;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->climb,
+ fields, climb, GYPSY_COURSE_FIELDS_CLIMB)) {
+ if (fields & GYPSY_COURSE_FIELDS_CLIMB) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_CLIMB;
+ gypsy->climb = climb;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeoclueVelocityFields fields;
+
+ fields = gypsy_course_to_geoclue (gypsy->course_fields);
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gypsy), fields,
+ timestamp, gypsy->speed, gypsy->direction, gypsy->climb);
+ }
+}
+
+static void
+accuracy_changed (GypsyAccuracy *accuracy,
+ GypsyAccuracyFields fields,
+ double pdop,
+ double hdop,
+ double vdop,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+ GeoclueAccuracyLevel level;
+ double horiz, vert;
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level, &horiz, &vert);
+ if (fields & (GYPSY_ACCURACY_FIELDS_HORIZONTAL |
+ GYPSY_ACCURACY_FIELDS_VERTICAL)){
+ if (level != GEOCLUE_ACCURACY_LEVEL_DETAILED ||
+ horiz != hdop || vert != vdop) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ hdop, vdop);
+ } else {
+
+ if (level != GEOCLUE_ACCURACY_LEVEL_NONE ||
+ horiz != 0.0 || vert != 0.0) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ gypsy->timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+connection_changed (GypsyDevice *device,
+ gboolean connected,
+ GeoclueGypsy *gypsy)
+{
+ if (connected == FALSE &&
+ gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+fix_status_changed (GypsyDevice *device,
+ GypsyDeviceFixStatus status,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ if (gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ if (gypsy->status != GEOCLUE_STATUS_ACQUIRING) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ if (gypsy->status != GEOCLUE_STATUS_AVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ break;
+ }
+
+ if (changed) {
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+get_initial_status (GeoclueGypsy *gypsy)
+{
+ gboolean connected;
+ GypsyDeviceFixStatus status;
+ GError *error = NULL;
+
+ connected = gypsy_device_get_connection_status (gypsy->device, &error);
+ if (connected == FALSE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ g_print ("Initial status - %d (disconnected)\n", gypsy->status);
+ return;
+ }
+
+ status = gypsy_device_get_fix_status (gypsy->device, &error);
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ break;
+ }
+
+ g_print ("Initial status - %d (connected)\n", gypsy->status);
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ const char *device_name;
+ char *path;
+
+ device_name = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSDevice");
+
+ if (g_strcmp0 (gypsy->device_name, device_name) == 0) {
+ return TRUE;
+ }
+
+ g_free (gypsy->device_name);
+ gypsy->device_name = NULL;
+
+ if (device_name == NULL || *device_name == '\0') {
+ return TRUE;
+ }
+
+ gypsy->device_name = g_strdup (device_name);
+ g_print ("Gypsy provider using '%s'\n", gypsy->device_name);
+ path = gypsy_control_create (gypsy->control, gypsy->device_name,
+ error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ return FALSE;
+ }
+
+ /* If we've got here, then we are out of the ERROR condition */
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ gypsy->device = gypsy_device_new (path);
+ g_signal_connect (gypsy->device, "connection-changed",
+ G_CALLBACK (connection_changed), gypsy);
+ g_signal_connect (gypsy->device, "fix-status-changed",
+ G_CALLBACK (fix_status_changed), gypsy);
+
+ gypsy->position = gypsy_position_new (path);
+ g_signal_connect (gypsy->position, "position-changed",
+ G_CALLBACK (position_changed), gypsy);
+ gypsy->course = gypsy_course_new (path);
+ g_signal_connect (gypsy->course, "course-changed",
+ G_CALLBACK (course_changed), gypsy);
+ gypsy->acc = gypsy_accuracy_new (path);
+ g_signal_connect (gypsy->acc, "accuracy-changed",
+ G_CALLBACK (accuracy_changed), gypsy);
+
+ g_debug ("starting device");
+ gypsy_device_start (gypsy->device, error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ g_free (path);
+ return FALSE;
+ }
+ get_initial_status (gypsy);
+ g_free (path);
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (provider);
+
+ g_main_loop_quit (gypsy->loop);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ geoclue_accuracy_free (gypsy->accuracy);
+ g_free (gypsy->device_name);
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ if (gypsy->control) {
+ g_object_unref (gypsy->control);
+ gypsy->control = NULL;
+ }
+
+ if (gypsy->device) {
+ g_object_unref (gypsy->device);
+ gypsy->device = NULL;
+ }
+
+ if (gypsy->position) {
+ g_object_unref (gypsy->position);
+ gypsy->position = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->dispose (object);
+}
+
+static void
+geoclue_gypsy_class_init (GeoclueGypsyClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_gypsy_init (GeoclueGypsy *gypsy)
+{
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ gypsy->control = gypsy_control_get_default ();
+
+ gc_provider_set_details (GC_PROVIDER (gypsy),
+ "org.freedesktop.Geoclue.Providers.Gypsy",
+ "/org/freedesktop/Geoclue/Providers/Gypsy",
+ "Gypsy", "Gypsy provider");
+
+ gypsy->position_fields = GYPSY_POSITION_FIELDS_NONE;
+
+ gypsy->accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ GeoclueAccuracyLevel level;
+ double horizontal, vertical;
+
+ *timestamp = gypsy->timestamp;
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LATITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *latitude = gypsy->latitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LONGITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *longitude = gypsy->longitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_ALTITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE;
+ *altitude = gypsy->altitude;
+ }
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level,
+ &horizontal, &vertical);
+ *accuracy = geoclue_accuracy_new (level, horizontal, vertical);
+
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueGypsy *gypsy;
+
+ g_type_init ();
+
+ gypsy = g_object_new (GEOCLUE_TYPE_GYPSY, NULL);
+
+ gypsy->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (gypsy->loop);
+
+ /* Unref the object so that gypsy-daemon knows we've shutdown */
+ g_object_unref (gypsy);
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Gypsy
+Service=org.freedesktop.Geoclue.Providers.Gypsy
+Path=/org/freedesktop/Geoclue/Providers/Gypsy
+Requires=RequiresGPS
+Provides=ProvidesUpdates
+Interfaces=org.freedesktop.Geoclue.Position;org.freedesktop.Geoclue.Velocity
+Accuracy=Detailed
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Gypsy
+Exec=@libexecdir@/geoclue-gypsy
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-hostip
+
+NOINST_H_FILES = \
+ geoclue-hostip.h
+
+geoclue_hostip_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-hostip.c
+
+geoclue_hostip_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_hostip_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-hostip.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Hostip.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-hostip.c - A hostip.info-based Address/Position provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007, 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <time.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-error.h>
+
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "geoclue-hostip.h"
+
+#define GEOCLUE_DBUS_SERVICE_HOSTIP "org.freedesktop.Geoclue.Providers.Hostip"
+#define GEOCLUE_DBUS_PATH_HOSTIP "/org/freedesktop/Geoclue/Providers/Hostip"
+
+#define HOSTIP_URL "http://api.hostip.info/"
+
+#define HOSTIP_NS_GML_NAME "gml"
+#define HOSTIP_NS_GML_URI "http://www.opengis.net/gml"
+
+#define HOSTIP_COUNTRY_XPATH "//gml:featureMember/Hostip/countryName"
+#define HOSTIP_COUNTRYCODE_XPATH "//gml:featureMember/Hostip/countryAbbrev"
+#define HOSTIP_LOCALITY_XPATH "//gml:featureMember/Hostip/gml:name"
+#define HOSTIP_LATLON_XPATH "//gml:featureMember/Hostip//gml:coordinates"
+
+static void geoclue_hostip_init (GeoclueHostip *obj);
+static void geoclue_hostip_position_init (GcIfacePositionClass *iface);
+static void geoclue_hostip_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueHostip, geoclue_hostip, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_hostip_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_hostip_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_hostip_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assume it is available so long as all the requirements are satisfied
+ ie: Network is available */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueHostip *obj = GEOCLUE_HOSTIP (provider);
+ g_main_loop_quit (obj->loop);
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_hostip_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueHostip *obj = (GEOCLUE_HOSTIP (iface));
+ gchar *coord_str = NULL;
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ if (!gc_web_service_query (obj->web_service, error, (char *)0)) {
+ return FALSE;
+ }
+
+ if (gc_web_service_get_string (obj->web_service,
+ &coord_str, HOSTIP_LATLON_XPATH)) {
+ if (sscanf (coord_str, "%lf,%lf", longitude , latitude) == 2) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ g_free (coord_str);
+ }
+
+ time ((time_t *)timestamp);
+
+ if (*fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0, 0);
+ } else {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0, 0);
+ }
+ return TRUE;
+}
+
+/* Address interface implementation */
+
+static gboolean
+geoclue_hostip_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueHostip *obj = GEOCLUE_HOSTIP (iface);
+ gchar *locality = NULL;
+ gchar *country = NULL;
+ gchar *country_code = NULL;
+
+ if (!gc_web_service_query (obj->web_service, error, (char *)0)) {
+ return FALSE;
+ }
+
+ if (address) {
+ *address = geoclue_address_details_new ();
+ if (gc_web_service_get_string (obj->web_service,
+ &locality, HOSTIP_LOCALITY_XPATH)) {
+ /* hostip "sctructured data" for the win... */
+ if (g_ascii_strcasecmp (locality, "(Unknown city)") == 0 ||
+ g_ascii_strcasecmp (locality, "(Unknown City?)") == 0) {
+
+ g_free (locality);
+ locality = NULL;
+ } else {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ locality);
+ }
+ }
+
+ if (gc_web_service_get_string (obj->web_service,
+ &country_code, HOSTIP_COUNTRYCODE_XPATH)) {
+ if (g_ascii_strcasecmp (country_code, "XX") == 0) {
+ g_free (country_code);
+ country_code = NULL;
+ } else {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ country_code);
+ geoclue_address_details_set_country_from_code (*address);
+ }
+ }
+
+ if (!g_hash_table_lookup (*address, GEOCLUE_ADDRESS_KEY_COUNTRY) &&
+ gc_web_service_get_string (obj->web_service,
+ &country, HOSTIP_COUNTRY_XPATH)) {
+ if (g_ascii_strcasecmp (country, "(Unknown Country?)") == 0) {
+ g_free (country);
+ country = NULL;
+ } else {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ country);
+ }
+ }
+ }
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ if (accuracy) {
+ if (locality && country) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 0, 0);
+ } else if (country) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_COUNTRY,
+ 0, 0);
+ } else {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0, 0);
+ }
+ }
+ g_free (locality);
+ g_free (country);
+ g_free (country_code);
+
+ return TRUE;
+}
+
+static void
+geoclue_hostip_finalize (GObject *obj)
+{
+ GeoclueHostip *self = (GeoclueHostip *) obj;
+
+ g_object_unref (self->web_service);
+
+ ((GObjectClass *) geoclue_hostip_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_hostip_class_init (GeoclueHostipClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_hostip_get_status;
+
+ o_class->finalize = geoclue_hostip_finalize;
+}
+
+static void
+geoclue_hostip_init (GeoclueHostip *obj)
+{
+ gc_provider_set_details (GC_PROVIDER (obj),
+ GEOCLUE_DBUS_SERVICE_HOSTIP,
+ GEOCLUE_DBUS_PATH_HOSTIP,
+ "Hostip", "Hostip provider");
+
+ obj->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->web_service, HOSTIP_URL);
+ gc_web_service_add_namespace (obj->web_service,
+ HOSTIP_NS_GML_NAME, HOSTIP_NS_GML_URI);
+}
+
+static void
+geoclue_hostip_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_hostip_get_position;
+}
+
+static void
+geoclue_hostip_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_hostip_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeoclueHostip *o = g_object_new (GEOCLUE_TYPE_HOSTIP, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-hostip.h - An Address/Position provider for hostip.info
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_HOSTIP
+#define _GEOCLUE_HOSTIP
+
+#include <glib-object.h>
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_HOSTIP (geoclue_hostip_get_type ())
+
+#define GEOCLUE_HOSTIP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_HOSTIP, GeoclueHostip))
+#define GEOCLUE_HOSTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_HOSTIP, GeoclueHostipClass))
+#define GEOCLUE_IS_HOSTIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_HOSTIP))
+#define GEOCLUE_IS_HOSTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_HOSTIP))
+
+typedef struct _GeoclueHostip {
+ GcProvider parent;
+ GMainLoop *loop;
+ GcWebService *web_service;
+} GeoclueHostip;
+
+typedef struct _GeoclueHostipClass {
+ GcProviderClass parent_class;
+} GeoclueHostipClass;
+
+GType geoclue_hostip_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+[Geoclue Provider]
+Name=Hostip
+Service=org.freedesktop.Geoclue.Providers.Hostip
+Path=/org/freedesktop/Geoclue/Providers/Hostip
+Accuracy=Locality
+Requires=RequiresNetwork
+Provides=ProvidesCacheableOnConnection
+Interfaces=org.freedesktop.Geoclue.Position;org.freedesktop.Geoclue.Address
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Hostip
+Exec=@libexecdir@/geoclue-hostip
--- /dev/null
+libexec_PROGRAMS = geoclue-localnet
+
+noinst_DATA = \
+ geoclue-localnet.xml
+
+nodist_geoclue_localnet_SOURCES = \
+ geoclue-localnet-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_localnet_SOURCES)
+
+geoclue_localnet_SOURCES = \
+ geoclue-localnet.c
+
+geoclue_localnet_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_localnet_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-localnet.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Localnet.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-localnet-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_localnet_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-localnet-glue.h: geoclue-localnet.xml
+ $(DBUS_BINDING_TOOL) --prefix=geoclue_localnet --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
--- /dev/null
+/**
+ *
+ * Expects to find a keyfile in user config dir
+ * (~/.config/geoclue-localnet-gateways).
+ *
+ * The keyfile should contain entries like this:
+ *
+ * [00:1D:7E:55:8D:80]
+ * country=Finland
+ * street=Solnantie 24
+ * locality=Helsinki
+ *
+ * Only address interface is supported so far.
+ *
+ * Any application that can obtain a reliable address can submit it
+ * to localnet provider through the D-Bus API -- it will then be provided
+ * whenever connected to the same router:
+ * org.freedesktop.Geoclue.Localnet.SetAddress
+ * org.freedesktop.Geoclue.Localnet.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ dbus-send --print-reply --type=method_call \
+ --dest=org.freedesktop.Geoclue.Providers.Localnet \
+ /org/freedesktop/Geoclue/Providers/Localnet \
+ org.freedesktop.Geoclue.Localnet.SetAddressFields \
+ string: \
+ string:"Finland" \
+ string: \
+ string:"Helsinki" \
+ string: \
+ string: \
+ string:"Solnantie 24"
+
+ * This would make the provider save the specified address with current
+ * router mac address. It will provide the address to clients whenever
+ * the computer is connected to the same router again.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-address.h>
+
+#define KEYFILE_NAME "geoclue-localnet-gateways"
+
+typedef struct {
+ char *mac;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} Gateway;
+
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+
+ char *keyfile_name;
+ GSList *gateways;
+} GeoclueLocalnet;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueLocalnetClass;
+
+#define GEOCLUE_TYPE_LOCALNET (geoclue_localnet_get_type ())
+#define GEOCLUE_LOCALNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_LOCALNET, GeoclueLocalnet))
+
+static void geoclue_localnet_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueLocalnet, geoclue_localnet, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_localnet_address_init))
+
+static gboolean geoclue_localnet_set_address (GeoclueLocalnet *localnet, GHashTable *address, GError **error);
+static gboolean geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet, char *country_code, char *country, char *region, char *locality, char *area, char *postalcode, char *street, GError **error);
+#include "geoclue-localnet-glue.h"
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (provider);
+ g_main_loop_quit (localnet->loop);
+}
+
+static void
+free_gateway_list (GSList *gateways)
+{
+ GSList *l;
+
+ l = gateways;
+ while (l) {
+ Gateway *gw;
+
+ gw = l->data;
+ g_free (gw->mac);
+ g_hash_table_destroy (gw->address);
+ geoclue_accuracy_free (gw->accuracy);
+ g_free (gw);
+
+ l = l->next;
+ }
+ g_slist_free (gateways);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (object);
+
+ g_free (localnet->keyfile_name);
+ free_gateway_list (localnet->gateways);
+
+ G_OBJECT_CLASS (geoclue_localnet_parent_class)->finalize (object);
+}
+
+static void
+geoclue_localnet_class_init (GeoclueLocalnetClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_localnet_get_type (),
+ &dbus_glib_geoclue_localnet_object_info);
+
+}
+
+/* Parse /proc/net/route to get default gateway address and then parse
+ * /proc/net/arp to find matching mac address.
+ *
+ * There are some problems with this. First, it's IPv4 only.
+ * Second, there must be a way to do this with ioctl, but that seemed really
+ * complicated... even /usr/sbin/arp parses /proc/net/arp
+ *
+ * returns:
+ * 1 : on success
+ * 0 : no success, no errors
+ * <0 : error
+ */
+int
+get_mac_address (char **mac)
+{
+ char *content;
+ char **lines, **entry;
+ GError *error = NULL;
+ char *route_gateway = NULL;
+
+ g_assert (*mac == NULL);
+
+ if (!g_file_get_contents ("/proc/net/route", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/route: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines + 1;
+
+ while (*entry && strlen (*entry) > 0) {
+ char dest[9];
+ char gateway[9];
+ if (sscanf (*entry,
+ "%*s %8[0-9A-Fa-f] %8[0-9A-Fa-f] %*s",
+ dest, gateway) != 2) {
+ g_warning ("Failed to parse /proc/net/route entry '%s'", *entry);
+ } else if (strcmp (dest, "00000000") == 0) {
+ route_gateway = g_strdup (gateway);
+ break;
+ }
+ entry++;
+ }
+ g_strfreev (lines);
+
+ if (!route_gateway) {
+ g_warning ("Failed to find default route in /proc/net/route");
+ return -1;
+ }
+
+ if (!g_file_get_contents ("/proc/net/arp", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/arp: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines+1;
+ while (*entry && strlen (*entry) > 0) {
+ char hwa[100];
+ char *arp_gateway;
+ int ip[4];
+
+ if (sscanf(*entry,
+ "%d.%d.%d.%d 0x%*x 0x%*x %100s %*s %*s\n",
+ &ip[0], &ip[1], &ip[2], &ip[3], hwa) != 5) {
+ g_warning ("Failed to parse /proc/net/arp entry '%s'", *entry);
+ } else {
+ arp_gateway = g_strdup_printf ("%02X%02X%02X%02X", ip[3], ip[2], ip[1], ip[0]);
+ if (strcmp (arp_gateway, route_gateway) == 0) {
+ g_free (arp_gateway);
+ *mac = g_strdup (hwa);
+ break;
+ }
+ g_free (arp_gateway);
+
+ }
+ entry++;
+ }
+ g_free (route_gateway);
+ g_strfreev (lines);
+
+ return *mac ? 1 : 0;
+}
+
+static void
+geoclue_localnet_load_gateways_from_keyfile (GeoclueLocalnet *localnet,
+ GKeyFile *keyfile)
+{
+ char **groups;
+ char **g;
+ GError *error = NULL;
+
+ groups = g_key_file_get_groups (keyfile, NULL);
+ g = groups;
+ while (*g) {
+ GeoclueAccuracyLevel level;
+ char **keys;
+ char **k;
+ Gateway *gateway = g_new0 (Gateway, 1);
+
+ gateway->mac = g_ascii_strdown (*g, -1);
+ gateway->address = geoclue_address_details_new ();
+
+ /* read all keys in the group as address fields */
+ keys = g_key_file_get_keys (keyfile, *g,
+ NULL, &error);
+ if (error) {
+ g_warning ("Could not load keys for group [%s] from %s: %s",
+ *g, localnet->keyfile_name, error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+
+ k = keys;
+ while (*k) {
+ char *value;
+
+ value = g_key_file_get_string (keyfile, *g, *k, NULL);
+ g_hash_table_insert (gateway->address,
+ *k, value);
+ k++;
+ }
+ g_free (keys);
+
+ level = geoclue_address_details_get_accuracy_level (gateway->address);
+ gateway->accuracy = geoclue_accuracy_new (level, 0, 0);
+
+ localnet->gateways = g_slist_prepend (localnet->gateways, gateway);
+
+ g++;
+ }
+ g_strfreev (groups);
+}
+
+static Gateway *
+geoclue_localnet_find_gateway (GeoclueLocalnet *localnet, char *mac)
+{
+ GSList *l;
+
+ l = localnet->gateways;
+ /* eww, should be using a hashtable or something here */
+ while (l) {
+ Gateway *gw = l->data;
+
+ if (strcmp (gw->mac, mac) == 0) {
+ return gw;
+ }
+
+ l = l->next;
+ }
+
+ return NULL;
+}
+
+static void
+geoclue_localnet_init (GeoclueLocalnet *localnet)
+{
+ const char *dir;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+
+ gc_provider_set_details (GC_PROVIDER (localnet),
+ "org.freedesktop.Geoclue.Providers.Localnet",
+ "/org/freedesktop/Geoclue/Providers/Localnet",
+ "Localnet", "provides Address based on current gateway mac address and a local address file (which can be updated through D-Bus)");
+
+
+ localnet->gateways = NULL;
+
+ /* load known addresses from keyfile */
+ dir = g_get_user_config_dir ();
+ g_mkdir_with_parents (dir, 0755);
+ localnet->keyfile_name = g_build_filename (dir, KEYFILE_NAME, NULL);
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &error)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, error->message);
+ g_error_free (error);
+ }
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+
+}
+
+typedef struct {
+ GKeyFile *keyfile;
+ char *group_name;
+} localnet_keyfile_group;
+
+static void
+add_address_detail_to_keyfile (char *key, char *value,
+ localnet_keyfile_group *group)
+{
+ g_key_file_set_string (group->keyfile, group->group_name,
+ key, value);
+}
+
+static gboolean
+geoclue_localnet_set_address (GeoclueLocalnet *localnet,
+ GHashTable *details,
+ GError **error)
+{
+ char *str, *mac = NULL;
+ GKeyFile *keyfile;
+ GError *int_err = NULL;
+ localnet_keyfile_group *keyfile_group;
+ Gateway *gw;
+
+ if (!details) {
+ /* TODO set error */
+ return FALSE;
+ }
+
+ if (get_mac_address (&mac) < 0)
+ return FALSE;
+
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ /* TODO set error */
+ return FALSE;
+ }
+ /* reload keyfile just in case it's changed */
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &int_err)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, int_err->message);
+ g_error_free (int_err);
+ int_err = NULL;
+ }
+
+ /* remove old group (if exists) and add new to GKeyFile */
+ g_key_file_remove_group (keyfile, mac, NULL);
+
+ keyfile_group = g_new0 (localnet_keyfile_group, 1);
+ keyfile_group->keyfile = keyfile;
+ keyfile_group->group_name = mac;
+ g_hash_table_foreach (details, (GHFunc) add_address_detail_to_keyfile, keyfile_group);
+ g_free (keyfile_group);
+
+ /* save keyfile*/
+ str = g_key_file_to_data (keyfile, NULL, &int_err);
+ if (int_err) {
+ g_warning ("Failed to get keyfile data as string: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ g_file_set_contents (localnet->keyfile_name, str, -1, &int_err);
+ g_free (str);
+ if (int_err) {
+ g_warning ("Failed to save keyfile: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ /* re-parse keyfile */
+ free_gateway_list (localnet->gateways);
+ localnet->gateways = NULL;
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (gw) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (localnet),
+ time (NULL), gw->address, gw->accuracy);
+ } else {
+ /* empty address -- should emit anyway? */
+ }
+ return TRUE;
+}
+
+static gboolean
+geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+ gboolean ret;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ if (!country) {
+ geoclue_address_details_set_country_from_code (address);
+ }
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ ret = geoclue_localnet_set_address (localnet,
+ address,
+ error);
+ g_hash_table_destroy (address);
+ return ret;
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueLocalnet *localnet;
+ int i, ret_val;
+ char *mac = NULL;
+ Gateway *gw;
+
+ localnet = GEOCLUE_LOCALNET (gc);
+
+ /* we may be trying to read /proc/net/arp right after network connection.
+ * It's sometimes not up yet, try a couple of times */
+ for (i = 0; i < 5; i++) {
+ ret_val = get_mac_address (&mac);
+ if (ret_val < 0)
+ return FALSE;
+ else if (ret_val == 1)
+ break;
+ usleep (200);
+ }
+
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ if (error) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE, "Could not get current gateway mac address");
+ }
+ return FALSE;
+ }
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (timestamp) {
+ *timestamp = time(NULL);
+ }
+ if (address) {
+ if (gw) {
+ *address = geoclue_address_details_copy (gw->address);
+ } else {
+ *address = geoclue_address_details_new ();
+ }
+ }
+ if (accuracy) {
+ if (gw) {
+ *accuracy = geoclue_accuracy_copy (gw->accuracy);
+ } else {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_localnet_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueLocalnet *localnet;
+
+ g_type_init ();
+
+ localnet = g_object_new (GEOCLUE_TYPE_LOCALNET, NULL);
+ localnet->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (localnet->loop);
+
+ g_main_loop_unref (localnet->loop);
+ g_object_unref (localnet);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Localnet
+Service=org.freedesktop.Geoclue.Providers.Localnet
+Path=/org/freedesktop/Geoclue/Providers/Localnet
+Interfaces=org.freedesktop.Geoclue.Address
+Accuracy=Street
+Provides=ProvidesCacheableOnConnection
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Localnet">
+ <method name="SetAddress">
+ <arg name="address" type="a{ss}" direction="in"/>
+ </method>
+ <method name="SetAddressFields">
+ <arg type="s" name="countrycode" direction="in"/>
+ <arg type="s" name="country" direction="in"/>
+ <arg type="s" name="region" direction="in"/>
+ <arg type="s" name="locality" direction="in"/>
+ <arg type="s" name="area" direction="in"/>
+ <arg type="s" name="postalcode" direction="in"/>
+ <arg type="s" name="street" direction="in"/>
+ </method>
+ </interface>
+</node>
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Localnet
+Exec=@libexecdir@/geoclue-localnet
--- /dev/null
+libexec_PROGRAMS = geoclue-manual
+
+noinst_DATA = \
+ geoclue-manual.xml
+
+nodist_geoclue_manual_SOURCES = \
+ geoclue-manual-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_manual_SOURCES)
+
+geoclue_manual_SOURCES = \
+ geoclue-manual.c
+
+geoclue_manual_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_manual_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-manual.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Manual.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-manual-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_manual_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-manual-glue.h: geoclue-manual.xml
+ $(DBUS_BINDING_TOOL) --prefix=geoclue_manual --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-manual.c - Manual address provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/** Geoclue manual provider
+ *
+ * This is an address provider which gets its address data from user
+ * input. No UI is included, any application may query the address from
+ * the user and submit it to manual provider through the D-Bus API:
+ * org.freedesktop.Geoclue.Manual.SetAddress
+ * org.freedesktop.Geoclue.Manual.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ * dbus-send --print-reply --type=method_call \
+ * --dest=org.freedesktop.Geoclue.Providers.Manual \
+ * /org/freedesktop/Geoclue/Providers/Manual \
+ * org.freedesktop.Geoclue.Manual.SetAddressFields \
+ * int32:7200 \
+ * string: \
+ * string:"Finland" \
+ * string: \
+ * string:"Helsinki" \
+ * string: \
+ * string: \
+ * string:"Solnantie 24"
+ *
+ * This would make the provider emit a AddressChanged signal with
+ * accuracy level GEOCLUE_ACCURACY_STREET. Unless new SetAddress* calls
+ * are made, provider will emit another signal in two hours (7200 sec),
+ * with empty address and GEOCLUE_ACCURACY_NONE.
+ **/
+
+#include <config.h>
+#include <string.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-address.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+
+ guint event_id;
+
+ int timestamp;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} GeoclueManual;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueManualClass;
+
+#define GEOCLUE_TYPE_MANUAL (geoclue_manual_get_type ())
+#define GEOCLUE_MANUAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_MANUAL, GeoclueManual))
+
+static void geoclue_manual_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueManual, geoclue_manual, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_manual_address_init))
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_until,
+ GHashTable *address,
+ GError **error);
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_until,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error);
+
+#include "geoclue-manual-glue.h"
+
+
+static GeoclueAccuracyLevel
+get_accuracy_for_address (GHashTable *address)
+{
+ if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_STREET)) {
+ return GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY)) {
+ return GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_REGION)) {
+ return GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRY) ||
+ g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ return GEOCLUE_ACCURACY_LEVEL_NONE;
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (provider);
+ g_main_loop_quit (manual->loop);
+}
+
+gboolean
+validity_ended (GeoclueManual *manual)
+{
+ manual->event_id = 0;
+ g_hash_table_remove_all (manual->address);
+ geoclue_accuracy_set_details (manual->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+ return FALSE;
+}
+
+
+static void
+geoclue_manual_set_address_common (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address)
+{
+ if (manual->event_id > 0) {
+ g_source_remove (manual->event_id);
+ }
+
+ manual->timestamp = time (NULL);
+
+ g_hash_table_destroy (manual->address);
+ manual->address = address;
+
+ geoclue_accuracy_set_details (manual->accuracy,
+ get_accuracy_for_address (address),
+ 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+
+ if (valid_for > 0) {
+ manual->event_id = g_timeout_add (valid_for * 1000,
+ (GSourceFunc)validity_ended,
+ manual);
+ }
+}
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address,
+ GError **error)
+{
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ geoclue_address_details_copy (address));
+ return TRUE;
+}
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_for,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ address);
+ return TRUE;
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (object);
+
+ g_hash_table_destroy (manual->address);
+ geoclue_accuracy_free (manual->accuracy);
+
+ ((GObjectClass *) geoclue_manual_parent_class)->finalize (object);
+}
+
+static void
+geoclue_manual_class_init (GeoclueManualClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_manual_get_type (),
+ &dbus_glib_geoclue_manual_object_info);
+}
+
+static void
+geoclue_manual_init (GeoclueManual *manual)
+{
+ gc_provider_set_details (GC_PROVIDER (manual),
+ "org.freedesktop.Geoclue.Providers.Manual",
+ "/org/freedesktop/Geoclue/Providers/Manual",
+ "Manual", "Manual provider");
+
+ manual->address = geoclue_address_details_new ();
+ manual->accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueManual *manual = GEOCLUE_MANUAL (gc);
+
+
+ if (timestamp) {
+ *timestamp = manual->timestamp;
+ }
+ if (address) {
+ *address = geoclue_address_details_copy (manual->address);
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_copy (manual->accuracy);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_manual_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueManual *manual;
+
+ g_type_init ();
+
+ manual = g_object_new (GEOCLUE_TYPE_MANUAL, NULL);
+ manual->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (manual->loop);
+
+ g_main_loop_unref (manual->loop);
+ g_object_unref (manual);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Manual
+Service=org.freedesktop.Geoclue.Providers.Manual
+Path=/org/freedesktop/Geoclue/Providers/Manual
+Interfaces=org.freedesktop.Geoclue.Address
+Provides=ProvidesUpdates
+Accuracy=Street
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Manual">
+ <method name="SetAddress">
+ <arg type="i" name="valid_for" direction="in"/>
+ <arg name="address" type="a{ss}" direction="in"/>
+ </method>
+ <method name="SetAddressFields">
+ <arg type="i" name="valid_for" direction="in"/>
+ <arg type="s" name="countrycode" direction="in"/>
+ <arg type="s" name="country" direction="in"/>
+ <arg type="s" name="region" direction="in"/>
+ <arg type="s" name="locality" direction="in"/>
+ <arg type="s" name="area" direction="in"/>
+ <arg type="s" name="postalcode" direction="in"/>
+ <arg type="s" name="street" direction="in"/>
+ </method>
+ </interface>
+</node>
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Manual
+Exec=@libexecdir@/geoclue-manual
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-nominatim
+
+NOINST_H_FILES = \
+ geoclue-nominatim.h
+
+geoclue_nominatim_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-nominatim.c
+
+geoclue_nominatim_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_nominatim_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-nominatim.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Nominatim.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-nominatim.c - A nominatim.openstreetmap.org-based "Geocode" and
+ * "Reverse geocode" provider
+ *
+ * Copyright 2010 by Intel Corporation
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ */
+
+/*
+ * The used web service APIs are documented at
+ * http://wiki.openstreetmap.org/wiki/Nominatim
+ *
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <string.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-address-details.h>
+#include <geoclue/geoclue-landmark.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-geocode.h>
+#include <geoclue/gc-iface-poi.h>
+#include <geoclue/gc-iface-reverse-geocode.h>
+#include "geoclue-nominatim.h"
+
+
+#define GEOCLUE_NOMINATIM_DBUS_SERVICE "org.freedesktop.Geoclue.Providers.Nominatim"
+#define GEOCLUE_NOMINATIM_DBUS_PATH "/org/freedesktop/Geoclue/Providers/Nominatim"
+
+#define GEOCODE_URL "http://nominatim.openstreetmap.org/search"
+#define REV_GEOCODE_URL "http://nominatim.openstreetmap.org/reverse"
+#define POI_URL "http://nominatim.openstreetmap.org/search"
+
+#define NOMINATIM_HOUSE "//reversegeocode/addressparts/house"
+#define NOMINATIM_ROAD "//reversegeocode/addressparts/road"
+#define NOMINATIM_VILLAGE "//reversegeocode/addressparts/village"
+#define NOMINATIM_SUBURB "//reversegeocode/addressparts/suburb"
+#define NOMINATIM_CITY "//reversegeocode/addressparts/city"
+#define NOMINATIM_POSTCODE "//reversegeocode/addressparts/postcode"
+#define NOMINATIM_COUNTY "//reversegeocode/addressparts/county"
+#define NOMINATIM_COUNTRY "//reversegeocode/addressparts/country"
+#define NOMINATIM_COUNTRYCODE "//reversegeocode/addressparts/country_code"
+
+#define NOMINATIM_LAT "//searchresults/place[1]/@lat"
+#define NOMINATIM_LON "//searchresults/place[1]/@lon"
+#define NOMINATIM_LATLON_HOUSE "//searchresults/place[1]/house"
+#define NOMINATIM_LATLON_ROAD "//searchresults/place[1]/road"
+#define NOMINATIM_LATLON_VILLAGE "//searchresults/place[1]/village"
+#define NOMINATIM_LATLON_SUBURB "//searchresults/place[1]/suburb"
+#define NOMINATIM_LATLON_POSTCODE "//searchresults/place[1]/postcode"
+#define NOMINATIM_LATLON_CITY "//searchresults/place[1]/city"
+#define NOMINATIM_LATLON_COUNTY "//searchresults/place[1]/county"
+#define NOMINATIM_LATLON_COUNTRY "//searchresults/place[1]/country"
+#define NOMINATIM_LATLON_COUNTRYCODE "//searchresults/place[1]/countrycode"
+
+#define NOMINATIM_SEARCH "//searchresults/place[%d]"
+#define NOMINATIM_SEARCH_ID NOMINATIM_SEARCH"/@place_id"
+#define NOMINATIM_SEARCH_RANK NOMINATIM_SEARCH"/@place_rank"
+#define NOMINATIM_SEARCH_BOUNDINGBOX NOMINATIM_SEARCH"/@boudingbox"
+#define NOMINATIM_SEARCH_DISPLAY_NAME NOMINATIM_SEARCH"/@display_name"
+#define NOMINATIM_SEARCH_ICON NOMINATIM_SEARCH"/@icon"
+#define NOMINATIM_SEARCH_LAT NOMINATIM_SEARCH"/@lat"
+#define NOMINATIM_SEARCH_LON NOMINATIM_SEARCH"/@lon"
+#define NOMINATIM_SEARCH_HOUSE NOMINATIM_SEARCH"/house"
+#define NOMINATIM_SEARCH_ROAD NOMINATIM_SEARCH"/road"
+#define NOMINATIM_SEARCH_VILLAGE NOMINATIM_SEARCH"/village"
+#define NOMINATIM_SEARCH_SUBURB NOMINATIM_SEARCH"/suburb"
+#define NOMINATIM_SEARCH_POSTCODE NOMINATIM_SEARCH"/postcode"
+#define NOMINATIM_SEARCH_CITY NOMINATIM_SEARCH"/city"
+#define NOMINATIM_SEARCH_COUNTY NOMINATIM_SEARCH"/county"
+#define NOMINATIM_SEARCH_COUNTRY NOMINATIM_SEARCH"/country"
+#define NOMINATIM_SEARCH_COUNTRYCODE NOMINATIM_SEARCH"/countrycode"
+
+
+
+
+static void geoclue_nominatim_init (GeoclueNominatim *obj);
+static void geoclue_nominatim_geocode_init (GcIfaceGeocodeClass *iface);
+static void geoclue_nominatim_reverse_geocode_init (GcIfaceReverseGeocodeClass *iface);
+static void geoclue_nominatim_poi_init (GcIfacePoiClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueNominatim, geoclue_nominatim, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_GEOCODE,
+ geoclue_nominatim_geocode_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_REVERSE_GEOCODE,
+ geoclue_nominatim_reverse_geocode_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POI,
+ geoclue_nominatim_poi_init))
+
+/* Geoclue interface implementation */
+
+static gboolean
+geoclue_nominatim_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assumption that we are available so long as the
+ providers requirements are met: ie network is up */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueNominatim *obj = GEOCLUE_NOMINATIM (provider);
+
+ g_main_loop_quit (obj->loop);
+}
+
+
+static void
+search_string_append (GString *str, const char *val)
+{
+ if (!val || strlen (val) == 0) {
+ return;
+ }
+
+ if (str->len != 0) {
+ g_string_append (str, ", ");
+ }
+ g_string_append (str, val);
+}
+
+static GeoclueAccuracy*
+get_geocode_accuracy (GcWebService *geocoder)
+{
+ char *str;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (gc_web_service_get_string (geocoder, &str, NOMINATIM_LATLON_HOUSE)) {
+ level = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+ } else if (gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_ROAD)) {
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_SUBURB) ||
+ gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_POSTCODE) ||
+ gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_VILLAGE)) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_CITY)) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_COUNTY)) {
+ level = GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_COUNTRY) ||
+ gc_web_service_get_string (geocoder, &str,
+ NOMINATIM_LATLON_COUNTRYCODE)) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+
+ return geoclue_accuracy_new (level, 0, 0);
+}
+
+/* Geocode interface implementation */
+static gboolean
+geoclue_nominatim_address_to_position (GcIfaceGeocode *iface,
+ GHashTable *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueNominatim *obj = GEOCLUE_NOMINATIM (iface);
+ gchar *country, *region, *locality, *postalcode, *street;
+ GString *str;
+
+ country = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ locality = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY);
+ postalcode = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE);
+ region = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_REGION);
+ street = g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_STREET);
+
+ str = g_string_new ("");
+ search_string_append (str, street);
+ search_string_append (str, locality);
+ search_string_append (str, region);
+ search_string_append (str, postalcode);
+ search_string_append (str, country);
+
+ if (!gc_web_service_query (obj->geocoder, error,
+ "q", str->str,
+ "format", "xml",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ g_string_free (str, TRUE);
+ return FALSE;
+ }
+ g_string_free (str, TRUE);
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (latitude && gc_web_service_get_double (obj->geocoder,
+ latitude, NOMINATIM_LAT)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+
+ if (longitude && gc_web_service_get_double (obj->geocoder,
+ longitude, NOMINATIM_LON)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (accuracy) {
+ *accuracy = get_geocode_accuracy (obj->geocoder);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+geoclue_nominatim_freeform_address_to_position (GcIfaceGeocode *iface,
+ const char *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueNominatim *obj = GEOCLUE_NOMINATIM (iface);
+
+ if (!gc_web_service_query (obj->geocoder, error,
+ "q", address,
+ "format", "xml",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (latitude && gc_web_service_get_double (obj->geocoder,
+ latitude, NOMINATIM_LAT)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+
+ if (longitude && gc_web_service_get_double (obj->geocoder,
+ longitude, NOMINATIM_LON)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (accuracy) {
+ *accuracy = get_geocode_accuracy (obj->geocoder);
+ }
+
+ return TRUE;
+}
+
+/* ReverseGeocode interface implementation */
+
+static gboolean
+geoclue_nominatim_position_to_address (GcIfaceReverseGeocode *iface,
+ double latitude,
+ double longitude,
+ GeoclueAccuracy *position_accuracy,
+ GHashTable **address,
+ GeoclueAccuracy **address_accuracy,
+ GError **error)
+{
+ GeoclueNominatim *obj = GEOCLUE_NOMINATIM (iface);
+ gchar *locality = NULL;
+ gchar *region = NULL;
+ gchar *country = NULL;
+ gchar *countrycode = NULL;
+ gchar *area = NULL;
+ gchar *street = NULL;
+ gchar *postcode = NULL;
+
+ GeoclueAccuracyLevel in_acc = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+ gchar lat[G_ASCII_DTOSTR_BUF_SIZE];
+ gchar lon[G_ASCII_DTOSTR_BUF_SIZE];
+
+ if (!address) {
+ return TRUE;
+ }
+
+ g_ascii_dtostr (lat, G_ASCII_DTOSTR_BUF_SIZE, latitude);
+ g_ascii_dtostr (lon, G_ASCII_DTOSTR_BUF_SIZE, longitude);
+ if (!gc_web_service_query (obj->rev_geocoder, error,
+ "lat", lat,
+ "lon", lon,
+ "format", "xml",
+ "zoom", "18", /* could set this based on position_accuracy */
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+
+ if (position_accuracy) {
+ geoclue_accuracy_get_details (position_accuracy, &in_acc, NULL, NULL);
+ }
+
+ *address = geoclue_address_details_new ();
+
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_COUNTRY &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &countrycode, NOMINATIM_COUNTRYCODE)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ countrycode);
+ g_free (countrycode);
+ geoclue_address_details_set_country_from_code (*address);
+ }
+ if (!g_hash_table_lookup (*address, GEOCLUE_ADDRESS_KEY_COUNTRY) &&
+ in_acc >= GEOCLUE_ACCURACY_LEVEL_COUNTRY &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &country, NOMINATIM_COUNTRY)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ country);
+ g_free (country);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_REGION &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ ®ion, NOMINATIM_COUNTY)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_REGION,
+ region);
+ g_free (region);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_LOCALITY &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &locality, NOMINATIM_CITY)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ locality);
+ g_free (locality);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_POSTALCODE &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &area, NOMINATIM_VILLAGE)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_AREA,
+ area);
+ g_free (area);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_POSTALCODE &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &postcode, NOMINATIM_POSTCODE)) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ postcode);
+ g_free (postcode);
+ }
+ if (in_acc >= GEOCLUE_ACCURACY_LEVEL_STREET &&
+ gc_web_service_get_string (obj->rev_geocoder,
+ &street, NOMINATIM_ROAD)) {
+ char *nr;
+
+ if (gc_web_service_get_string (obj->rev_geocoder,
+ &nr, NOMINATIM_HOUSE)) {
+ char *full_street = g_strdup_printf ("%s %s", street, nr);
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ full_street);
+ g_free (nr);
+ g_free (full_street);
+ } else {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ street);
+ }
+ g_free (street);
+ }
+
+ if (address_accuracy) {
+ GeoclueAccuracyLevel level = geoclue_address_details_get_accuracy_level (*address);
+ *address_accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ return TRUE;
+}
+
+gboolean _parsing_boundary (char *boundary_src, gdouble *top, gdouble *left, gdouble *bottom, gdouble *right)
+{
+ g_return_val_if_fail (boundary_src, FALSE);
+
+ char *ptr = NULL;
+
+ ptr = strtok (boundary_src, ",");
+ if (!ptr) return FALSE;
+ *top = atof (ptr);
+
+ ptr = strtok (NULL, ",");
+ if (!ptr) return FALSE;
+ *left = atof (ptr);
+
+ ptr = strtok (NULL, ",");
+ if (!ptr) return FALSE;
+ *bottom = atof (ptr);
+
+ ptr = strtok (NULL, ",");
+ if (!ptr) return FALSE;
+ *right = atof (ptr);
+
+ return TRUE;
+}
+
+gboolean _get_landmark_data (GeoclueNominatim *obj, int index, GeoclueLandmark *landmark_info)
+{
+ g_return_val_if_fail (index > -1, FALSE);
+ g_return_val_if_fail (landmark_info, FALSE);
+
+ gdouble left = 0.0, top = 0.0, right = 0.0, bottom = 0.0;
+ gboolean ret = FALSE;
+
+ gchar buf[128] = {0,};
+ gchar *str = NULL;
+
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_ID, index);
+ if (!gc_web_service_get_string(obj->poi, &str, buf)) {
+ return FALSE;
+ }
+
+ if (str) {
+ landmark_info->id = atoi (str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_RANK, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->rank = atoi (str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_ICON, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->icon = g_strdup(str);
+ g_free (str);
+ }
+ snprintf(buf, 128, NOMINATIM_SEARCH_DISPLAY_NAME, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->name = g_strdup(str);
+ g_free (str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_BOUNDINGBOX, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ ret = _parsing_boundary (str, &top, &left, &bottom, &right);
+ if (ret) {
+ landmark_info->boundary_left = left;
+ landmark_info->boundary_top = top;
+ landmark_info->boundary_right = right;
+ landmark_info->boundary_bottom = bottom;
+ }
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_LAT, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->lat = atof (str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_LON, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->lon = atof (str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_HOUSE, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->house = g_strdup(str);
+ g_free(str);
+ }
+ snprintf(buf, 128, NOMINATIM_SEARCH_ROAD, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->road = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_VILLAGE, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->village = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_SUBURB, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->suburb = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_POSTCODE, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->postcode = g_strdup(str);
+ g_free(str);
+ }
+ snprintf(buf, 128, NOMINATIM_SEARCH_CITY, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->city = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_COUNTY, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->county = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_COUNTRY, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->country = g_strdup(str);
+ g_free(str);
+ }
+
+ snprintf(buf, 128, NOMINATIM_SEARCH_COUNTRYCODE, index);
+ if (gc_web_service_get_string(obj->poi, &str, buf)) {
+ landmark_info->country_code = g_strdup(str);
+ g_free(str);
+ }
+
+ return TRUE;
+}
+
+
+/* Poi interface implementation */
+static gboolean
+geoclue_nominatim_poi_search_by_position (GcIfacePoi *iface,
+ const char *keyword,
+ const char *lang,
+ const char *country_code,
+ int limit,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int *count,
+ GPtrArray **landmark,
+ GError **error)
+{
+ g_return_val_if_fail (landmark, FALSE);
+
+ GeoclueNominatim *obj = GEOCLUE_NOMINATIM (iface);
+ *landmark = NULL;
+
+ int index = 1;
+ gboolean ret = FALSE;
+ gchar str_limit [6] = {0, };
+ GeoclueLandmark landmark_data = {0, };
+
+
+ snprintf(str_limit, 6, "%d", limit);
+
+ if (left || top || right || bottom) {
+ /* Viewbox is available */
+ gchar viewbox[64] = {0, };
+
+ /* VIEWBOX FORMAT (LEFT_TOP_LONGITUDE,LEFT_TOP_LATITUDE, RIGHT_BOTTOM_LONGITUDE, RIGHT_BOTTOM_LATITUDE */
+ snprintf(viewbox, 64, "%d,%d,%d,%d", top, left, bottom, right);
+
+ if (country_code) {
+ if (!gc_web_service_query (obj->poi, error,
+ "q", keyword,
+ "accept-language", lang,
+ "countrycodes", country_code,
+ "limit", str_limit,
+ "viewbox", viewbox,
+ "format", "xml",
+ "bounded", "1",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+ }
+ else {
+ if (!gc_web_service_query (obj->poi, error,
+ "q", keyword,
+ "accept-language", lang,
+ "limit", str_limit,
+ "viewbox", viewbox,
+ "format", "xml",
+ "bounded", "1",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+ }
+ }
+ else {
+ /* There is no viewbox. */
+ if (country_code) {
+ if (!gc_web_service_query (obj->poi, error,
+ "q", keyword,
+ "accept-language", lang,
+ "countrycodes", country_code,
+ "limit", str_limit,
+ "format", "xml",
+ "bounded", "0",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+ }
+ else {
+ if (!gc_web_service_query (obj->poi, error,
+ "q", keyword,
+ "accept-language", lang,
+ "limit", str_limit,
+ "format", "xml",
+ "bounded", "0",
+ "polygon", "0",
+ "addressdetails", "1",
+ (char *)0)) {
+ return FALSE;
+ }
+ }
+ }
+
+ *landmark = g_ptr_array_new();
+
+ while (1) {
+ ret = _get_landmark_data (obj, index, &landmark_data);
+ if (ret == FALSE) {
+ index--;
+ break;
+ }
+
+ GValue v_poi = {0, };
+ g_value_init (&v_poi, GEOCLUE_LANDMARK);
+ g_value_take_boxed (&v_poi, dbus_g_type_specialized_construct (GEOCLUE_LANDMARK));
+
+ dbus_g_type_struct_set(&v_poi,
+ 0, landmark_data.id,
+ 1, landmark_data.rank,
+ 2, landmark_data.lat,
+ 3, landmark_data.lon,
+ 4, landmark_data.boundary_left,
+ 5, landmark_data.boundary_top,
+ 6, landmark_data.boundary_right,
+ 7, landmark_data.boundary_bottom,
+ 8, landmark_data.name,
+ 9, landmark_data.icon,
+ 10, landmark_data.house,
+ 11, landmark_data.road,
+ 12, landmark_data.village,
+ 13, landmark_data.suburb,
+ 14, landmark_data.city,
+ 15, landmark_data.county,
+ 16, landmark_data.country,
+ 17, landmark_data.country_code,
+ G_MAXUINT);
+
+ g_ptr_array_add (*landmark, g_value_get_boxed(&v_poi));
+
+ index++;
+ }
+
+ *count = index;
+
+ return TRUE;
+}
+
+static void
+geoclue_nominatim_finalize (GObject *obj)
+{
+ ((GObjectClass *) geoclue_nominatim_parent_class)->finalize (obj);
+}
+
+static void
+geoclue_nominatim_dispose (GObject *obj)
+{
+ GeoclueNominatim *self = (GeoclueNominatim *) obj;
+
+ if (self->geocoder) {
+ g_object_unref (self->geocoder);
+ self->geocoder = NULL;
+ }
+
+ if (self->rev_geocoder) {
+ g_object_unref (self->rev_geocoder);
+ self->rev_geocoder = NULL;
+ }
+
+ if (self->poi) {
+ g_object_unref (self->poi);
+ self->poi = NULL;
+ }
+
+ ((GObjectClass *) geoclue_nominatim_parent_class)->dispose (obj);
+}
+
+/* Initialization */
+
+static void
+geoclue_nominatim_class_init (GeoclueNominatimClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_nominatim_get_status;
+
+ o_class->finalize = geoclue_nominatim_finalize;
+ o_class->dispose = geoclue_nominatim_dispose;
+}
+
+static void
+geoclue_nominatim_init (GeoclueNominatim *obj)
+{
+ gc_provider_set_details (GC_PROVIDER (obj),
+ GEOCLUE_NOMINATIM_DBUS_SERVICE,
+ GEOCLUE_NOMINATIM_DBUS_PATH,
+ "Nominatim", "Nominatim (OpenStreetMap geocoder) provider");
+
+ obj->geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->geocoder, GEOCODE_URL);
+
+ obj->rev_geocoder = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->rev_geocoder, REV_GEOCODE_URL);
+
+ obj->poi = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (obj->poi, GEOCODE_URL);
+}
+
+static void
+geoclue_nominatim_geocode_init (GcIfaceGeocodeClass *iface)
+{
+ iface->address_to_position = geoclue_nominatim_address_to_position;
+ iface->freeform_address_to_position = geoclue_nominatim_freeform_address_to_position;
+}
+
+static void
+geoclue_nominatim_poi_init (GcIfacePoiClass *iface)
+{
+ iface->search_by_position = geoclue_nominatim_poi_search_by_position;
+}
+
+static void
+geoclue_nominatim_reverse_geocode_init (GcIfaceReverseGeocodeClass *iface)
+{
+ iface->position_to_address = geoclue_nominatim_position_to_address;
+}
+
+int
+main()
+{
+ GeoclueNominatim *obj;
+
+ g_type_init();
+ obj = g_object_new (GEOCLUE_TYPE_NOMINATIM, NULL);
+ obj->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (obj->loop);
+
+ g_main_loop_unref (obj->loop);
+ g_object_unref (obj);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-nominatim.h - A Geocode/ReverseGeocode provider for nominatim.openstreetmap.org
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ */
+
+#ifndef _GEOCLUE_NOMINATIM
+#define _GEOCLUE_NOMINATIM
+
+#include <glib-object.h>
+#include <geoclue/gc-web-service.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_NOMINATIM (geoclue_nominatim_get_type ())
+
+#define GEOCLUE_NOMINATIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_NOMINATIM, GeoclueNominatim))
+#define GEOCLUE_NOMINATIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_NOMINATIM, GeoclueNominatimClass))
+#define GEOCLUE_IS_NOMINATIM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_NOMINATIM))
+#define GEOCLUE_IS_NOMINATIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_NOMINATIM))
+
+typedef struct _GeoclueNominatim {
+ GcProvider parent;
+ GMainLoop *loop;
+
+ GcWebService *geocoder;
+ GcWebService *rev_geocoder;
+ GcWebService *poi;
+} GeoclueNominatim;
+
+typedef struct _GeoclueNominatimClass {
+ GcProviderClass parent_class;
+} GeoclueNominatimClass;
+
+typedef struct _GeocluePOIData {
+ gint id;
+ gint rank;
+ gdouble lat;
+ gdouble lon;
+ gdouble boundary_left;
+ gdouble boundary_top;
+ gdouble boudnary_right;
+ gdouble boundary_bottom;
+ gchar *name;
+ gchar *icon;
+ gchar *house;
+ gchar *road;
+ gchar *village;
+ gchar *suburb;
+ gchar *city;
+ gchar *county;
+ gchar *country;
+ gchar *country_code;
+} GeocluePOIData;
+
+GType geoclue_nominatim_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+[Geoclue Provider]
+Name=Nominatim (OpenStreetMap geocoder) Provider
+Service=org.freedesktop.Geoclue.Providers.Nominatim
+Path=/org/freedesktop/Geoclue/Providers/Nominatim
+Requires=RequiresNetwork
+Accuracy=Street
+Interfaces=org.freedesktop.Geoclue.Geocode;org.freedesktop.Geoclue.ReverseGeocode;org.freedesktop.Geoclue.Poi
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Nominatim
+Exec=@libexecdir@/geoclue-nominatim
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-plazes
+
+geoclue_plazes_SOURCES = \
+ geoclue-plazes.c
+
+geoclue_plazes_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_plazes_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-plazes.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Plazes.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-plazes.c - A plazes.com-based Address/Position provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#define GEOCLUE_DBUS_SERVICE_PLAZES "org.freedesktop.Geoclue.Providers.Plazes"
+#define GEOCLUE_DBUS_PATH_PLAZES "/org/freedesktop/Geoclue/Providers/Plazes"
+#define PLAZES_URL "http://plazes.com/suggestions.xml"
+#define PLAZES_KEY_MAC "mac_address"
+#define PLAZES_LAT_XPATH "//plaze/latitude"
+#define PLAZES_LON_XPATH "//plaze/longitude"
+
+#define GEOCLUE_TYPE_PLAZES (geoclue_plazes_get_type ())
+#define GEOCLUE_PLAZES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_PLAZES, GeocluePlazes))
+
+typedef struct _GeocluePlazes {
+ GcProvider parent;
+ GMainLoop *loop;
+ GcWebService *web_service;
+ GeoclueStatus last_status;
+} GeocluePlazes;
+
+typedef struct _GeocluePlazesClass {
+ GcProviderClass parent_class;
+} GeocluePlazesClass;
+
+
+static void geoclue_plazes_init (GeocluePlazes *plazes);
+static void geoclue_plazes_position_init (GcIfacePositionClass *iface);
+static void geoclue_plazes_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeocluePlazes, geoclue_plazes, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_plazes_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_plazes_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_plazes_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+
+ *status = plazes->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (provider);
+ g_main_loop_quit (plazes->loop);
+}
+
+static void
+geoclue_plazes_set_status (GeocluePlazes *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self), status);
+ }
+}
+
+/* Parse /proc/net/route to get default gateway address and then parse
+ * /proc/net/arp to find matching mac address.
+ *
+ * There are some problems with this. First, it's IPv4 only.
+ * Second, there must be a way to do this with ioctl, but that seemed really
+ * complicated... even /usr/sbin/arp parses /proc/net/arp
+ *
+ * returns:
+ * 1 : on success
+ * 0 : no success, no errors
+ * <0 : error
+ */
+int
+get_mac_address (char **mac)
+{
+ char *content;
+ char **lines, **entry;
+ GError *error = NULL;
+ char *route_gateway = NULL;
+
+ g_assert (*mac == NULL);
+
+ if (!g_file_get_contents ("/proc/net/route", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/route: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines + 1;
+
+ while (*entry && strlen (*entry) > 0) {
+ char dest[9];
+ char gateway[9];
+ if (sscanf (*entry,
+ "%*s %8[0-9A-Fa-f] %8[0-9A-Fa-f] %*s",
+ dest, gateway) != 2) {
+ g_warning ("Failed to parse /proc/net/route entry '%s'", *entry);
+ } else if (strcmp (dest, "00000000") == 0) {
+ route_gateway = g_strdup (gateway);
+ break;
+ }
+ entry++;
+ }
+ g_strfreev (lines);
+
+ if (!route_gateway) {
+ g_warning ("Failed to find default route in /proc/net/route");
+ return -1;
+ }
+
+ if (!g_file_get_contents ("/proc/net/arp", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/arp: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines+1;
+ while (*entry && strlen (*entry) > 0) {
+ char hwa[100];
+ char *arp_gateway;
+ int ip[4];
+
+ if (sscanf(*entry,
+ "%d.%d.%d.%d 0x%*x 0x%*x %100s %*s %*s\n",
+ &ip[0], &ip[1], &ip[2], &ip[3], hwa) != 5) {
+ g_warning ("Failed to parse /proc/net/arp entry '%s'", *entry);
+ } else {
+ arp_gateway = g_strdup_printf ("%02X%02X%02X%02X", ip[3], ip[2], ip[1], ip[0]);
+ if (strcmp (arp_gateway, route_gateway) == 0) {
+ g_free (arp_gateway);
+ *mac = g_strdup (hwa);
+ break;
+ }
+ g_free (arp_gateway);
+
+ }
+ entry++;
+ }
+ g_free (route_gateway);
+ g_strfreev (lines);
+
+ return *mac ? 1 : 0;
+}
+
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_plazes_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeocluePlazes *plazes;
+ int i, ret_val;
+ char *mac = NULL;
+
+ plazes = (GEOCLUE_PLAZES (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ /* we may be trying to read /proc/net/arp right after network connection.
+ * It's sometimes not up yet, try a couple of times */
+ for (i = 0; i < 5; i++) {
+ ret_val = get_mac_address (&mac);
+ if (ret_val < 0)
+ return FALSE;
+ else if (ret_val == 1)
+ break;
+ usleep (200);
+ }
+
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac,
+ (char *)0)) {
+ g_free (mac);
+ // did not get a reply; we can try again later
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+
+ if (latitude && gc_web_service_get_double (plazes->web_service,
+ latitude, PLAZES_LAT_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (longitude && gc_web_service_get_double (plazes->web_service,
+ longitude, PLAZES_LON_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (accuracy) {
+ /* Educated guess. Plazes are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET, 0, 0);
+ }
+
+ if (!(*fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ *fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+
+static gboolean
+geoclue_plazes_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+ int i, ret_val;
+ char *mac = NULL;
+
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ /* we may be trying to read /proc/net/arp right after network connection.
+ * It's sometimes not up yet, try a couple of times */
+ for (i = 0; i < 5; i++) {
+ ret_val = get_mac_address (&mac);
+ if (ret_val < 0)
+ return FALSE;
+ else if (ret_val == 1)
+ break;
+ usleep (200);
+ }
+
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac,
+ (char *)0)) {
+ g_free (mac);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+
+ if (address) {
+ char *str;
+
+ *address = geoclue_address_details_new ();
+
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/city")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/zip_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/address")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ }
+ }
+
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_plazes_finalize (GObject *obj)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (obj);
+
+ g_object_unref (plazes->web_service);
+
+ ((GObjectClass *) geoclue_plazes_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_plazes_class_init (GeocluePlazesClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_plazes_get_status;
+
+ o_class->finalize = geoclue_plazes_finalize;
+}
+
+static void
+geoclue_plazes_init (GeocluePlazes *plazes)
+{
+ gc_provider_set_details (GC_PROVIDER (plazes),
+ GEOCLUE_DBUS_SERVICE_PLAZES,
+ GEOCLUE_DBUS_PATH_PLAZES,
+ "Plazes", "Plazes.com based provider, uses gateway mac address to locate");
+
+ plazes->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (plazes->web_service, PLAZES_URL);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+}
+
+static void
+geoclue_plazes_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_plazes_get_position;
+}
+
+static void
+geoclue_plazes_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_plazes_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeocluePlazes *o = g_object_new (GEOCLUE_TYPE_PLAZES, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Plazes
+Service=org.freedesktop.Geoclue.Providers.Plazes
+Path=/org/freedesktop/Geoclue/Providers/Plazes
+Accuracy=Street
+Requires=RequiresNetwork
+Provides=ProvidesCacheableOnConnection
+Interfaces=org.freedesktop.Geoclue.Position;org.freedesktop.Geoclue.Address
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Plazes
+Exec=@libexecdir@/geoclue-plazes
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-skyhook
+
+geoclue_skyhook_SOURCES = \
+ geoclue-skyhook.c
+
+geoclue_skyhook_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(SKYHOOK_CFLAGS)
+
+geoclue_skyhook_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(SKYHOOK_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-skyhook.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Skyhook.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-skyhook.c - A skyhook.com-based Address/Position provider
+ *
+ * Author: Bastien Nocera <hadess@hadess.net>
+ * Copyright 2009 Bastien Nocera
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <libsoup/soup.h>
+#include <libxml/xpathInternals.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+
+#define GEOCLUE_DBUS_SERVICE_SKYHOOK "org.freedesktop.Geoclue.Providers.Skyhook"
+#define GEOCLUE_DBUS_PATH_SKYHOOK "/org/freedesktop/Geoclue/Providers/Skyhook"
+#define SKYHOOK_URL "https://api.skyhookwireless.com/wps2/location"
+#define SKYHOOK_LAT_XPATH "//prefix:latitude"
+#define SKYHOOK_LON_XPATH "//prefix:longitude"
+#define USER_AGENT "Geoclue "VERSION
+
+#define GEOCLUE_TYPE_SKYHOOK (geoclue_skyhook_get_type ())
+#define GEOCLUE_SKYHOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_SKYHOOK, GeoclueSkyhook))
+
+#define QUERY "<?xml version=\'1.0\'?><LocationRQ xmlns=\'http://skyhookwireless.com/wps/2005\' version=\'2.6\' street-address-lookup=\'full\'><authentication version=\'2.0\'><simple><username>beta</username><realm>js.loki.com</realm></simple></authentication><access-point><mac>%s</mac><signal-strength>-50</signal-strength></access-point></LocationRQ>"
+
+typedef struct _GeoclueSkyhook {
+ GcProvider parent;
+ GMainLoop *loop;
+ SoupSession *session;
+} GeoclueSkyhook;
+
+typedef struct _GeoclueSkyhookClass {
+ GcProviderClass parent_class;
+} GeoclueSkyhookClass;
+
+
+static void geoclue_skyhook_init (GeoclueSkyhook *skyhook);
+static void geoclue_skyhook_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueSkyhook, geoclue_skyhook, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_skyhook_position_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_skyhook_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assume available so long as all the requirements are satisfied
+ ie: Network is available */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+_shutdown (GcProvider *provider)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (provider);
+ g_main_loop_quit (skyhook->loop);
+}
+
+#define MAC_LEN 18
+
+static char *
+get_mac_address (void)
+ {
+ /* this is an ugly hack, but it seems there is no easy
+ * ioctl-based way to get the mac address of the router. This
+ * implementation expects the system to have netstat, grep and awk
+ * */
+
+ FILE *in;
+ char mac[MAC_LEN];
+ int i;
+
+ /*for some reason netstat or /proc/net/arp isn't always ready
+ * when a connection is already up... Try a couple of times */
+ for (i=0; i<10; i++) {
+ if (!(in = popen ("ROUTER_IP=`netstat -rn | grep '^0.0.0.0 ' | awk '{ print $2 }'` && grep \"^$ROUTER_IP \" /proc/net/arp | awk '{print $4}'", "r"))) {
+ g_warning ("popen failed");
+ return NULL;
+ }
+
+ if (!(fgets (mac, MAC_LEN, in))) {
+ if (errno != ENOENT && errno != EAGAIN) {
+ g_debug ("error %d", errno);
+ return NULL;
+ }
+ /* try again */
+ pclose (in);
+ g_debug ("trying again...");
+ g_usleep (200);
+ continue;
+ }
+ pclose (in);
+ return g_strdup (mac);
+ }
+ return NULL;
+}
+
+static char *
+create_post_query (void)
+{
+ char *mac, *query;
+ char **split;
+
+ mac = get_mac_address ();
+ if (mac == NULL)
+ return NULL;
+ /* Remove the ":" */
+ split = g_strsplit (mac, ":", -1);
+ g_free (mac);
+ if (split == NULL)
+ return NULL;
+ mac = g_strjoinv ("", split);
+ g_strfreev (split);
+
+ query = g_strdup_printf (QUERY, mac);
+ g_free (mac);
+
+ return query;
+}
+
+static gboolean
+get_double (xmlXPathContext *xpath_ctx, char *xpath, gdouble *value)
+{
+ xmlXPathObject *obj = NULL;
+
+ obj = xmlXPathEvalExpression (BAD_CAST (xpath), xpath_ctx);
+ if (obj &&
+ (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval))) {
+ xmlXPathFreeObject (obj);
+ return FALSE;
+ }
+ *value = xmlXPathCastNodeSetToNumber (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+static gboolean
+parse_response (const char *body, gdouble *latitude, gdouble *longitude)
+{
+ xmlDocPtr doc;
+ xmlXPathContext *xpath_ctx;
+ gboolean ret = TRUE;
+
+ doc = xmlParseDoc (BAD_CAST (body));
+ if (!doc)
+ return FALSE;
+
+ xpath_ctx = xmlXPathNewContext(doc);
+ if (!xpath_ctx) {
+ xmlFreeDoc (doc);
+ return FALSE;
+ }
+ xmlXPathRegisterNs (xpath_ctx, BAD_CAST ("prefix"), BAD_CAST("http://skyhookwireless.com/wps/2005"));
+ if (get_double (xpath_ctx, SKYHOOK_LAT_XPATH, latitude) == FALSE) {
+ ret = FALSE;
+ } else if (get_double (xpath_ctx, SKYHOOK_LON_XPATH, longitude) == FALSE) {
+ ret = FALSE;
+ }
+ xmlXPathFreeContext (xpath_ctx);
+ xmlFreeDoc (doc);
+
+ return ret;
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_skyhook_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueSkyhook *skyhook;
+ char *query;
+ SoupMessage *msg;
+
+ skyhook = (GEOCLUE_SKYHOOK (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp)
+ *timestamp = time (NULL);
+
+ query = create_post_query ();
+ if (query == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ /* TODO: set status == error ? */
+ return FALSE;
+ }
+
+ msg = soup_message_new ("POST", SKYHOOK_URL);
+ soup_message_headers_append (msg->request_headers, "User-Agent", USER_AGENT);
+ soup_message_set_request (msg,
+ "text/xml",
+ SOUP_MEMORY_TAKE,
+ query,
+ strlen (query));
+ soup_session_send_message (skyhook->session, msg);
+ if (msg->response_body == NULL || msg->response_body->data == NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Failed to query web service");
+ return FALSE;
+ }
+
+ if (strstr (msg->response_body->data, "<error>") != NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Web service returned an error");
+ return FALSE;
+ }
+
+ if (parse_response (msg->response_body->data, latitude, longitude) == FALSE) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Couldn't parse response from web service");
+ return FALSE;
+ }
+
+ if (latitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ if (longitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+
+ if (accuracy) {
+ if (*fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0, 0);
+ } else {
+ /* Educated guess. Skyhook are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET,
+ 0, 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_skyhook_finalize (GObject *obj)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (obj);
+
+ g_object_unref (skyhook->session);
+
+ ((GObjectClass *) geoclue_skyhook_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_skyhook_class_init (GeoclueSkyhookClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = _shutdown;
+ p_class->get_status = geoclue_skyhook_get_status;
+
+ o_class->finalize = geoclue_skyhook_finalize;
+}
+
+static void
+geoclue_skyhook_init (GeoclueSkyhook *skyhook)
+{
+ gc_provider_set_details (GC_PROVIDER (skyhook),
+ GEOCLUE_DBUS_SERVICE_SKYHOOK,
+ GEOCLUE_DBUS_PATH_SKYHOOK,
+ "Skyhook", "Skyhook.com based provider, uses gateway mac address to locate");
+ skyhook->session = soup_session_sync_new ();
+}
+
+static void
+geoclue_skyhook_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_skyhook_get_position;
+}
+
+int
+main()
+{
+ g_type_init();
+ g_thread_init (NULL);
+
+ GeoclueSkyhook *o = g_object_new (GEOCLUE_TYPE_SKYHOOK, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Plazes
+Service=org.freedesktop.Geoclue.Providers.Skyhook
+Path=/org/freedesktop/Geoclue/Providers/Skyhook
+Accuracy=Street
+Requires=RequiresNetwork
+Provides=ProvidesCacheableOnConnection
+Interfaces=org.freedesktop.Geoclue.Position
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Skyhook
+Exec=@libexecdir@/geoclue-skyhook
--- /dev/null
+libexec_PROGRAMS = \
+ geoclue-yahoo
+
+geoclue_yahoo_SOURCES = \
+ geoclue-yahoo.c
+
+geoclue_yahoo_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_yahoo_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-yahoo.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Yahoo.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-yahoo.c - A "local.yahooapis.com"-based Geocode-provider which
+ * converts from street address to position.
+ *
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <string.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-web-service.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-geocode.h>
+
+#define YAHOO_GEOCLUE_APP_ID "zznSbDjV34HRU5CXQc4D3qE1DzCsJTaKvWTLhNJxbvI_JTp1hIncJ4xTSJFRgjE-"
+#define YAHOO_BASE_URL "http://api.local.yahoo.com/MapsService/V1/geocode"
+#define GEOCLUE_TYPE_YAHOO (geoclue_yahoo_get_type ())
+#define GEOCLUE_YAHOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_YAHOO, GeoclueYahoo))
+
+typedef struct _GeoclueYahoo {
+ GcProvider parent;
+ GMainLoop *loop;
+
+ GcWebService *web_service;
+} GeoclueYahoo;
+
+typedef struct _GeoclueYahooClass {
+ GcProviderClass parent_class;
+} GeoclueYahooClass;
+
+
+static void geoclue_yahoo_init (GeoclueYahoo *obj);
+static void geoclue_yahoo_geocode_init (GcIfaceGeocodeClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueYahoo, geoclue_yahoo, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_GEOCODE,
+ geoclue_yahoo_geocode_init))
+
+
+/* Geoclue interface implementation */
+
+static gboolean
+geoclue_yahoo_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assumption that we are available so long as the
+ providers requirements are met: ie network is up */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueYahoo *yahoo = GEOCLUE_YAHOO (provider);
+
+ g_main_loop_quit (yahoo->loop);
+}
+
+
+static char *
+get_address_value (GHashTable *address, char *key)
+{
+ char *value;
+
+ value = g_strdup (g_hash_table_lookup (address, key));
+ if (!value) {
+ value = g_strdup ("");
+ }
+ return value;
+}
+
+static GeoclueAccuracyLevel
+get_query_accuracy_level (GeoclueYahoo *yahoo)
+{
+ char *precision = NULL;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ gc_web_service_get_string (yahoo->web_service,
+ &precision, "//yahoo:Result/attribute::precision");
+ if (precision) {
+ if ((strcmp (precision, "street") == 0) ||
+ (strcmp (precision, "address") == 0)) {
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if ((strcmp (precision, "zip") == 0) ||
+ (strcmp (precision, "city") == 0)) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if ((strcmp (precision, "zip+2") == 0) ||
+ (strcmp (precision, "zip+4") == 0)) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (strcmp (precision, "state") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (strcmp (precision, "country") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ g_free (precision);
+ }
+ return level;
+}
+
+/* Geocode interface implementation */
+static gboolean
+geoclue_yahoo_address_to_position (GcIfaceGeocode *iface,
+ GHashTable *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueYahoo *yahoo;
+ char *street, *postalcode, *locality, *region;
+
+ yahoo = GEOCLUE_YAHOO (iface);
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ /* weird: the results are all over the globe, but country is not an input parameter... */
+ street = get_address_value (address, GEOCLUE_ADDRESS_KEY_STREET);
+ postalcode = get_address_value (address, GEOCLUE_ADDRESS_KEY_POSTALCODE);
+ locality = get_address_value (address, GEOCLUE_ADDRESS_KEY_LOCALITY);
+ region = get_address_value (address, GEOCLUE_ADDRESS_KEY_REGION);
+
+ if (!gc_web_service_query (yahoo->web_service, error,
+ "appid", YAHOO_GEOCLUE_APP_ID,
+ "street", street,
+ "zip", postalcode,
+ "city", locality,
+ "state", region,
+ (char *)0)) {
+ return FALSE;
+ }
+
+ if (latitude) {
+ if (gc_web_service_get_double (yahoo->web_service,
+ latitude, "//yahoo:Latitude")) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ }
+ if (longitude) {
+ if (gc_web_service_get_double (yahoo->web_service,
+ longitude, "//yahoo:Longitude")) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+ }
+
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (get_query_accuracy_level (yahoo),
+ 0, 0);
+ }
+
+ g_free (street);
+ g_free (postalcode);
+ g_free (locality);
+ g_free (region);
+
+ return TRUE;
+}
+
+static gboolean
+geoclue_yahoo_freeform_address_to_position (GcIfaceGeocode *iface,
+ const char *address,
+ GeocluePositionFields *fields,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueYahoo *yahoo;
+
+ yahoo = GEOCLUE_YAHOO (iface);
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ if (!gc_web_service_query (yahoo->web_service, error,
+ "appid", YAHOO_GEOCLUE_APP_ID,
+ "location", address,
+ (char *)0)) {
+ return FALSE;
+ }
+
+ if (latitude) {
+ if (gc_web_service_get_double (yahoo->web_service,
+ latitude, "//yahoo:Latitude")) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ }
+ if (longitude) {
+ if (gc_web_service_get_double (yahoo->web_service,
+ longitude, "//yahoo:Longitude")) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+ }
+
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (get_query_accuracy_level (yahoo),
+ 0, 0);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_yahoo_dispose (GObject *obj)
+{
+ GeoclueYahoo *yahoo = (GeoclueYahoo *) obj;
+
+ if (yahoo->web_service) {
+ g_object_unref (yahoo->web_service);
+ yahoo->web_service = NULL;
+ }
+
+ ((GObjectClass *) geoclue_yahoo_parent_class)->dispose (obj);
+}
+
+/* Initialization */
+
+static void
+geoclue_yahoo_class_init (GeoclueYahooClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_yahoo_get_status;
+
+ o_class->dispose = geoclue_yahoo_dispose;
+}
+
+static void
+geoclue_yahoo_init (GeoclueYahoo *yahoo)
+{
+ gc_provider_set_details (GC_PROVIDER (yahoo),
+ "org.freedesktop.Geoclue.Providers.Yahoo",
+ "/org/freedesktop/Geoclue/Providers/Yahoo",
+ "Yahoo", "Geocode provider that uses the Yahoo! Maps web services API");
+
+ yahoo->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (yahoo->web_service, YAHOO_BASE_URL);
+ gc_web_service_add_namespace (yahoo->web_service, "yahoo", "urn:yahoo:maps");
+}
+
+
+static void
+geoclue_yahoo_geocode_init (GcIfaceGeocodeClass *iface)
+{
+ iface->address_to_position = geoclue_yahoo_address_to_position;
+ iface->freeform_address_to_position =
+ geoclue_yahoo_freeform_address_to_position;
+}
+
+int
+main()
+{
+ GeoclueYahoo *yahoo;
+
+ g_type_init();
+ yahoo = g_object_new (GEOCLUE_TYPE_YAHOO, NULL);
+ yahoo->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (yahoo->loop);
+
+ g_main_loop_unref (yahoo->loop);
+ g_object_unref (yahoo);
+
+ return 0;
+}
--- /dev/null
+[Geoclue Provider]
+Name=Yahoo
+Service=org.freedesktop.Geoclue.Providers.Yahoo
+Path=/org/freedesktop/Geoclue/Providers/Yahoo
+Requires=RequiresNetwork
+Accuracy=Street
+Interfaces=org.freedesktop.Geoclue.Geocode
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Providers.Yahoo
+Exec=@libexecdir@/geoclue-yahoo
--- /dev/null
+libexec_PROGRAMS = geoclue-master
+
+geoclue_master_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ -I$(top_builddir) \
+ -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \
+ $(GEOCLUE_CFLAGS) \
+ $(MASTER_CFLAGS) \
+ $(CONNECTIVITY_CFLAGS)
+
+geoclue_master_LDADD = \
+ $(top_builddir)/geoclue/libgeoclue.la \
+ $(GEOCLUE_LIBS) \
+ $(MASTER_LIBS) \
+ $(CONNECTIVITY_LIBS)
+
+NOINST_H_FILES = \
+ main.h \
+ master.h \
+ master-provider.h \
+ client.h \
+ connectivity.h \
+ connectivity-networkmanager.h \
+ connectivity-conic.h
+
+geoclue_master_SOURCES = \
+ $(NOINST_H_FILES) \
+ client.c \
+ main.c \
+ master.c \
+ master-provider.c \
+ connectivity.c \
+ connectivity-networkmanager.c \
+ connectivity-conic.c
+
+BUILT_SOURCES = \
+ gc-iface-master-glue.h \
+ gc-iface-master-client-glue.h
+
+%-glue.h: stamp-%-glue.h
+ @true
+stamp-gc-iface-master-glue.h: ../interfaces/gc-iface-master.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_master --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-master-client-glue.h: ../interfaces/gc-iface-master-client.xml
+ $(DBUS_BINDING_TOOL) --prefix=gc_iface_master_client --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Master.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-gc-iface-master-glue.h \
+ stamp-gc-iface-master-client-glue.h
+
+DISTCLEANFILES = \
+ $(service_DATA)
--- /dev/null
+/*
+ * Geoclue
+ * client.c - Geoclue Master Client
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/** TODO
+ *
+ * might want to write a testing-provider with a gui for
+ * choosing what to emit...
+ *
+ **/
+
+
+#include <config.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "client.h"
+
+#define GEOCLUE_POSITION_INTERFACE_NAME "org.freedesktop.Geoclue.Position"
+#define GEOCLUE_ADDRESS_INTERFACE_NAME "org.freedesktop.Geoclue.Address"
+
+enum {
+ ADDRESS_PROVIDER_CHANGED,
+ POSITION_PROVIDER_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+
+enum {
+ POSITION_CHANGED, /* signal id of current provider */
+ ADDRESS_CHANGED, /* signal id of current provider */
+ LAST_PRIVATE_SIGNAL
+};
+
+typedef struct _GcMasterClientPrivate {
+ guint32 signals[LAST_PRIVATE_SIGNAL];
+
+ GeoclueAccuracyLevel min_accuracy;
+ int min_time;
+ gboolean require_updates;
+ GeoclueResourceFlags allowed_resources;
+
+ gboolean position_started;
+ GcMasterProvider *position_provider;
+ GList *position_providers;
+ gboolean position_provider_choice_in_progress;
+
+ gboolean address_started;
+ GcMasterProvider *address_provider;
+ GList *address_providers;
+ gboolean address_provider_choice_in_progress;
+
+} GcMasterClientPrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_CLIENT, GcMasterClientPrivate))
+
+
+
+static gboolean gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error);
+static gboolean gc_iface_master_client_position_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_address_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+static gboolean gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+
+static void gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface);
+static void gc_master_client_position_init (GcIfacePositionClass *iface);
+static void gc_master_client_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcMasterClient, gc_master_client, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE,
+ gc_master_client_geoclue_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ gc_master_client_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ gc_master_client_address_init))
+
+#include "gc-iface-master-client-glue.h"
+
+
+static gboolean status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status);
+static void gc_master_client_emit_position_changed (GcMasterClient *client);
+static void gc_master_client_emit_address_changed (GcMasterClient *client);
+static gboolean gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers);
+static gboolean gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers);
+
+
+static void
+status_changed (GcMasterProvider *provider,
+ GeoclueStatus status,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ g_debug ("client: provider %s status changed: %d", gc_master_provider_get_name (provider), status);
+
+ /* change providers if needed (and if we're not choosing provider already) */
+
+ if (!priv->position_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->position_providers,
+ priv->position_provider,
+ provider, status) &&
+ gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+
+ /* we have a new position provider, force-emit position_changed */
+ gc_master_client_emit_position_changed (client);
+ }
+
+ if (!priv->address_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->address_providers,
+ priv->address_provider,
+ provider, status) &&
+ gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+
+ /* we have a new address provider, force-emit address_changed */
+ gc_master_client_emit_address_changed (client);
+ }
+}
+
+static void
+accuracy_changed (GcMasterProvider *provider,
+ GcInterfaceFlags interface,
+ GeoclueAccuracyLevel level,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0 (GcInterfaceAccuracy, 1);
+ g_debug ("client: %s accuracy changed (%d)",
+ gc_master_provider_get_name (provider), level);
+
+ accuracy_data->interface = interface;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+ switch (interface) {
+ case GC_IFACE_POSITION:
+ priv->position_providers =
+ g_list_sort_with_data (priv->position_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->position_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+ gc_master_client_emit_position_changed (client);
+ }
+ break;
+
+ case GC_IFACE_ADDRESS:
+ priv->address_providers =
+ g_list_sort_with_data (priv->address_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->address_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+ gc_master_client_emit_address_changed (client);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ g_free (accuracy_data);
+}
+
+static void
+position_changed (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+address_changed (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/*if changed_provider status changes, do we need to choose a new provider? */
+static gboolean
+status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status)
+{
+ if (!provider_list) {
+ return FALSE;
+
+ } else if (current_provider == NULL) {
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+
+ } else if (current_provider == changed_provider) {
+ return (status != GEOCLUE_STATUS_AVAILABLE);
+
+ }else if (status != GEOCLUE_STATUS_AVAILABLE) {
+ return FALSE;
+
+ }
+
+ while (provider_list) {
+ GcMasterProvider *p = provider_list->data;
+ if (p == current_provider) {
+ /* not interested in worse-than-current providers */
+ return FALSE;
+ }
+ if (p == changed_provider) {
+ /* changed_provider is better than current */
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+ }
+ provider_list = provider_list->next;
+ }
+ return FALSE;
+}
+
+static void
+gc_master_client_connect_common_signals (GcMasterClient *client, GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *l;
+
+ /* connect to common signals if the provider is not already connected */
+ l = providers;
+ while (l) {
+ GcMasterProvider *p = l->data;
+ if (!g_list_find (priv->address_providers, p) &&
+ !g_list_find (priv->position_providers, p)) {
+ g_debug ("client: connecting to '%s' accuracy-changed and status-changed", gc_master_provider_get_name (p));
+ g_signal_connect (G_OBJECT (p),
+ "status-changed",
+ G_CALLBACK (status_changed),
+ client);
+ g_signal_connect (G_OBJECT (p),
+ "accuracy-changed",
+ G_CALLBACK (accuracy_changed),
+ client);
+ }
+ l = l->next;
+ }
+}
+
+static void
+gc_master_client_unsubscribe_providers (GcMasterClient *client, GList *provider_list, GcInterfaceFlags iface)
+{
+ while (provider_list) {
+ GcMasterProvider *provider = provider_list->data;
+
+ gc_master_provider_unsubscribe (provider, client, iface);
+ provider_list = provider_list->next;
+ }
+
+}
+
+/* get_best_provider will return the best provider with status == GEOCLUE_STATUS_AVAILABLE.
+ * It will also "subscribe" to that provider and all better ones, and unsubscribe from worse.*/
+static GcMasterProvider *
+gc_master_client_get_best_provider (GcMasterClient *client,
+ GList **provider_list,
+ GcInterfaceFlags iface)
+{
+ GList *l = *provider_list;
+ /* TODO: should maybe choose a acquiring provider if better ones are are not available */
+
+ g_debug ("client: choosing best provider");
+
+ while (l) {
+ GcMasterProvider *provider = l->data;
+
+ g_debug (" ...trying provider %s", gc_master_provider_get_name (provider));
+ if (gc_master_provider_subscribe (provider, client, iface)) {
+ /* provider was started, so accuracy may have changed
+ (which re-sorts provider lists), restart provider selection */
+ /* TODO re-think this: restarting provider selection leads to potentially
+ never-ending looping */
+ g_debug (" ...started %s (status %d), re-starting provider selection",
+ gc_master_provider_get_name (provider),
+ gc_master_provider_get_status (provider));
+ l = *provider_list;
+ continue;
+ }
+ /* provider did not need to be started */
+
+ /* TODO: currently returning even providers that are worse than priv->min_accuracy,
+ * if nothing else is available */
+ if (gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) {
+ /* unsubscribe from all providers worse than this */
+ gc_master_client_unsubscribe_providers (client, l->next, iface);
+ return provider;
+ }
+ l = l->next;
+ }
+
+ /* no provider found */
+ gc_master_client_unsubscribe_providers (client, *provider_list, iface);
+ return NULL;
+}
+
+static void
+gc_master_client_emit_position_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeocluePositionFields fields;
+ int timestamp;
+ double latitude, longitude, altitude;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+
+ if (priv->position_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL),
+ 0.0, 0.0, 0.0,
+ accuracy);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+
+ fields = gc_master_provider_get_position
+ (priv->position_provider,
+ ×tamp,
+ &latitude, &longitude, &altitude,
+ &accuracy,
+ &error);
+ if (error) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get position from %s: %s",
+ gc_master_provider_get_name (priv->position_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+gc_master_client_emit_address_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (priv->address_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ details = g_hash_table_new (g_str_hash, g_str_equal);
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ time (NULL),
+ details,
+ accuracy);
+ g_hash_table_destroy (details);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+ if (!gc_master_provider_get_address
+ (priv->address_provider,
+ ×tamp,
+ &details,
+ &accuracy,
+ &error)) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get address from %s: %s",
+ gc_master_provider_get_name (priv->address_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+ /* choose and start provider */
+ priv->position_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->position_providers,
+ GC_IFACE_POSITION);
+ priv->position_provider_choice_in_progress = FALSE;
+
+ if (priv->position_provider && new_p == priv->position_provider) {
+ return FALSE;
+ }
+
+ if (priv->signals[POSITION_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->position_provider,
+ priv->signals[POSITION_CHANGED]);
+ priv->signals[POSITION_CHANGED] = 0;
+ }
+
+ priv->position_provider = new_p;
+
+ if (priv->position_provider == NULL) {
+ g_debug ("client: position provider changed (to NULL)");
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: position provider changed (to %s)", gc_master_provider_get_name (priv->position_provider));
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->position_provider),
+ gc_master_provider_get_description (priv->position_provider),
+ gc_master_provider_get_service (priv->position_provider),
+ gc_master_provider_get_path (priv->position_provider));
+ priv->signals[POSITION_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->position_provider),
+ "position-changed",
+ G_CALLBACK (position_changed),
+ client);
+ return TRUE;
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+
+ /* choose and start provider */
+ priv->address_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->address_providers,
+ GC_IFACE_ADDRESS);
+ priv->address_provider_choice_in_progress = FALSE;
+
+ if (priv->address_provider != NULL && new_p == priv->address_provider) {
+ /* keep using the same provider */
+ return FALSE;
+ }
+
+ if (priv->address_provider && priv->signals[ADDRESS_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->address_provider,
+ priv->signals[ADDRESS_CHANGED]);
+ priv->signals[ADDRESS_CHANGED] = 0;
+ }
+
+ priv->address_provider = new_p;
+
+ if (priv->address_provider == NULL) {
+ g_debug ("client: address provider changed (to NULL)");
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: address provider changed (to %s)", gc_master_provider_get_name (priv->address_provider));
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->address_provider),
+ gc_master_provider_get_description (priv->address_provider),
+ gc_master_provider_get_service (priv->address_provider),
+ gc_master_provider_get_path (priv->address_provider));
+ priv->signals[ADDRESS_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->address_provider),
+ "address-changed",
+ G_CALLBACK (address_changed),
+ client);
+ return TRUE;
+}
+
+static void
+gc_master_provider_set_position_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_POSITION;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->position_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_provider_set_address_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_ADDRESS;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->address_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_client_init_position_providers (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *providers;
+
+ if (!priv->position_started) {
+ return;
+ }
+
+ /* TODO: free priv->position_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_POSITION,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d position providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_position_providers (client, providers);
+ gc_master_client_choose_position_provider (client, priv->position_providers);
+}
+static void
+gc_master_client_init_address_providers (GcMasterClient *client)
+{
+ GList *providers;
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (!priv->address_started) {
+ return;
+ }
+
+ /* TODO: free priv->address_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_ADDRESS,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d address providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_address_providers (client, providers);
+ gc_master_client_choose_address_provider (client, priv->address_providers);
+}
+
+static gboolean
+gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->min_accuracy = min_accuracy;
+ priv->min_time = min_time;
+ priv->require_updates = require_updates;
+ priv->allowed_resources = allowed_resources;
+
+ gc_master_client_init_position_providers (client);
+ gc_master_client_init_address_providers (client);
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_iface_master_client_position_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Position interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->position_started = TRUE;
+
+ gc_master_client_init_position_providers (client);
+
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_address_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Address interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->address_started = TRUE;
+ gc_master_client_init_address_providers (client);
+ return TRUE;
+}
+
+static void
+get_master_provider_details (GcMasterProvider *provider,
+ char **name,
+ char **description,
+ char **service,
+ char **path)
+{
+ if (name) {
+ if (!provider) {
+ *name = NULL;
+ } else {
+ *name = g_strdup (gc_master_provider_get_name (provider));
+ }
+ }
+ if (description) {
+ if (!provider) {
+ *description = NULL;
+ } else {
+ *description = g_strdup (gc_master_provider_get_description (provider));
+ }
+ }
+ if (service) {
+ if (!provider) {
+ *service = NULL;
+ } else {
+ *service = g_strdup (gc_master_provider_get_service (provider));
+ }
+ }
+ if (path) {
+ if (!provider) {
+ *path = NULL;
+ } else {
+ *path = g_strdup (gc_master_provider_get_path (provider));
+ }
+ }
+}
+
+
+static gboolean
+gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->address_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->position_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (object);
+ GcMasterClientPrivate *priv = GET_PRIVATE (object);
+
+ /* do not free contents of the lists, Master takes care of them */
+ if (priv->position_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->position_providers, GC_IFACE_ALL);
+ g_list_free (priv->position_providers);
+ priv->position_providers = NULL;
+ }
+ if (priv->address_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->address_providers, GC_IFACE_ALL);
+ g_list_free (priv->address_providers);
+ priv->address_providers = NULL;
+ }
+
+ ((GObjectClass *) gc_master_client_parent_class)->finalize (object);
+}
+
+static void
+gc_master_client_class_init (GcMasterClientClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ g_type_class_add_private (klass, sizeof (GcMasterClientPrivate));
+
+ signals[ADDRESS_PROVIDER_CHANGED] =
+ g_signal_new ("address-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ signals[POSITION_PROVIDER_CHANGED] =
+ g_signal_new ("position-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ dbus_g_object_type_install_info (gc_master_client_get_type (),
+ &dbus_glib_gc_iface_master_client_object_info);
+
+
+}
+
+static void
+gc_master_client_init (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->position_provider_choice_in_progress = FALSE;
+ priv->address_provider_choice_in_progress = FALSE;
+
+ priv->position_started = FALSE;
+ priv->position_provider = NULL;
+ priv->position_providers = NULL;
+
+ priv->address_started = FALSE;
+ priv->address_provider = NULL;
+ priv->address_providers = NULL;
+}
+
+static gboolean
+get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Position providers");
+ }
+ return FALSE;
+ }
+
+ *fields = gc_master_provider_get_position
+ (priv->position_provider,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy,
+ error);
+ return (!*error);
+}
+
+static gboolean
+get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Address providers");
+ }
+ return FALSE;
+ }
+
+ return gc_master_provider_get_address
+ (priv->address_provider,
+ timestamp,
+ address,
+ accuracy,
+ error);
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* not really meaningful */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error)
+{
+ /* not meaningful, options come from master */
+
+ /* It is not an error to not have a SetOptions implementation */
+ return TRUE;
+}
+
+static gboolean
+get_provider_info (GcIfaceGeoclue *geoclue,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ if (name) {
+ *name = g_strdup ("Geoclue Master");
+ }
+ if (description) {
+ *description = g_strdup ("Meta-provider that internally uses what ever provider is the best ");
+ }
+ return TRUE;
+}
+
+static void
+add_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+remove_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface)
+{
+ iface->get_provider_info = get_provider_info;
+ iface->get_status = get_status;
+ iface->set_options = set_options;
+ iface->add_reference = add_reference;
+ iface->remove_reference = remove_reference;
+}
+
+static void
+gc_master_client_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static void
+gc_master_client_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
--- /dev/null
+/*
+ * Geoclue
+ * client.h - Master process client
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _CLIENT_H_
+#define _CLIENT_H_
+
+#include <glib-object.h>
+#include <geoclue/geoclue-accuracy.h>
+
+#include "master.h"
+#include "master-provider.h"
+
+#define GC_TYPE_MASTER_CLIENT (gc_master_client_get_type ())
+#define GC_MASTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_MASTER_CLIENT, GcMasterClient))
+
+typedef struct {
+ GObject parent;
+} GcMasterClient;
+
+typedef struct {
+ GObjectClass parent_class;
+} GcMasterClientClass;
+
+GType gc_master_client_get_type (void);
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-conic.c
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#ifdef HAVE_CONIC
+
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <conicconnectionevent.h>
+#include "connectivity-conic.h"
+
+static void geoclue_conic_connectivity_init (GeoclueConnectivityInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueConic, geoclue_conic, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_conic_connectivity_init))
+
+
+/* GeoclueConnectivity iface method */
+static int
+get_status (GeoclueConnectivity *iface)
+{
+ GeoclueConic *conic = GEOCLUE_CONIC (iface);
+
+ return conic->status;
+}
+
+
+static void
+finalize (GObject *object)
+{
+ /* free everything */
+
+ ((GObjectClass *) geoclue_conic_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueConic *self = GEOCLUE_CONIC (object);
+
+ g_object_unref (self->conic);
+ ((GObjectClass *) geoclue_conic_parent_class)->dispose (object);
+}
+
+static void
+geoclue_conic_class_init (GeoclueConicClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+}
+
+
+static GeoclueNetworkStatus
+conicstatus_to_geocluenetworkstatus (ConIcConnectionStatus status)
+{
+ switch (status) {
+ case CON_IC_STATUS_CONNECTED:
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ case CON_IC_STATUS_DISCONNECTED:
+ case CON_IC_STATUS_DISCONNECTING:
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ default:
+ g_warning ("Uknown ConIcConnectionStatus: %d", status);
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ break;
+ }
+}
+
+static void
+geoclue_conic_state_changed (ConIcConnection *connection,
+ ConIcConnectionEvent *event,
+ gpointer userdata)
+{
+ GeoclueConic *self = GEOCLUE_CONIC (userdata);
+ ConIcConnectionStatus status = con_ic_connection_event_get_status (event);
+ GeoclueNetworkStatus gc_status;
+
+ g_debug ("conic change");
+ gc_status = conicstatus_to_geocluenetworkstatus (status);
+ if (gc_status != self->status) {
+ self->status = gc_status;
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+static void
+geoclue_conic_init (GeoclueConic *self)
+{
+ DBusConnection *system_bus = NULL;
+
+ self->status = GEOCLUE_CONNECTIVITY_UNKNOWN;
+
+ /* Need to run dbus_connection_setup_with_g_main(),
+ * otherwise conic signals will not fire... */
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!system_bus) {
+ g_warning ("D-Bus system bus not available, connection signals not connected.");
+ return;
+ }
+ dbus_connection_setup_with_g_main (system_bus, NULL);
+
+ self->conic = con_ic_connection_new();
+ if (self->conic == NULL) {
+ g_warning ("Creating new ConicConnection failed");
+ return;
+ }
+
+ g_signal_connect (G_OBJECT (self->conic),
+ "connection-event",
+ G_CALLBACK (geoclue_conic_state_changed),
+ self);
+
+ /* this should result in a connection-event signal with current
+ * connection status. Weird API.*/
+ g_object_set (G_OBJECT (self->conic),
+ "automatic-connection-events",
+ TRUE, NULL);
+}
+
+
+static void
+geoclue_conic_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = get_status;
+}
+
+#endif /* HAVE_CONIC*/
--- /dev/null
+/*
+ * Geoclue
+ * connectivity-conic.h
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _CONNECTIVITY_CONIC_H
+#define _CONNECTIVITY_CONIC_H
+
+#include <glib-object.h>
+#include <conicconnection.h>
+#include "connectivity.h"
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_CONIC (geoclue_conic_get_type ())
+#define GEOCLUE_CONIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONIC, GeoclueConic))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ ConIcConnection *conic;
+} GeoclueConic;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueConicClass;
+
+GType geoclue_conic_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-networkmanager.c
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#ifdef HAVE_NETWORK_MANAGER
+
+
+#include <dbus/dbus-glib.h>
+#include <NetworkManager.h> /*for DBus strings */
+
+#ifdef HAVE_NETWORK_MANAGER
+#include <nm-client.h>
+#include <nm-device-wifi.h>
+#endif
+
+#include "connectivity-networkmanager.h"
+
+static void geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueNetworkManager, geoclue_networkmanager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_networkmanager_connectivity_init))
+
+
+/* GeoclueConnectivity iface method */
+static int
+get_status (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *nm = GEOCLUE_NETWORKMANAGER (iface);
+
+ return nm->status;
+}
+
+static char *
+get_ap_mac (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+
+ return self->cache_ap_mac;
+}
+
+static void
+get_best_ap (GeoclueNetworkManager *self, NMDevice *device)
+{
+ const GPtrArray *aps;
+ guint i;
+
+ aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+ if (aps == NULL || aps->len == 0)
+ return;
+ for (i = 0; i < aps->len; i++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
+ int strength;
+
+ strength = nm_access_point_get_strength (ap);
+ if (strength > self->ap_strength) {
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = g_strdup (nm_access_point_get_hw_address (ap));
+ self->ap_strength = strength;
+ }
+ }
+}
+
+static void
+cache_ap_mac (GeoclueNetworkManager *self)
+{
+ const GPtrArray *devices;
+ guint i;
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ self->ap_strength = 0;
+
+ devices = nm_client_get_devices (self->client);
+ if (devices == NULL) {
+ g_warning ("NetworkManager found no devices.");
+ return;
+ }
+
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ if (NM_IS_DEVICE_WIFI (device)) {
+ get_best_ap (self, device);
+ }
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ /* free everything */
+
+ ((GObjectClass *) geoclue_networkmanager_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (object);
+
+ dbus_g_connection_unref (self->connection);
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ g_object_unref (self->client);
+ self->client = NULL;
+ ((GObjectClass *) geoclue_networkmanager_parent_class)->dispose (object);
+}
+
+static void
+geoclue_networkmanager_class_init (GeoclueNetworkManagerClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+}
+
+static GeoclueNetworkStatus
+nmstate_to_geocluenetworkstatus (NMState status)
+{
+ switch (status) {
+ case NM_STATE_UNKNOWN:
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_DISCONNECTED:
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ case NM_STATE_CONNECTING:
+ return GEOCLUE_CONNECTIVITY_ACQUIRING;
+ case NM_STATE_CONNECTED:
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ default:
+ g_warning ("Unknown NMStatus: %d", status);
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ }
+}
+
+static void
+geoclue_networkmanager_state_changed (DBusGProxy *proxy,
+ NMState status,
+ gpointer userdata)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (userdata);
+ GeoclueNetworkStatus gc_status;
+
+ gc_status = nmstate_to_geocluenetworkstatus (status);
+
+ if (gc_status != self->status) {
+ cache_ap_mac (self);
+ self->status = gc_status;
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+
+#define NM_DBUS_SIGNAL_STATE_CHANGE "StateChange"
+
+static void
+geoclue_networkmanager_init (GeoclueNetworkManager *self)
+{
+ GError *error = NULL;
+ DBusGProxy *proxy;
+ NMState state;
+
+ self->status = GEOCLUE_CONNECTIVITY_UNKNOWN;
+
+ self->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (self->connection == NULL) {
+ g_warning ("%s was unable to create a connection to D-Bus: %s",
+ G_OBJECT_TYPE_NAME (self), error->message);
+ g_error_free (error);
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (self->connection,
+ NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE);
+ dbus_g_proxy_add_signal (proxy, NM_DBUS_SIGNAL_STATE_CHANGE,
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (proxy, NM_DBUS_SIGNAL_STATE_CHANGE,
+ G_CALLBACK (geoclue_networkmanager_state_changed),
+ self, NULL);
+
+ if (dbus_g_proxy_call (proxy, "state", &error,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &state, G_TYPE_INVALID)){
+ self->status = nmstate_to_geocluenetworkstatus (state);
+ } else {
+ g_warning ("Could not get connectivity state from NetworkManager: %s", error->message);
+ g_error_free (error);
+ }
+
+ self->client = nm_client_new ();
+ cache_ap_mac (self);
+}
+
+
+static void
+geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = get_status;
+ iface->get_ap_mac = get_ap_mac;
+}
+
+#endif /* HAVE_NETWORK_MANAGER */
--- /dev/null
+/*
+ * Geoclue
+ * connectivity-networkmanager.h
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _CONNECTIVITY_NETWORKMANAGER_H
+#define _CONNECTIVITY_NETWORKMANAGER_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include "connectivity.h"
+
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_NETWORKMANAGER (geoclue_networkmanager_get_type ())
+#define GEOCLUE_NETWORKMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_NETWORKMANAGER, GeoclueNetworkManager))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ DBusGConnection *connection;
+ NMClient *client;
+ char *cache_ap_mac;
+ int ap_strength;
+} GeoclueNetworkManager;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueNetworkManagerClass;
+
+GType geoclue_networkmanager_get_type (void);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-connectivity.c
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <glib.h>
+#include "connectivity.h"
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void
+geoclue_connectivity_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+
+ initialized = TRUE;
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeoclueConnectivityInterface,
+ status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+GType
+geoclue_connectivity_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GeoclueConnectivityInterface),
+ geoclue_connectivity_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GeoclueConnectivity",
+ &info, 0);
+ }
+
+ return type;
+}
+
+GeoclueNetworkStatus
+geoclue_connectivity_get_status (GeoclueConnectivity *self)
+{
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_status (self);
+}
+
+char *
+geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self)
+{
+ if (GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac != NULL)
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac (self);
+ return NULL;
+}
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status)
+{
+ g_signal_emit (self, signals[STATUS_CHANGED], 0, status);
+}
--- /dev/null
+/*
+ * Geoclue
+ * geoclue-connectivity.h
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _GEOCLUE_CONNECTIVITY_H
+#define _GEOCLUE_CONNECTIVITY_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_CONNECTIVITY (geoclue_connectivity_get_type ())
+#define GEOCLUE_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivity))
+#define GEOCLUE_IS_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_CONNECTIVITY))
+#define GEOCLUE_CONNECTIVITY_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivityInterface))
+
+typedef struct _GeoclueConnectivity GeoclueConnectivity;
+typedef struct _GeoclueConnectivityInterface GeoclueConnectivityInterface;
+
+struct _GeoclueConnectivityInterface {
+ GTypeInterface parent;
+
+ /* signals */
+ void (* status_changed) (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+ /* vtable */
+ int (*get_status) (GeoclueConnectivity *self);
+ char * (*get_ap_mac) (GeoclueConnectivity *self);
+};
+
+GType geoclue_connectivity_get_type (void);
+
+
+GeoclueNetworkStatus geoclue_connectivity_get_status (GeoclueConnectivity *self);
+
+char *geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self);
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * main.c - Master process
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <gconf/gconf-client.h>
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "master.h"
+
+static GMainLoop *mainloop;
+static GHashTable *options;
+static GcMaster *master;
+
+
+#define GEOCLUE_GCONF_TOP "/apps/geoclue/master"
+#define GEOCLUE_MASTER_NAME "org.freedesktop.Geoclue.Master"
+
+static void
+gconf_key_changed (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ const char *key, *value;
+ GConfValue *v;
+
+ key = gconf_entry_get_key (entry);
+ v = gconf_entry_get_value (entry);
+ if (v->type != GCONF_VALUE_STRING)
+ return;
+ value = gconf_value_get_string (v);
+
+ g_message ("gconf key changed %s", key);
+
+ /* Don't add empty strings in the hashtable */
+ if (value != NULL && value[0] == '\0')
+ value = NULL;
+
+ g_hash_table_insert (options, g_path_get_basename (key),
+ g_strdup (value));
+
+ g_signal_emit_by_name (G_OBJECT (master), "options-changed", options);
+}
+
+static GHashTable *
+load_options (void)
+{
+ GHashTable *ht = NULL;
+ GConfClient *client = gconf_client_get_default ();
+ GSList *entries, *e;
+ GError *error = NULL;
+
+ gconf_client_add_dir (client, GEOCLUE_GCONF_TOP,
+ GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+
+ entries = gconf_client_all_entries (client, GEOCLUE_GCONF_TOP, &error);
+ if (error != NULL) {
+ g_warning ("Error loading master options: %s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ /* Setup keys monitoring */
+ gconf_client_notify_add (client, GEOCLUE_GCONF_TOP,
+ (GConfClientNotifyFunc) gconf_key_changed,
+ NULL, NULL, NULL);
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ g_print ("Master options:\n");
+ for (e = entries; e; e = e->next) {
+ GConfEntry *entry = e->data;
+ const char *key, *value;
+ GConfValue *v;
+
+ key = gconf_entry_get_key (entry);
+ v = gconf_entry_get_value (entry);
+ if (v->type != GCONF_VALUE_STRING)
+ continue;
+ value = gconf_value_get_string (v);
+
+ if (value != NULL && value[0] == '\0')
+ value = NULL;
+
+ g_print (" %s = %s\n", key, value);
+ g_hash_table_insert (ht, g_path_get_basename (key),
+ g_strdup (value));
+ gconf_entry_free (entry);
+ }
+ g_slist_free (entries);
+
+ return ht;
+ }
+
+GHashTable *
+geoclue_get_main_options (void)
+{
+ return options;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ DBusGConnection *conn;
+ DBusGProxy *proxy;
+ GError *error = NULL;
+ guint32 request_name_ret;
+
+ g_type_init ();
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ conn = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!conn) {
+ g_error ("Error getting bus: %s", error->message);
+ return 1;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ if (!org_freedesktop_DBus_request_name (proxy, GEOCLUE_MASTER_NAME,
+ 0, &request_name_ret, &error)) {
+ g_error ("Error registering D-Bus service %s: %s",
+ GEOCLUE_MASTER_NAME, error->message);
+ return 1;
+ }
+
+ /* Just quit if master is already running */
+ if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ return 1;
+ }
+
+ /* Load options */
+ options = load_options ();
+
+ master = g_object_new (GC_TYPE_MASTER, NULL);
+ dbus_g_connection_register_g_object (conn,
+ "/org/freedesktop/Geoclue/Master",
+ G_OBJECT (master));
+
+ g_main_loop_run (mainloop);
+ return 0;
+}
--- /dev/null
+/*
+ * Geoclue
+ * main.h
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _MAIN_H_
+#define _MAIN_H_
+
+#include <glib.h>
+
+GHashTable *geoclue_get_main_options (void);
+
+#endif
--- /dev/null
+/*
+ * Geoclue
+ * master-provider.c - Provider object for master and master client
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ */
+
+/**
+ * Provider object for GcMaster. Takes care of cacheing
+ * queried data.
+ *
+ * Should probably start/stop the actual providers as needed
+ * in the future
+ *
+ * Cache could also be used to save "stale" data for situations when
+ * current data is not available (MasterClient api would have to
+ * have a "allowOldData" setting)
+ *
+ * TODO:
+ * figure out what to do if get_* returns GEOCLUE_ERROR_NOT_AVAILABLE.
+ * Should try again, but when?
+ *
+ * implement velocity
+ *
+ * implement other (non-updating) ifaces
+ **/
+
+#include <string.h>
+
+#include "main.h"
+#include "master-provider.h"
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-marshal.h>
+
+typedef enum _GeoclueProvideFlags {
+ GEOCLUE_PROVIDE_NONE = 0,
+ GEOCLUE_PROVIDE_UPDATES = 1 << 0, /* will send *-changed signals */
+ GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION = 1 << 1, /* data can be queried on new connection, and cached until connection ends */
+} GeoclueProvideFlags;
+
+typedef struct _GcPositionCache {
+ int timestamp;
+ GeocluePositionFields fields;
+ double latitude;
+ double longitude;
+ double altitude;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcPositionCache;
+
+typedef struct _GcAddressCache {
+ int timestamp;
+ GHashTable *details;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcAddressCache;
+
+typedef struct _GcMasterProviderPrivate {
+ char *name;
+ char *description;
+
+ char *service;
+ char *path;
+ GcInterfaceFlags interfaces;
+
+ GList *position_clients; /* list of clients currently using this provider */
+ GList *address_clients;
+
+ GeoclueAccuracyLevel expected_accuracy;
+
+ GeoclueResourceFlags required_resources;
+ GeoclueProvideFlags provides;
+
+ GeoclueStatus master_status; /* net_status and status affect this */
+ GeoclueNetworkStatus net_status;
+
+ GeoclueStatus status; /* cached status from actual provider */
+
+ GeocluePosition *position;
+ GcPositionCache position_cache;
+
+ GeoclueAddress *address;
+ GcAddressCache address_cache;
+
+} GcMasterProviderPrivate;
+
+enum {
+ STATUS_CHANGED,
+ ACCURACY_CHANGED,
+ POSITION_CHANGED,
+ ADDRESS_CHANGED,
+ NMEA_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_PROVIDER, GcMasterProviderPrivate))
+
+G_DEFINE_TYPE (GcMasterProvider, gc_master_provider, G_TYPE_OBJECT)
+
+static void
+copy_error (GError **target, GError *source)
+{
+ if (*target) {
+ g_error_free (*target);
+ *target = NULL;
+ }
+ if (source) {
+ *target = g_error_copy (source);
+
+ /* If the error type is a D-Bus remote exception,
+ * don't lose the "magic" sauce after the message string.
+ * See the code in gerror_to_dbus_error_message() in dbus-glib */
+ if (source->domain == DBUS_GERROR &&
+ source->code == DBUS_GERROR_REMOTE_EXCEPTION) {
+ int len;
+ g_free ((*target)->message);
+ len = strlen (source->message);
+ len += strlen (source->message + len + 1);
+ len += 2;
+ (*target)->message = g_memdup (source->message, len);
+ }
+ }
+}
+
+static GeoclueProvider*
+gc_master_provider_get_provider (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ if (priv->address) {
+ return GEOCLUE_PROVIDER (priv->address);
+ }
+ if (priv->position) {
+ return GEOCLUE_PROVIDER (priv->position);
+ }
+ return NULL;
+}
+
+static gboolean
+gc_master_provider_is_running (GcMasterProvider *master_provider)
+{
+ return (gc_master_provider_get_provider (master_provider) != NULL);
+}
+
+static void
+gc_master_provider_handle_new_position_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_POSITION, new_level);
+ }
+}
+
+static void
+gc_master_provider_handle_new_address_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_ADDRESS, new_level);
+ }
+}
+
+static void
+gc_master_provider_set_position (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_cache.timestamp = timestamp;
+ priv->position_cache.fields = fields;
+ priv->position_cache.latitude = latitude;
+ priv->position_cache.longitude = longitude;
+ priv->position_cache.altitude = altitude;
+
+ copy_error (&priv->position_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_position_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[POSITION_CHANGED], 0,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ priv->position_cache.accuracy);
+ }
+}
+
+static void
+gc_master_provider_set_address (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->address_cache.timestamp = timestamp;
+
+ g_hash_table_destroy (priv->address_cache.details);
+ if (details) {
+ priv->address_cache.details = geoclue_address_details_copy (details);
+ }else {
+ priv->address_cache.details = geoclue_address_details_new ();
+ }
+ copy_error (&priv->address_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_address_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[ADDRESS_CHANGED], 0,
+ priv->address_cache.timestamp,
+ priv->address_cache.details,
+ priv->address_cache.accuracy);
+ }
+}
+
+
+
+static GeoclueResourceFlags
+parse_resource_strings (char **flags)
+{
+ GeoclueResourceFlags resources = GEOCLUE_RESOURCE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "RequiresNetwork") == 0) {
+ resources |= GEOCLUE_RESOURCE_NETWORK;
+ } else if (strcmp (flags[i], "RequiresCell") == 0) {
+ resources |= GEOCLUE_RESOURCE_CELL;
+ } else if (strcmp (flags[i], "RequiresGPS") == 0) {
+ resources |= GEOCLUE_RESOURCE_GPS;
+ }
+ }
+
+ return resources;
+}
+
+static GeoclueProvideFlags
+parse_provide_strings (char **flags)
+{
+ GeoclueProvideFlags provides = GEOCLUE_PROVIDE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "ProvidesUpdates") == 0) {
+ provides |= GEOCLUE_PROVIDE_UPDATES;
+ } else if (strcmp (flags[i], "ProvidesCacheableOnConnection") == 0) {
+ provides |= GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ }
+ }
+
+ return provides;
+}
+
+static GcInterfaceFlags
+parse_interface_strings (char **strs)
+{
+ GcInterfaceFlags ifaces = GC_IFACE_GEOCLUE;
+ int i;
+
+ for (i = 0; strs[i]; i++) {
+ if (strcmp (strs[i], GEOCLUE_POSITION_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_POSITION;
+ } else if (strcmp (strs[i], GEOCLUE_ADDRESS_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_ADDRESS;
+ }
+ }
+ return ifaces;
+}
+
+static GeoclueAccuracyLevel
+parse_accuracy_string (char *str)
+{
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (!str || strcmp (str, "None") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ } else if (strcmp (str, "Country") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ } else if (strcmp (str, "Region") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (strcmp (str, "Locality") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (strcmp (str, "Postalcode") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (strcmp (str, "Street") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (strcmp (str, "Detailed") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+ } else {
+ g_warning ("'%s' is not a recognised accuracy level value", str);
+ }
+ return level;
+}
+
+static void
+gc_master_provider_handle_error (GcMasterProvider *provider, GError *error)
+{
+ GcMasterProviderPrivate *priv;
+
+ g_assert (error);
+
+ priv = GET_PRIVATE (provider);
+ g_debug ("%s handling error %d", priv->name, error->code);
+
+ /* web service providers that are unavailable */
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ error->code == GEOCLUE_ERROR_NOT_AVAILABLE) {
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ /* TODO set timer to re-check availability */
+ }
+}
+
+/* Sets master_status based on provider status and net_status
+ * Should be called whenever priv->status or priv->net_status change */
+static void
+gc_master_provider_handle_status_change (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ GeoclueStatus new_master_status;
+
+ /* calculate new master status */
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ switch (priv->net_status) {
+ case GEOCLUE_CONNECTIVITY_UNKNOWN:
+ /* falling through */
+ case GEOCLUE_CONNECTIVITY_OFFLINE:
+ new_master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+ case GEOCLUE_CONNECTIVITY_ACQUIRING:
+ if (priv->status == GEOCLUE_STATUS_AVAILABLE){
+ new_master_status = GEOCLUE_STATUS_ACQUIRING;
+ } else {
+ new_master_status = priv->status;
+ }
+ break;
+ case GEOCLUE_CONNECTIVITY_ONLINE:
+ new_master_status = priv->status;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ } else {
+ new_master_status = priv->status;
+ }
+
+ if (new_master_status != priv->master_status) {
+ priv->master_status = new_master_status;
+
+ g_signal_emit (provider, signals[STATUS_CHANGED], 0, new_master_status);
+ }
+}
+
+
+static void
+gc_master_provider_update_cache (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (master_provider);
+
+ if ((!(priv->provides & GEOCLUE_PROVIDE_UPDATES)) ||
+ (!gc_master_provider_get_provider (master_provider))) {
+ /* non-cacheable provider or provider not running */
+ return;
+ }
+
+ g_debug ("%s: Updating cache ", priv->name);
+ priv->master_status = GEOCLUE_STATUS_ACQUIRING;
+ g_signal_emit (master_provider, signals[STATUS_CHANGED], 0, priv->master_status);
+
+ if (priv->position) {
+ int timestamp;
+ double lat, lon, alt;
+ GeocluePositionFields fields;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ fields = geoclue_position_get_position (priv->position,
+ ×tamp,
+ &lat, &lon, &alt,
+ &accuracy,
+ &error);
+ if (error){
+ g_warning ("Error updating position cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_position (master_provider,
+ fields, timestamp,
+ lat, lon, alt,
+ accuracy, error);
+ }
+
+ if (priv->address) {
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (!geoclue_address_get_address (priv->address,
+ ×tamp,
+ &details,
+ &accuracy,
+ &error)) {
+ g_warning ("Error updating address cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_address (master_provider,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+/* signal handlers for the actual providers signals */
+
+static void
+provider_status_changed (GeoclueProvider *provider,
+ GeoclueStatus status,
+ GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ priv->status = status;
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_position (provider,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ accuracy, NULL);
+}
+
+static void
+address_changed (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_address (provider,
+ timestamp,
+ details,
+ accuracy,
+ NULL);
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ geoclue_accuracy_free (priv->position_cache.accuracy);
+ geoclue_accuracy_free (priv->address_cache.accuracy);
+ if (priv->position_cache.error) {
+ g_error_free (priv->position_cache.error);
+ }
+ if (priv->address_cache.error) {
+ g_error_free (priv->address_cache.error);
+ }
+
+ g_free (priv->name);
+ g_free (priv->description);
+ g_free (priv->service);
+ g_free (priv->path);
+
+ g_free (priv->position_clients);
+ g_free (priv->address_clients);
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ if (priv->address_cache.details) {
+ g_hash_table_destroy (priv->address_cache.details);
+ priv->address_cache.details = NULL;
+ }
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->dispose (object);
+}
+
+static void
+gc_master_provider_class_init (GcMasterProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GcMasterProviderPrivate));
+
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+ signals[ACCURACY_CHANGED] = g_signal_new ("accuracy-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, accuracy_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, position_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 6,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+ signals[ADDRESS_CHANGED] = g_signal_new ("address-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, address_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+}
+
+static void
+gc_master_provider_init (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_clients = NULL;
+ priv->address_clients = NULL;
+
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ priv->position = NULL;
+ priv->position_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->position_cache.error = NULL;
+
+ priv->address = NULL;
+ priv->address_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->address_cache.details = geoclue_address_details_new ();
+ priv->address_cache.error = NULL;
+}
+
+#if DEBUG_INFO
+static void
+gc_master_provider_dump_position (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+ GeocluePositionFields fields;
+ int time;
+ double lat, lon, alt;
+ GError *error = NULL;
+
+ priv = GET_PRIVATE (provider);
+
+
+ g_print (" Position Information:\n");
+ g_print (" ---------------------\n");
+
+ fields = gc_master_provider_get_position (provider,
+ &time,
+ &lat, &lon, &alt,
+ NULL, &error);
+ if (error) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_print (" Latitude: %.2f %s\n", lat,
+ fields & GEOCLUE_POSITION_FIELDS_LATITUDE ? "" : "(not set)");
+ g_print (" Longitude: %.2f %s\n", lon,
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE ? "" : "(not set)");
+ g_print (" Altitude: %.2f %s\n", alt,
+ fields & GEOCLUE_POSITION_FIELDS_ALTITUDE ? "" : "(not set)");
+
+}
+
+static void
+dump_address_key_and_value (char *key, char *value, GHashTable *target)
+{
+ g_print (" %s: %s\n", key, value);
+}
+
+static void
+gc_master_provider_dump_address (GcMasterProvider *provider)
+{
+ int time;
+ GHashTable *details;
+ GError *error = NULL;
+
+ g_print (" Address Information:\n");
+ g_print (" --------------------\n");
+ if (!gc_master_provider_get_address (provider,
+ &time,
+ &details,
+ NULL, &error)) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_hash_table_foreach (details, (GHFunc)dump_address_key_and_value, NULL);
+
+}
+
+static void
+gc_master_provider_dump_required_resources (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Requires\n");
+ if (priv->required_resources & GEOCLUE_RESOURCE_GPS) {
+ g_print (" - GPS\n");
+ }
+
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK) {
+ g_print (" - Network\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provides (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Provides\n");
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ g_print (" - Updates\n");
+ }
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ g_print (" - Cacheable on network connection\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provider_details (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print ("\n Name - %s\n", priv->name);
+ g_print (" Description - %s\n", priv->description);
+ g_print (" Service - %s\n", priv->service);
+ g_print (" Path - %s\n", priv->path);
+ g_print (" Accuracy level - %d\n", priv->expected_accuracy);
+ g_print (" Provider is currently %srunning, status %d\n",
+ gc_master_provider_get_provider (master_provider) ? "" : "not ",
+ priv->master_status);
+ gc_master_provider_dump_required_resources (provider);
+ gc_master_provider_dump_provides (provider);
+
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ g_print (" Interface - Position\n");
+ gc_master_provider_dump_position (provider);
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ g_print (" Interface - Address\n");
+ gc_master_provider_dump_address (provider);
+ }
+}
+#endif
+
+static gboolean
+gc_master_provider_initialize_geoclue (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (master_provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ /* priv->name has been read from .provider-file earlier...
+ * could ask the provider anyway, just to be consistent */
+ if (!geoclue_provider_get_provider_info (geoclue, NULL,
+ &priv->description, &error)) {
+ g_warning ("Error getting provider info: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_signal_connect (G_OBJECT (geoclue), "status-changed",
+ G_CALLBACK (provider_status_changed), master_provider);
+
+
+ if (!geoclue_provider_get_status (geoclue, &priv->status, &error)) {
+ g_warning ("Error getting provider status: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+gc_master_provider_initialize_interfaces (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ if (priv->interfaces <= GC_IFACE_GEOCLUE) {
+ g_warning ("No interfaces defined for %s", priv->name);
+ return FALSE;
+ }
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ if (priv->position == NULL) {
+ priv->position = geoclue_position_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->position), "position-changed",
+ G_CALLBACK (position_changed), provider);
+ }
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ if (priv->address == NULL) {
+ priv->address = geoclue_address_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->address), "address-changed",
+ G_CALLBACK (address_changed), provider);
+ }
+ }
+
+ if (!gc_master_provider_initialize_geoclue (provider)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_master_provider_initialize (GcMasterProvider *provider)
+{
+ if (!gc_master_provider_initialize_interfaces (provider)) {
+ return FALSE;
+ }
+
+ gc_master_provider_update_cache (provider);
+#if DEBUG_INFO
+ gc_master_provider_dump_provider_details (provider);
+#endif
+ return TRUE;
+}
+
+static void
+gc_master_provider_deinitialize (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ g_debug ("deinited %s", priv->name);
+}
+
+static void
+network_status_changed (gpointer *connectivity,
+ GeoclueNetworkStatus status,
+ GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ priv->net_status = status;
+ /* update connection-cacheable providers */
+ if (status == GEOCLUE_CONNECTIVITY_ONLINE &&
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ /* intialize to fill cache (this will handle status change) */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ } else {
+ gc_master_provider_handle_status_change (provider);
+ }
+}
+
+/* for updating cache on providers that are not running */
+static gboolean
+update_cache_and_deinit (GcMasterProvider *provider)
+{
+ /* fill cache */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ return FALSE;
+}
+
+
+/* public methods (for GcMaster and GcMasterClient) */
+
+/* Loads provider details from 'filename' */
+GcMasterProvider *
+gc_master_provider_new (const char *filename,
+ GeoclueConnectivity *connectivity)
+{
+ GcMasterProvider *provider;
+ GcMasterProviderPrivate *priv;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gboolean ret;
+ char *accuracy_str;
+ char **flags, **interfaces;
+
+ keyfile = g_key_file_new ();
+ ret = g_key_file_load_from_file (keyfile, filename,
+ G_KEY_FILE_NONE, &error);
+ if (ret == FALSE) {
+ g_warning ("Error loading %s: %s", filename, error->message);
+ g_error_free (error);
+ g_key_file_free (keyfile);
+ return NULL;
+ }
+
+ provider = g_object_new (GC_TYPE_MASTER_PROVIDER, NULL);
+ priv = GET_PRIVATE (provider);
+
+ priv->name = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Name", NULL);
+ priv->service = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Service", NULL);
+ priv->path = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Path", NULL);
+
+ accuracy_str = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Accuracy", NULL);
+ priv->expected_accuracy = parse_accuracy_string (accuracy_str);
+ if (accuracy_str){
+ g_free (accuracy_str);
+ }
+
+ /* set cached accuracies to a default value */
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Requires", NULL, NULL);
+ if (flags != NULL) {
+ priv->required_resources = parse_resource_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->required_resources = GEOCLUE_RESOURCE_NONE;
+ }
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Provides", NULL, NULL);
+ if (flags != NULL) {
+ priv->provides = parse_provide_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->provides = GEOCLUE_PROVIDE_NONE;
+ }
+
+ if (!connectivity &&
+ (priv->required_resources & GEOCLUE_RESOURCE_NETWORK)) {
+ priv->provides &= ~GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ priv->net_status = GEOCLUE_CONNECTIVITY_ONLINE;
+ priv->status = GEOCLUE_STATUS_AVAILABLE;
+ gc_master_provider_handle_status_change (provider);
+ }
+
+ if (connectivity &&
+ (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+
+ /* we have network status events: mark network provider
+ * with update flag, set the callback and set use_cache */
+ priv->provides |= GEOCLUE_PROVIDE_UPDATES;
+
+ g_signal_connect (connectivity,
+ "status-changed",
+ G_CALLBACK (network_status_changed),
+ provider);
+ priv->net_status = geoclue_connectivity_get_status (connectivity);
+ }
+
+ priv->interfaces = GC_IFACE_GEOCLUE;
+ interfaces = g_key_file_get_string_list (keyfile,
+ "Geoclue Provider",
+ "Interfaces",
+ NULL, NULL);
+ if (interfaces) {
+ priv->interfaces = parse_interface_strings (interfaces);
+ g_strfreev (interfaces);
+ }
+
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ priv->net_status == GEOCLUE_CONNECTIVITY_ONLINE) {
+ /* do this as idle so we can return without waiting for http queries */
+ g_idle_add ((GSourceFunc)update_cache_and_deinit, provider);
+ }
+ return provider;
+}
+
+/* client calls this when it wants to use the provider.
+ Returns true if provider was actually started, and
+ client should assume accuracy has changed.
+ Returns false if provider was not started (it was either already
+ running or starting the provider failed). */
+gboolean
+gc_master_provider_subscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ gboolean started = FALSE;
+
+ /* decide wether to run initialize or not */
+ if (!gc_master_provider_is_running (provider)) {
+ if (!(priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+ started = gc_master_provider_initialize (provider);
+ }
+ }
+
+ /* add subscription */
+ if (interface & GC_IFACE_POSITION) {
+ if (!g_list_find (priv->position_clients, client)) {
+ priv->position_clients = g_list_prepend (priv->position_clients, client);
+ }
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ if (!g_list_find (priv->address_clients, client)) {
+ priv->address_clients = g_list_prepend (priv->address_clients, client);
+ }
+ }
+
+ return started;
+}
+
+/* client calls this when it does not intend to use the provider */
+void
+gc_master_provider_unsubscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (interface & GC_IFACE_POSITION) {
+ priv->position_clients = g_list_remove (priv->position_clients, client);
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ priv->address_clients = g_list_remove (priv->address_clients, client);
+ }
+
+ if (!priv->position_clients &&
+ !priv->address_clients) {
+ /* no one is using this provider, shutdown... */
+ /* not clearing cached accuracies on purpose */
+ g_debug ("%s without clients", priv->name);
+
+ /* gc_master_provider_deinitialize (provider); */
+ }
+}
+
+
+GeocluePositionFields
+gc_master_provider_get_position (GcMasterProvider *provider,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ g_assert (priv->position ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION);
+
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ if (timestamp != NULL) {
+ *timestamp = priv->position_cache.timestamp;
+ }
+ if (latitude != NULL) {
+ *latitude = priv->position_cache.latitude;
+ }
+ if (longitude != NULL) {
+ *longitude = priv->position_cache.longitude;
+ }
+ if (altitude != NULL) {
+ *altitude = priv->position_cache.altitude;
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->position_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->position_cache.error);
+ }
+ return priv->position_cache.fields;
+ } else {
+ return geoclue_position_get_position (priv->position,
+ timestamp,
+ latitude,
+ longitude,
+ altitude,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_get_address (GcMasterProvider *provider,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+
+ if (timestamp != NULL) {
+ *timestamp = priv->address_cache.timestamp;
+ }
+ if (details != NULL) {
+ *details = geoclue_address_details_copy (priv->address_cache.details);
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->address_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->address_cache.error);
+ }
+ return (!priv->address_cache.error);
+ } else {
+ g_assert (priv->address);
+ return geoclue_address_get_address (priv->address,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_is_good (GcMasterProvider *provider,
+ GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean need_update,
+ GeoclueResourceFlags allowed_resources)
+{
+ GcMasterProviderPrivate *priv;
+ GcInterfaceFlags supported_ifaces;
+ GeoclueProvideFlags required_flags = GEOCLUE_PROVIDE_NONE;
+
+ priv = GET_PRIVATE (provider);
+
+ if (need_update) {
+ required_flags |= GEOCLUE_PROVIDE_UPDATES;
+ }
+
+ supported_ifaces = priv->interfaces;
+
+ /* provider must provide all that is required and
+ * cannot require a resource that is not allowed */
+ /* TODO: really, we need to change some of those terms... */
+
+ return (((supported_ifaces & iface_type) == iface_type) &&
+ ((priv->provides & required_flags) == required_flags) &&
+ (priv->expected_accuracy >= min_accuracy) &&
+ ((priv->required_resources & (~allowed_resources)) == 0));
+}
+
+void
+gc_master_provider_update_options (GcMasterProvider *provider)
+{
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+GeoclueStatus
+gc_master_provider_get_status (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->master_status;
+}
+
+GeoclueAccuracyLevel
+gc_master_provider_get_accuracy (GcMasterProvider *provider, GcInterfaceFlags iface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel acc_level;
+
+ switch (iface) {
+ case GC_IFACE_POSITION:
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ case GC_IFACE_ADDRESS:
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return acc_level;
+}
+
+/*returns a reference, but is not meant for editing...*/
+char *
+gc_master_provider_get_name (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->name;
+}
+char *
+gc_master_provider_get_description (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->description;
+}
+char *
+gc_master_provider_get_service (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->service;
+}
+char *
+gc_master_provider_get_path (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->path;
+}
+
+/* GCompareDataFunc for sorting providers by accuracy and required resources */
+int
+gc_master_provider_compare (GcMasterProvider *a,
+ GcMasterProvider *b,
+ GcInterfaceAccuracy *iface_min_accuracy)
+{
+ int diff;
+ GeoclueAccuracy *acc_a, *acc_b;
+ GeoclueAccuracyLevel level_a, level_b, min_level;
+
+
+ GcMasterProviderPrivate *priv_a = GET_PRIVATE (a);
+ GcMasterProviderPrivate *priv_b = GET_PRIVATE (b);
+
+ /* get the current accuracylevels */
+ switch (iface_min_accuracy->interface) {
+ case GC_IFACE_POSITION:
+ acc_a = priv_a->position_cache.accuracy;
+ acc_b = priv_b->position_cache.accuracy;
+ break;
+ case GC_IFACE_ADDRESS:
+ acc_a = priv_a->address_cache.accuracy;
+ acc_b = priv_b->address_cache.accuracy;
+ break;
+ default:
+ g_warning("iface: %d", iface_min_accuracy->interface);
+ g_assert_not_reached ();
+ }
+
+
+ geoclue_accuracy_get_details (acc_a, &level_a, NULL, NULL);
+ geoclue_accuracy_get_details (acc_b, &level_b, NULL, NULL);
+ min_level = iface_min_accuracy->accuracy_level;
+
+ /* sort by resource requirements and accuracy, but only if both
+ * providers meet the minimum accuracy requirement */
+ if ((level_b >= min_level) &&
+ (level_a >= min_level)) {
+ diff = priv_a->required_resources - priv_b->required_resources;
+ if (diff != 0 ) {
+ return diff;
+ }
+ return level_b - level_a;
+ }
+
+ /* one or both do not meet req's, sort by accuracy */
+ return level_b - level_a;
+}
--- /dev/null
+/*
+ * Geoclue
+ * master-provider.h
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 MASTER_PROVIDER_H
+#define MASTER_PROVIDER_H
+
+
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include "connectivity.h"
+
+G_BEGIN_DECLS
+
+#define GC_TYPE_MASTER_PROVIDER (gc_master_provider_get_type ())
+#define GC_MASTER_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_MASTER_PROVIDER, GcMasterProvider))
+#define GC_IS_MASTER_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GC_TYPE_MASTER_PROVIDER))
+
+typedef enum {
+ GC_IFACE_NONE = 0,
+ GC_IFACE_GEOCLUE = 1 << 0,
+ GC_IFACE_POSITION = 1 << 1,
+ GC_IFACE_ADDRESS = 1 << 2,
+ GC_IFACE_VELOCITY = 1 << 3,
+ GC_IFACE_GEOCODE = 1 << 4,
+ GC_IFACE_REVERSE_GEOCODE = 1 << 5,
+
+ GC_IFACE_ALL = (1 << 6) - 1
+} GcInterfaceFlags;
+
+
+typedef struct _GcMasterProvider {
+ GObject parent;
+} GcMasterProvider;
+
+typedef struct _GcMasterProviderClass {
+ GObjectClass parent_class;
+
+ void (* status_changed) (GcMasterProvider *master_provider,
+ GeoclueStatus status);
+ void (* accuracy_changed) (GcMasterProvider *master_provider,
+ GcInterfaceFlags interface,
+ GeoclueAccuracyLevel status);
+ void (* position_changed) (GcMasterProvider *master_provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy);
+ void (* address_changed) (GcMasterProvider *master_provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy);
+} GcMasterProviderClass;
+
+GType gc_master_provider_get_type (void);
+
+GcMasterProvider *gc_master_provider_new (const char *filename,
+ GeoclueConnectivity *connectivity);
+
+gboolean gc_master_provider_subscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface);
+void gc_master_provider_unsubscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface);
+
+/* for gc_master_provider_compare */
+typedef struct _GcInterfaceAccuracy {
+ GcInterfaceFlags interface;
+ GeoclueAccuracyLevel accuracy_level;
+} GcInterfaceAccuracy;
+
+gint gc_master_provider_compare (GcMasterProvider *a,
+ GcMasterProvider *b,
+ GcInterfaceAccuracy *iface_min_accuracy);
+
+gboolean gc_master_provider_is_good (GcMasterProvider *provider,
+ GcInterfaceFlags iface_types,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean need_update,
+ GeoclueResourceFlags allowed_resources);
+
+void gc_master_provider_network_status_changed (GcMasterProvider *provider,
+ GeoclueNetworkStatus status);
+void gc_master_provider_update_options (GcMasterProvider *provider);
+
+char* gc_master_provider_get_name (GcMasterProvider *provider);
+char* gc_master_provider_get_description (GcMasterProvider *provider);
+char* gc_master_provider_get_service (GcMasterProvider *provider);
+char* gc_master_provider_get_path (GcMasterProvider *provider);
+
+GeoclueStatus gc_master_provider_get_status (GcMasterProvider *provider);
+GeoclueAccuracyLevel gc_master_provider_get_accuracy (GcMasterProvider *provider, GcInterfaceFlags iface);
+
+GeocluePositionFields gc_master_provider_get_position (GcMasterProvider *master_provider,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+gboolean gc_master_provider_get_address (GcMasterProvider *master_provider,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error);
+
+
+G_END_DECLS
+
+#endif /* MASTER_PROVIDER_H */
--- /dev/null
+/*
+ * Geoclue
+ * master.c - Master process
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <config.h>
+
+#include <string.h>
+
+#include "main.h"
+#include "master.h"
+#include "client.h"
+#include "master-provider.h"
+
+#ifdef HAVE_NETWORK_MANAGER
+#include "connectivity-networkmanager.h"
+#else
+#ifdef HAVE_CONIC
+#include "connectivity-conic.h"
+#endif
+#endif
+
+enum {
+ OPTIONS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (GcMaster, gc_master, G_TYPE_OBJECT);
+
+static GList *providers = NULL;
+
+static gboolean gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error);
+
+#include "gc-iface-master-glue.h"
+
+#define GEOCLUE_MASTER_PATH "/org/freedesktop/Geoclue/Master/client"
+static gboolean
+gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error)
+{
+ static guint32 serial = 0;
+ GcMasterClient *client;
+ char *path;
+
+ path = g_strdup_printf ("%s%d", GEOCLUE_MASTER_PATH, serial++);
+ client = g_object_new (GC_TYPE_MASTER_CLIENT, NULL);
+ dbus_g_connection_register_g_object (master->connection, path,
+ G_OBJECT (client));
+
+ if (object_path) {
+ *object_path = path;
+ }
+ return TRUE;
+}
+
+static void
+gc_master_class_init (GcMasterClass *klass)
+{
+ dbus_g_object_type_install_info (gc_master_get_type (),
+ &dbus_glib_gc_iface_master_object_info);
+
+ signals[OPTIONS_CHANGED] = g_signal_new ("options-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterClass, options_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_HASH_TABLE);
+}
+
+/* Load the provider details out of a keyfile */
+static void
+gc_master_add_new_provider (GcMaster *master,
+ const char *filename)
+{
+ GcMasterProvider *provider;
+
+ provider = gc_master_provider_new (filename,
+ master->connectivity);
+
+ if (!provider) {
+ g_warning ("Loading from %s failed", filename);
+ return;
+ }
+
+ providers = g_list_prepend (providers, provider);
+}
+
+/* Scan a directory for .provider files */
+#define PROVIDER_EXTENSION ".provider"
+
+static void
+gc_master_load_providers (GcMaster *master)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const char *filename;
+
+ dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error);
+ if (dir == NULL) {
+ g_warning ("Error opening %s: %s\n", GEOCLUE_PROVIDERS_DIR,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ filename = g_dir_read_name (dir);
+ if (!filename) {
+ g_print ("No providers found in %s\n", dir);
+ } else {
+ g_print ("Found providers:\n");
+ }
+ while (filename) {
+ char *fullname, *ext;
+
+ g_print (" %s\n", filename);
+ ext = strrchr (filename, '.');
+ if (ext == NULL || strcmp (ext, PROVIDER_EXTENSION) != 0) {
+ g_print (" - Ignored\n");
+ filename = g_dir_read_name (dir);
+ continue;
+ }
+
+ fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR,
+ filename, NULL);
+ gc_master_add_new_provider (master, fullname);
+ g_free (fullname);
+
+ filename = g_dir_read_name (dir);
+ }
+
+ g_dir_close (dir);
+}
+
+static void
+gc_master_init (GcMaster *master)
+{
+ GError *error = NULL;
+
+
+ master->connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (master->connection == NULL) {
+ g_warning ("Could not get %s: %s", GEOCLUE_DBUS_BUS,
+ error->message);
+ g_error_free (error);
+ }
+
+ master->connectivity = NULL;
+#ifdef HAVE_NETWORK_MANAGER
+ master->connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_NETWORKMANAGER, NULL));
+#else
+#ifdef HAVE_CONIC
+ master->connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONIC, NULL));
+#endif
+#endif
+
+ gc_master_load_providers (master);
+}
+
+
+GList *
+gc_master_get_providers (GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean can_update,
+ GeoclueResourceFlags allowed,
+ GError **error)
+{
+ GList *l, *p = NULL;
+
+ if (providers == NULL) {
+ return NULL;
+ }
+
+ for (l = providers; l; l = l->next) {
+ GcMasterProvider *provider = l->data;
+
+ if (gc_master_provider_is_good (provider,
+ iface_type,
+ min_accuracy,
+ can_update,
+ allowed)) {
+ p = g_list_prepend (p, provider);
+ }
+ }
+
+ return p;
+}
--- /dev/null
+/*
+ * Geoclue
+ * master.h - Master process
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 _MASTER_H_
+#define _MASTER_H_
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#include <geoclue/geoclue-types.h>
+#include <geoclue/geoclue-accuracy.h>
+#include "connectivity.h"
+#include "master-provider.h"
+
+#define GC_TYPE_MASTER (gc_master_get_type ())
+#define GC_MASTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GC_TYPE_MASTER, GcMaster))
+
+typedef struct {
+ GObject parent;
+
+ GMainLoop *loop;
+ DBusGConnection *connection;
+ GeoclueConnectivity *connectivity;
+} GcMaster;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ void (*options_changed) (GcMaster *master, GHashTable *options);
+} GcMasterClass;
+
+GType gc_master_get_type (void);
+GList *gc_master_get_providers (GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean can_update,
+ GeoclueResourceFlags allowed,
+ GError **error);
+
+#endif
+
--- /dev/null
+[D-BUS Service]
+Name=org.freedesktop.Geoclue.Master
+Exec=@libexecdir@/geoclue-master
--- /dev/null
+if HAVE_GTK
+
+bin_PROGRAMS = geoclue-test-gui
+
+geoclue_test_gui_LDADD = \
+ $(GTK_LIBS) \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_test_gui_CFLAGS= \
+ -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \
+ $(GTK_CFLAGS) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_test_gui_SOURCES = \
+ geoclue-test-gui.c
+
+endif
--- /dev/null
+/*
+ * Geoclue
+ * client-test-gui.c - Geoclue Test GUI
+ *
+ * Authors: Jussi Kukkonen <jku@linux.intel.com>
+ *
+ * Copyright 2008 OpenedHand Ltd
+ * 2008 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <time.h>
+#include <string.h>
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-master-client.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-position.h>
+
+enum {
+ COL_ADDRESS_PROVIDER = 0,
+ COL_ADDRESS_PROVIDER_NAME,
+ COL_ADDRESS_IS_MASTER,
+ COL_ADDRESS_COUNTRY,
+ COL_ADDRESS_COUNTRYCODE,
+ COL_ADDRESS_REGION,
+ COL_ADDRESS_LOCALITY,
+ COL_ADDRESS_AREA,
+ COL_ADDRESS_POSTALCODE,
+ COL_ADDRESS_STREET,
+ NUM_ADDRESS_COLS
+};
+enum {
+ COL_POSITION_PROVIDER = 0,
+ COL_POSITION_PROVIDER_NAME,
+ COL_POSITION_IS_MASTER,
+ COL_POSITION_LAT,
+ COL_POSITION_LON,
+ COL_POSITION_ALT,
+ NUM_POSITION_COLS
+};
+
+
+#define GEOCLUE_TYPE_TEST_GUI geoclue_test_gui_get_type()
+#define GEOCLUE_TEST_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGui))
+#define GEOCLUE_TEST_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGuiClass))
+#define GEOCLUE_TEST_GUI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGuiClass))
+
+typedef struct {
+ GObject parent;
+
+ GtkWidget *window;
+ GtkTextBuffer *buffer;
+
+ GeoclueMasterClient *client;
+ char *master_client_path;
+ GeoclueAccuracyLevel master_accuracy;
+ GeoclueResourceFlags master_resources;
+
+ GtkListStore *position_store;
+ GList *position_providers; /* PositionProviders, first one is master */
+
+ GtkListStore *address_store;
+ GList *address_providers; /* AddressProviders, first one is master */
+} GeoclueTestGui;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueTestGuiClass;
+
+G_DEFINE_TYPE (GeoclueTestGui, geoclue_test_gui, G_TYPE_OBJECT)
+
+
+static void
+geoclue_test_gui_dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (geoclue_test_gui_parent_class)->dispose (object);
+}
+
+
+static void
+geoclue_test_gui_class_init (GeoclueTestGuiClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = geoclue_test_gui_dispose;
+}
+
+
+static void
+geoclue_test_gui_master_log_message (GeoclueTestGui *gui, char *message)
+{
+ GtkTextIter iter;
+ char *line;
+ time_t rawtime;
+ struct tm *timeinfo;
+ char time_buffer [20];
+
+ time (&rawtime);
+ timeinfo = localtime (&rawtime);
+
+ strftime (time_buffer, 19, "%X", timeinfo);
+ line = g_strdup_printf ("%s: %s\n", time_buffer, message);
+
+ gtk_text_buffer_get_end_iter (gui->buffer, &iter);
+ gtk_text_buffer_insert (gui->buffer, &iter, line, -1);
+
+ g_free (line);
+}
+
+static gboolean
+get_matching_tree_iter (GtkTreeModel *model, GeoclueProvider *provider, GtkTreeIter *iter)
+{
+ GeoclueProvider *p = NULL;
+ gboolean valid;
+
+ g_assert (model);
+ g_assert (provider);
+
+ valid = gtk_tree_model_get_iter_first (model, iter);
+ while (valid) {
+ gtk_tree_model_get (model, iter,
+ COL_ADDRESS_PROVIDER, &p,
+ -1);
+ if (p == provider) {
+ return TRUE;
+ }
+
+ valid = gtk_tree_model_iter_next (model, iter);
+ }
+
+ return FALSE;
+}
+
+static void
+update_address (GeoclueTestGui *gui, GeoclueAddress *address, GHashTable *details)
+{
+ GtkTreeIter iter;
+
+ g_assert (details);
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store),
+ GEOCLUE_PROVIDER (address),
+ &iter)) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_COUNTRY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRY),
+ COL_ADDRESS_COUNTRYCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ COL_ADDRESS_REGION, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_REGION),
+ COL_ADDRESS_LOCALITY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_LOCALITY),
+ COL_ADDRESS_AREA, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_AREA),
+ COL_ADDRESS_POSTALCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ COL_ADDRESS_STREET, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_STREET),
+ -1);
+ }
+}
+
+
+static void
+update_position (GeoclueTestGui *gui, GeocluePosition *position,
+ double lat, double lon, double alt)
+{
+ GtkTreeIter iter;
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store),
+ GEOCLUE_PROVIDER (position),
+ &iter)) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_LAT, lat,
+ COL_POSITION_LON, lon,
+ COL_POSITION_ALT, alt,
+ -1);
+ }
+}
+
+
+static void
+address_changed (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GeoclueTestGui *gui)
+{
+ update_address (gui, address, details);
+}
+
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GeoclueTestGui *gui)
+{
+ update_position (gui, position, latitude, longitude, altitude);
+}
+
+static void
+address_callback (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_warning ("Error getting address: %s\n", error->message);
+ g_error_free (error);
+ details = geoclue_address_details_new ();
+ }
+
+ update_address (GEOCLUE_TEST_GUI (userdata), address, details);
+}
+
+static void
+info_callback (GeoclueProvider *provider,
+ char *name,
+ char *description,
+ GError *error,
+ gpointer userdata)
+{
+ GtkTreeIter iter;
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_warning ("Error getting provider info: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store),
+ provider,
+ &iter)) {
+ /* skip master, that's handled in master_*_provider_changed */
+ if (strcmp (name, "Geoclue Master") != 0) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER_NAME, name,
+ -1);
+ }
+ }
+
+ if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store),
+ provider,
+ &iter)) {
+ /* skip master, that's handled in master_*_provider_changed */
+ if (strcmp (name, "Geoclue Master") != 0) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER_NAME, name,
+ -1);
+ }
+ }
+}
+
+static void
+add_to_address_store (GeoclueTestGui *gui, GeoclueAddress *address, gboolean is_master)
+{
+ GtkTreeIter iter;
+
+ g_assert (gui->address_store);
+ g_assert (address);
+
+ if (is_master) {
+ /* master is already on the first line */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store), &iter);
+ } else {
+ gtk_list_store_append (gui->address_store, &iter);
+ }
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER, address,
+ COL_ADDRESS_IS_MASTER, is_master,
+ -1);
+
+ g_signal_connect (G_OBJECT (address), "address-changed",
+ G_CALLBACK (address_changed), gui);
+
+ geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (address),
+ info_callback,
+ gui);
+ geoclue_address_get_address_async (address, address_callback, gui);
+
+}
+
+static gboolean
+get_next_provider (GDir *dir, char **name, char **service, char **path, char **ifaces)
+{
+ const char *filename;
+ char *fullname;
+ GKeyFile *keyfile;
+ gboolean ret;
+ GError *error;
+
+ filename = g_dir_read_name (dir);
+ if (!filename) {
+ return FALSE;
+ }
+
+ fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR,
+ filename, NULL);
+ keyfile = g_key_file_new ();
+ ret = g_key_file_load_from_file (keyfile, fullname,
+ G_KEY_FILE_NONE, &error);
+ g_free (fullname);
+
+ if (!ret) {
+ g_warning ("Error loading %s: %s", filename, error->message);
+ g_error_free (error);
+ } else {
+ *name = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Name", NULL);
+
+ *service = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Service", NULL);
+ *path = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Path", NULL);
+ *ifaces = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Interfaces", NULL);
+ }
+
+ g_key_file_free (keyfile);
+ return TRUE;
+}
+
+static void
+position_callback (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double lat, double lon, double alt,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_warning ("Error getting position: %s\n", error->message);
+ g_error_free (error);
+ lat = lon = alt = 0.0/0.0;
+ }
+ update_position (GEOCLUE_TEST_GUI (userdata), position, lat, lon, alt);
+}
+
+static void
+add_to_position_store (GeoclueTestGui *gui, GeocluePosition *position, gboolean is_master)
+{
+ GtkTreeIter iter;
+
+ g_assert (gui->position_store);
+ g_assert (position);
+
+ if (is_master) {
+ /* master is already on the first line */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store), &iter);
+ } else {
+ gtk_list_store_append (gui->position_store, &iter);
+ }
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER, position,
+ COL_POSITION_IS_MASTER, is_master,
+ -1);
+
+ g_signal_connect (G_OBJECT (position), "position-changed",
+ G_CALLBACK (position_changed), gui);
+
+ geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (position),
+ info_callback,
+ gui);
+ geoclue_position_get_position_async (position, position_callback, gui);
+}
+
+
+static GtkWidget *
+get_address_tree_view (GeoclueTestGui *gui)
+{
+ GtkTreeView *view;
+ GtkCellRenderer *renderer;
+
+ view = GTK_TREE_VIEW (gtk_tree_view_new ());
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "Provider",
+ renderer,
+ "text",
+ COL_ADDRESS_PROVIDER_NAME,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ renderer,
+ "text",
+ COL_ADDRESS_COUNTRY,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ renderer,
+ "text",
+ COL_ADDRESS_COUNTRYCODE,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_REGION,
+ renderer,
+ "text",
+ COL_ADDRESS_REGION,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ renderer,
+ "text",
+ COL_ADDRESS_LOCALITY,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_AREA,
+ renderer,
+ "text",
+ COL_ADDRESS_AREA,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ renderer,
+ "text",
+ COL_ADDRESS_POSTALCODE,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ renderer,
+ "text",
+ COL_ADDRESS_STREET,
+ NULL);
+
+ gui->address_store = gtk_list_store_new (NUM_ADDRESS_COLS,
+ G_TYPE_POINTER,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->address_store));
+
+ return GTK_WIDGET (view);
+}
+
+
+static GtkWidget *
+get_position_tree_view (GeoclueTestGui *gui)
+{
+ GtkTreeView *view;
+ GtkCellRenderer *renderer;
+
+ view = GTK_TREE_VIEW (gtk_tree_view_new ());
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "Provider",
+ renderer,
+ "text",
+ COL_POSITION_PROVIDER_NAME,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "latitude",
+ renderer,
+ "text",
+ COL_POSITION_LAT,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "longitude",
+ renderer,
+ "text",
+ COL_POSITION_LON,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (view, -1,
+ "altitude",
+ renderer,
+ "text",
+ COL_POSITION_ALT,
+ NULL);
+
+ gui->position_store = gtk_list_store_new (NUM_POSITION_COLS,
+ G_TYPE_POINTER,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE);
+
+ gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->position_store));
+
+ return GTK_WIDGET (view);
+}
+
+static void
+master_position_provider_changed (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+ char *msg;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store),
+ &iter)) {
+ gtk_list_store_set (gui->position_store, &iter,
+ COL_POSITION_PROVIDER_NAME, g_strdup_printf ("Master (%s)", name),
+ -1);
+ }
+ msg = g_strdup_printf ("Master: position provider changed: %s", name);
+ geoclue_test_gui_master_log_message (gui, msg);
+ g_free (msg);
+}
+
+static void
+master_address_provider_changed (GeoclueMasterClient *client,
+ char *name,
+ char *description,
+ char *service,
+ char *path,
+ GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+ char *msg;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store),
+ &iter)) {
+ gtk_list_store_set (gui->address_store, &iter,
+ COL_ADDRESS_PROVIDER_NAME, g_strdup_printf ("Master (%s)", name),
+ -1);
+ }
+ msg = g_strdup_printf ("Master: address provider changed: %s", name);
+ geoclue_test_gui_master_log_message (gui, msg);
+ g_free (msg);
+}
+
+static void
+set_requirements_callback (GeoclueMasterClient *client,
+ GError *error,
+ gpointer userdata)
+{
+ if (error) {
+ g_printerr ("Setting requirements failed : %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+update_master_requirements (GeoclueTestGui *gui)
+{
+ geoclue_master_client_set_requirements_async (gui->client,
+ gui->master_accuracy,
+ 0,
+ FALSE,
+ gui->master_resources,
+ set_requirements_callback,
+ NULL);
+}
+
+static void
+create_address_callback (GeoclueMasterClient *client,
+ GeoclueAddress *address,
+ GError *error,
+ gpointer userdata)
+{
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Master Client: Failed to create address: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ add_to_address_store (gui, address, TRUE);
+}
+
+static void
+create_position_callback (GeoclueMasterClient *client,
+ GeocluePosition *position,
+ GError *error,
+ gpointer userdata)
+{
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Master Client: Failed to create position: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ add_to_position_store (gui, position, TRUE);
+}
+
+
+static void
+create_client_callback (GeoclueMaster *master,
+ GeoclueMasterClient *client,
+ char *object_path,
+ GError *error,
+ gpointer userdata)
+{
+ GDir *dir;
+ char *name, *path, *service, *ifaces;
+ GtkTreeIter iter;
+ GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata);
+
+ if (error) {
+ g_printerr ("Failed to create master client: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ gui->client = client;
+
+ g_signal_connect (G_OBJECT (gui->client), "position-provider-changed",
+ G_CALLBACK (master_position_provider_changed), gui);
+ g_signal_connect (G_OBJECT (gui->client), "address-provider-changed",
+ G_CALLBACK (master_address_provider_changed), gui);
+ update_master_requirements (gui);
+
+ /* add master providers to the lists */
+ gtk_list_store_append (gui->position_store, &iter);
+ geoclue_master_client_create_position_async (gui->client,
+ create_position_callback,
+ gui);
+ gtk_list_store_append (gui->address_store, &iter);
+ geoclue_master_client_create_address_async (gui->client,
+ create_address_callback,
+ gui);
+
+ /* add individual providers based on files in GEOCLUE_PROVIDERS_DIR */
+ dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error);
+ if (!dir) {
+ g_warning ("Error opening %s: %s\n",
+ GEOCLUE_PROVIDERS_DIR, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ name = service = path = ifaces = NULL;
+ while (get_next_provider (dir, &name, &service, &path, &ifaces)) {
+ if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Position")) {
+ add_to_position_store (gui, geoclue_position_new (service, path), FALSE);
+ }
+ if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Address")) {
+ add_to_address_store (gui, geoclue_address_new (service, path), FALSE);
+ }
+ g_free (name);
+ g_free (path);
+ g_free (service);
+ g_free (ifaces);
+ }
+
+ g_dir_close (dir);
+ g_object_unref (master);
+}
+
+static void
+geoclue_test_gui_load_providers (GeoclueTestGui *gui)
+{
+ GeoclueMaster *master;
+
+ master = geoclue_master_get_default ();
+ geoclue_master_create_client_async (master,
+ create_client_callback,
+ gui);
+}
+
+static void
+accuracy_combo_changed (GtkComboBox *combo, GeoclueTestGui *gui)
+{
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter (combo, &iter)) {
+ GtkTreeModel *model;
+
+ model = gtk_combo_box_get_model (combo);
+ gtk_tree_model_get (model, &iter, 0, &gui->master_accuracy, -1);
+
+ update_master_requirements (gui);
+ }
+}
+
+static void
+gps_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_GPS;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_GPS;
+ }
+ update_master_requirements (gui);
+}
+
+static void
+network_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_NETWORK;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_NETWORK;
+ }
+ update_master_requirements (gui);
+}
+
+static void
+cell_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) {
+ gui->master_resources |= GEOCLUE_RESOURCE_CELL;
+ } else {
+ gui->master_resources &= ~GEOCLUE_RESOURCE_CELL;
+ }
+ update_master_requirements (gui);
+}
+
+static GtkWidget*
+get_accuracy_combo (GeoclueTestGui *gui)
+{
+ GtkListStore *store;
+ GtkWidget *combo;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
+
+ store = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_COUNTRY,
+ 1, "Country",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_REGION,
+ 1, "Region",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_LOCALITY,
+ 1, "Locality",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_POSTALCODE,
+ 1, "Postalcode",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_STREET,
+ 1, "Street",
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ 1, "Detailed",
+ -1);
+
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
+ "text", 1, NULL);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+ gui->master_accuracy = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+
+ return combo;
+}
+
+
+static void
+geoclue_test_gui_init (GeoclueTestGui *gui)
+{
+ GtkWidget *address_view;
+ GtkWidget *position_view;
+ GtkWidget *notebook;
+ GtkWidget *box;
+ GtkWidget *frame;
+ GtkWidget *hbox, *vbox;
+ GtkWidget *label;
+ GtkWidget *combo, *check;
+ GtkWidget *scrolled_win;
+ GtkWidget *view;
+
+ gui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (gui->window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ view = gtk_text_view_new ();
+ gtk_widget_set_size_request (GTK_WIDGET (view), 500, 200);
+ g_object_set (G_OBJECT (view), "editable", FALSE, NULL);
+ gui->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+
+ box = gtk_vbox_new (FALSE, 8);
+ gtk_container_add (GTK_CONTAINER (gui->window), box);
+
+ frame = gtk_frame_new ("Master settings");
+ gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 4);
+
+
+ hbox = gtk_hbox_new (FALSE, 24);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 8);
+ label = gtk_label_new ("Required accuracy level:");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ combo = get_accuracy_combo (gui);
+ g_signal_connect (combo, "changed",
+ G_CALLBACK (accuracy_combo_changed), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+ label = gtk_label_new ("Allow resources:");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("Network");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
+ gui->master_resources |= GEOCLUE_RESOURCE_NETWORK;
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (network_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("GPS");
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (gps_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ check = gtk_check_button_new_with_label ("Cell");
+ g_signal_connect (check, "toggled",
+ G_CALLBACK (cell_check_toggled), gui);
+ gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+
+ notebook = gtk_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (box), notebook, FALSE, FALSE, 0);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), TRUE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), TRUE);
+
+ address_view = get_address_tree_view (gui);
+ label = gtk_label_new ("Address");
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), address_view, label);
+
+ position_view = get_position_tree_view (gui);
+ label = gtk_label_new ("Position");
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), position_view, label);
+
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);
+ label = gtk_label_new ("Master log");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+ gtk_container_add (GTK_CONTAINER (box), scrolled_win);
+ gtk_container_add (GTK_CONTAINER (scrolled_win), view);
+
+ geoclue_test_gui_load_providers (gui);
+
+ geoclue_test_gui_master_log_message (gui, "Started Geoclue test UI");
+
+ gtk_widget_show_all (gui->window);
+}
+
+
+int main (int argc, char **argv)
+{
+ GeoclueTestGui *gui;
+
+ gtk_init (&argc, &argv);
+
+ gui = g_object_new (GEOCLUE_TYPE_TEST_GUI, NULL);
+ gtk_main ();
+
+ g_object_unref (gui);
+
+ return 0;
+}