ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #01186
[Merge] lp:~dbarth/indicator-sound/character-limit into lp:indicator-sound
David Barth has proposed merging lp:~dbarth/indicator-sound/character-limit into lp:indicator-sound.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
Enforce the current character limit for the broadcast field. 140 is the current limit for services managed by gwibber.
--
https://code.launchpad.net/~dbarth/indicator-sound/character-limit/+merge/21440
Your team ayatana-commits is subscribed to branch lp:indicator-sound.
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2010-03-16 11:29:18 +0000
@@ -0,0 +1,63 @@
+compile
+m4
+po
+src/libmessaging.la
+src/libmessaging_la-indicator-messages.lo
+config.guess.cdbs-orig
+config.sub.cdbs-orig
+debian/compat
+debian/files
+debian/indicator-messages
+debian/indicator-messages.debhelper.log
+debian/indicator-messages.postinst.debhelper
+debian/indicator-messages.postrm.debhelper
+debian/indicator-messages.substvars
+debian/stamp-autotools-files
+debian/stamp-makefile-build
+libstatus-users-session.la
+libstatus_users_session_la-indicator-fusa.lo
+libstatus_users_session_la-indicator-sus.lo
+indicator-session-service
+indicator-status-service
+indicator-users-service
+indicator-session.service
+indicator-status.service
+indicator-users.service
+indicator-me.service
+status-service-client.h
+status-service-server.h
+debian/indicator-fusa
+debian/indicator-fusa.debhelper.log
+debian/indicator-fusa.postinst.debhelper
+debian/indicator-fusa.postrm.debhelper
+debian/indicator-fusa.substvars
+debian/indicator-sus
+debian/indicator-sus.debhelper.log
+debian/indicator-sus.postinst.debhelper
+debian/indicator-sus.postrm.debhelper
+debian/indicator-sus.substvars
+gtk-logout-helper
+.deps
+.libs
+src/libsession.la
+src/libsession_la-indicator-session.lo
+src/status-provider-pidgin-marshal.c
+src/status-provider-pidgin-marshal.h
+src/status-provider-telepathy-marshal.c
+src/status-provider-telepathy-marshal.h
+src/status-provider-mc5-marshal.c
+src/status-provider-mc5-marshal.h
+data/indicator-session.schemas
+src/users-service-client.h
+src/users-service-marshal.c
+src/users-service-marshal.h
+indicator-me-[0-9].[0-9].[0-9].tar.gz
+indicator-me-[0-9].[0-9].tar.gz
+indicator-me-[0-9].[0-9].[0-9].tar.gz.asc
+indicator-me-[0-9].[0-9].tar.gz.asc
+src/indicator-me-service
+src/libme.la
+src/libme_la-indicator-me.lo
+po/indicator-me.pot
+src/me-service-client.h
+src/me-service-server.h
=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added file 'AUTHORS'
--- AUTHORS 1970-01-01 00:00:00 +0000
+++ AUTHORS 2010-03-16 11:29:18 +0000
@@ -0,0 +1,2 @@
+Ted Gould <ted@xxxxxxxxxxxxx>
+Cody Russell <crussell@xxxxxxxxxxxxx>
=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'COPYING'
--- COPYING 1970-01-01 00:00:00 +0000
+++ COPYING 2010-03-16 11:29:18 +0000
@@ -0,0 +1,676 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
=== renamed file 'COPYING' => 'COPYING.moved'
=== added file 'ChangeLog'
=== renamed file 'ChangeLog' => 'ChangeLog.moved'
=== added file 'Makefile.am'
--- Makefile.am 1970-01-01 00:00:00 +0000
+++ Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,9 @@
+
+SUBDIRS = \
+ src \
+ data \
+ po
+EXTRA_DIST = autogen.sh
+
+DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall
+
=== renamed file 'Makefile.am' => 'Makefile.am.moved'
=== added file 'NEWS'
=== renamed file 'NEWS' => 'NEWS.moved'
=== added file 'README'
=== renamed file 'README' => 'README.moved'
=== added file 'autogen.sh'
--- autogen.sh 1970-01-01 00:00:00 +0000
+++ autogen.sh 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+PKG_NAME="indicator-me"
+
+which gnome-autogen.sh || {
+ echo "You need gnome-common from GNOME SVN"
+ exit 1
+}
+
+USE_GNOME2_MACROS=1 \
+. gnome-autogen.sh
=== renamed file 'autogen.sh' => 'autogen.sh.moved'
=== added file 'configure.ac'
--- configure.ac 1970-01-01 00:00:00 +0000
+++ configure.ac 2010-03-16 11:29:18 +0000
@@ -0,0 +1,138 @@
+
+AC_INIT(indicator-me, 0.2.5, david.barth@xxxxxxxxxxxxx)
+AC_COPYRIGHT([Copyright 2009, 2010 Canonical])
+
+AC_PREREQ(2.53)
+
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(indicator-me, 0.2.5)
+
+AM_MAINTAINER_MODE
+
+IT_PROG_INTLTOOL([0.35.0])
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_STDC_HEADERS
+AC_PROG_LIBTOOL
+
+AC_SUBST(VERSION)
+AC_CONFIG_MACRO_DIR([m4])
+
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
+###########################
+# Dependencies
+###########################
+
+GTK_REQUIRED_VERSION=2.12
+INDICATOR_REQUIRED_VERSION=0.3.0
+DBUSMENUGTK_REQUIRED_VERSION=0.2.2
+DBUSMENUGLIB_REQUIRED_VERSION=0.2.2
+TELEPATHYGLIB_REQUIRED_VERSION=0.9.0
+GCONF_REQUIRED_VERSION=2.0.0
+INDICATOR_DISPLAY_OBJECTS=0.1
+
+PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ indicator >= $INDICATOR_REQUIRED_VERSION
+ libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS
+ dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION)
+PKG_CHECK_MODULES(MESERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
+ gconf-2.0 >= $GCONF_REQUIRED_VERSION
+ indicator >= $INDICATOR_REQUIRED_VERSION
+ telepathy-glib >= $TELEPATHYGLIB_REQUIRED_VERSION)
+
+###########################
+# Check to see if we're local
+###########################
+
+with_localinstall="no"
+AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all of the files localy instead of system directories (for distcheck)]), with_localinstall=$enableval, with_localinstall=no)
+
+###########################
+# Indicator Info
+###########################
+
+if test "x$with_localinstall" = "xyes"; then
+ INDICATORDIR="${libdir}/indicators/3/"
+ INDICATORICONSDIR="${datadir}/indicator-applet/icons/"
+else
+ INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator`
+ INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator`
+fi
+AC_SUBST(INDICATORDIR)
+AC_SUBST(INDICATORICONSDIR)
+
+###########################
+# DBus Service Info
+###########################
+
+if test "x$with_localinstall" = "xyes"; then
+ DBUSSERVICEDIR="${datadir}/dbus-1/services/"
+else
+ DBUSSERVICEDIR=`$PKG_CONFIG --variable=session_bus_services_dir dbus-1`
+fi
+AC_SUBST(DBUSSERVICEDIR)
+
+##############################
+# Custom Junk
+##############################
+
+AC_DEFUN([AC_DEFINE_PATH], [
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_path=`eval echo [$]$2`
+ ac_define_path=`eval echo [$]ac_define_path`
+ $1="$ac_define_path"
+ AC_SUBST($1)
+ ifelse($3, ,
+ AC_DEFINE_UNQUOTED($1, "$ac_define_path"),
+ AC_DEFINE_UNQUOTED($1, "$ac_define_path", $3))
+])
+
+###########################
+# Internationalization
+###########################
+
+GETTEXT_PACKAGE=indicator-me
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Name of the default get text domain])
+AC_DEFINE_PATH(GNOMELOCALEDIR, "${datadir}/locale", [locale directory])
+
+AM_GLIB_GNU_GETTEXT
+
+###########################
+# Files
+###########################
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+data/Makefile
+data/icons/Makefile
+data/icons/16x16/Makefile
+data/icons/16x16/status/Makefile
+data/icons/22x22/Makefile
+data/icons/22x22/status/Makefile
+data/icons/24x24/Makefile
+data/icons/24x24/status/Makefile
+data/icons/32x32/Makefile
+data/icons/32x32/status/Makefile
+data/icons/48x48/Makefile
+data/icons/48x48/status/Makefile
+data/icons/scalable/Makefile
+data/icons/scalable/status/Makefile
+po/Makefile.in
+])
+
+###########################
+# Results
+###########################
+
+AC_MSG_NOTICE([
+
+Me Indicator Configuration:
+
+ Prefix: $prefix
+])
=== renamed file 'configure.ac' => 'configure.ac.moved'
=== added directory 'data'
=== renamed directory 'data' => 'data.moved'
=== added file 'data/Makefile.am'
--- data/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,16 @@
+SUBDIRS = icons
+
+dbus_servicesdir = $(DBUSSERVICEDIR)
+service_in_files = indicator-me.service.in
+dbus_services_DATA = $(service_in_files:.service.in=.service)
+
+%.service: %.service.in
+ sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+
+EXTRA_DIST = \
+ $(service_in_files)
+
+CLEANFILES = \
+ $(dbus_services_DATA)
+
=== added directory 'data/icons'
=== added directory 'data/icons/16x16'
=== added file 'data/icons/16x16/Makefile.am'
--- data/icons/16x16/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/16x16/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/16x16/status'
=== added file 'data/icons/16x16/status/Makefile.am'
--- data/icons/16x16/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/16x16/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/16x16/status
+
+icons_DATA = \
+ user-available.png \
+ user-offline.png \
+ user-away.png \
+ user-busy.png \
+ user-invisible.png
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/16x16/status/user-available.png'
Binary files data/icons/16x16/status/user-available.png 1970-01-01 00:00:00 +0000 and data/icons/16x16/status/user-available.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/16x16/status/user-away.png'
Binary files data/icons/16x16/status/user-away.png 1970-01-01 00:00:00 +0000 and data/icons/16x16/status/user-away.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/16x16/status/user-busy.png'
Binary files data/icons/16x16/status/user-busy.png 1970-01-01 00:00:00 +0000 and data/icons/16x16/status/user-busy.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/16x16/status/user-invisible.png'
Binary files data/icons/16x16/status/user-invisible.png 1970-01-01 00:00:00 +0000 and data/icons/16x16/status/user-invisible.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/16x16/status/user-offline.png'
Binary files data/icons/16x16/status/user-offline.png 1970-01-01 00:00:00 +0000 and data/icons/16x16/status/user-offline.png 2010-03-16 11:29:18 +0000 differ
=== added directory 'data/icons/22x22'
=== added file 'data/icons/22x22/Makefile.am'
--- data/icons/22x22/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/22x22/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/22x22/status'
=== added file 'data/icons/22x22/status/Makefile.am'
--- data/icons/22x22/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/22x22/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/22x22/status
+
+icons_DATA = \
+ user-available.png \
+ user-offline.png \
+ user-away.png \
+ user-busy.png \
+ user-invisible.png
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/22x22/status/user-available.png'
Binary files data/icons/22x22/status/user-available.png 1970-01-01 00:00:00 +0000 and data/icons/22x22/status/user-available.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/22x22/status/user-away.png'
Binary files data/icons/22x22/status/user-away.png 1970-01-01 00:00:00 +0000 and data/icons/22x22/status/user-away.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/22x22/status/user-busy.png'
Binary files data/icons/22x22/status/user-busy.png 1970-01-01 00:00:00 +0000 and data/icons/22x22/status/user-busy.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/22x22/status/user-invisible.png'
Binary files data/icons/22x22/status/user-invisible.png 1970-01-01 00:00:00 +0000 and data/icons/22x22/status/user-invisible.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/22x22/status/user-offline.png'
Binary files data/icons/22x22/status/user-offline.png 1970-01-01 00:00:00 +0000 and data/icons/22x22/status/user-offline.png 2010-03-16 11:29:18 +0000 differ
=== added directory 'data/icons/24x24'
=== added file 'data/icons/24x24/Makefile.am'
--- data/icons/24x24/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/24x24/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/24x24/status'
=== added file 'data/icons/24x24/status/Makefile.am'
--- data/icons/24x24/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/24x24/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/24x24/status
+
+icons_DATA = \
+ user-available.png \
+ user-offline.png \
+ user-away.png \
+ user-busy.png \
+ user-invisible.png
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/24x24/status/user-available.png'
Binary files data/icons/24x24/status/user-available.png 1970-01-01 00:00:00 +0000 and data/icons/24x24/status/user-available.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/24x24/status/user-away.png'
Binary files data/icons/24x24/status/user-away.png 1970-01-01 00:00:00 +0000 and data/icons/24x24/status/user-away.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/24x24/status/user-busy.png'
Binary files data/icons/24x24/status/user-busy.png 1970-01-01 00:00:00 +0000 and data/icons/24x24/status/user-busy.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/24x24/status/user-invisible.png'
Binary files data/icons/24x24/status/user-invisible.png 1970-01-01 00:00:00 +0000 and data/icons/24x24/status/user-invisible.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/24x24/status/user-offline.png'
Binary files data/icons/24x24/status/user-offline.png 1970-01-01 00:00:00 +0000 and data/icons/24x24/status/user-offline.png 2010-03-16 11:29:18 +0000 differ
=== added directory 'data/icons/32x32'
=== added file 'data/icons/32x32/Makefile.am'
--- data/icons/32x32/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/32x32/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/32x32/status'
=== added file 'data/icons/32x32/status/Makefile.am'
--- data/icons/32x32/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/32x32/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/32x32/status
+
+icons_DATA = \
+ user-available.png \
+ user-offline.png \
+ user-away.png \
+ user-busy.png \
+ user-invisible.png
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/32x32/status/user-available.png'
Binary files data/icons/32x32/status/user-available.png 1970-01-01 00:00:00 +0000 and data/icons/32x32/status/user-available.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/32x32/status/user-away.png'
Binary files data/icons/32x32/status/user-away.png 1970-01-01 00:00:00 +0000 and data/icons/32x32/status/user-away.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/32x32/status/user-busy.png'
Binary files data/icons/32x32/status/user-busy.png 1970-01-01 00:00:00 +0000 and data/icons/32x32/status/user-busy.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/32x32/status/user-invisible.png'
Binary files data/icons/32x32/status/user-invisible.png 1970-01-01 00:00:00 +0000 and data/icons/32x32/status/user-invisible.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/32x32/status/user-offline.png'
Binary files data/icons/32x32/status/user-offline.png 1970-01-01 00:00:00 +0000 and data/icons/32x32/status/user-offline.png 2010-03-16 11:29:18 +0000 differ
=== added directory 'data/icons/48x48'
=== added file 'data/icons/48x48/Makefile.am'
--- data/icons/48x48/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/48x48/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/48x48/status'
=== added file 'data/icons/48x48/status/Makefile.am'
--- data/icons/48x48/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/48x48/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/48x48/status
+
+icons_DATA = \
+ user-available.png \
+ user-offline.png \
+ user-away.png \
+ user-busy.png \
+ user-invisible.png
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/48x48/status/user-available.png'
Binary files data/icons/48x48/status/user-available.png 1970-01-01 00:00:00 +0000 and data/icons/48x48/status/user-available.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/48x48/status/user-away.png'
Binary files data/icons/48x48/status/user-away.png 1970-01-01 00:00:00 +0000 and data/icons/48x48/status/user-away.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/48x48/status/user-busy.png'
Binary files data/icons/48x48/status/user-busy.png 1970-01-01 00:00:00 +0000 and data/icons/48x48/status/user-busy.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/48x48/status/user-invisible.png'
Binary files data/icons/48x48/status/user-invisible.png 1970-01-01 00:00:00 +0000 and data/icons/48x48/status/user-invisible.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/48x48/status/user-offline.png'
Binary files data/icons/48x48/status/user-offline.png 1970-01-01 00:00:00 +0000 and data/icons/48x48/status/user-offline.png 2010-03-16 11:29:18 +0000 differ
=== added file 'data/icons/Makefile.am'
--- data/icons/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,15 @@
+SUBDIRS = scalable 16x16 22x22 24x24 32x32 48x48
+
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(INDICATORICONSDIR)/hicolor
+
+install-data-hook: update-icon-cache
+uninstall-hook: update-icon-cache
+update-icon-cache:
+ @-if test -z "$(DESTDIR)"; then \
+ echo "Updating Gtk icon cache."; \
+ $(gtk_update_icon_cache); \
+ else \
+ echo "*** Icon cache not updated. After (un)install, run this:"; \
+ echo "*** $(gtk_update_icon_cache)"; \
+ fi
+
=== added directory 'data/icons/scalable'
=== added file 'data/icons/scalable/Makefile.am'
--- data/icons/scalable/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+SUBDIRS = status
=== added directory 'data/icons/scalable/status'
=== added file 'data/icons/scalable/status/Makefile.am'
--- data/icons/scalable/status/Makefile.am 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,11 @@
+
+iconsdir = $(INDICATORICONSDIR)/hicolor/scalable/status
+
+icons_DATA = \
+ user-available.svg \
+ user-offline.svg \
+ user-away.svg \
+ user-busy.svg \
+ user-invisible.svg
+
+EXTRA_DIST = $(icons_DATA)
=== added file 'data/icons/scalable/status/user-available.svg'
--- data/icons/scalable/status/user-available.svg 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/user-available.svg 2010-03-16 11:29:18 +0000
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg4908"
+ sodipodi:version="0.32"
+ inkscape:version="0.44+devel"
+ sodipodi:docbase="/home/andreas/project/gossip/16x16"
+ sodipodi:docname="status-avaible.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/andreas/project/gossip/16x16/status-avaible.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:modified="true">
+ <defs
+ id="defs4910">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5899">
+ <stop
+ style="stop-color:#7fe719;stop-opacity:1"
+ offset="0"
+ id="stop5901" />
+ <stop
+ style="stop-color:#67bc13;stop-opacity:1"
+ offset="1"
+ id="stop5903" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5899"
+ id="radialGradient5905"
+ cx="9.466115"
+ cy="8.9839392"
+ fx="9.466115"
+ fy="8.9839392"
+ r="6.7474474"
+ gradientTransform="matrix(1.1671849,-3.2679277e-3,2.7524467e-3,1.0150183,-1.6222549,-0.2024225)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.197802"
+ inkscape:cx="14.452639"
+ inkscape:cy="6.4458104"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1674"
+ inkscape:window-height="969"
+ inkscape:window-x="0"
+ inkscape:window-y="26" />
+ <metadata
+ id="metadata4913">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient5905);fill-opacity:1;stroke:#376e01;stroke-width:0.97113216;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path4926"
+ sodipodi:cx="7.9737625"
+ sodipodi:cy="7.7221532"
+ sodipodi:rx="6.2618814"
+ sodipodi:ry="6.3632426"
+ d="M 14.235644 7.7221532 A 6.2618814 6.3632426 0 1 1 1.7118812,7.7221532 A 6.2618814 6.3632426 0 1 1 14.235644 7.7221532 z"
+ transform="matrix(1.0380267,0,0,1.0214918,-0.2769783,0.1118841)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.14770162;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path5897"
+ sodipodi:cx="7.9737625"
+ sodipodi:cy="7.7221532"
+ sodipodi:rx="6.2618814"
+ sodipodi:ry="6.3632426"
+ d="M 14.235644 7.7221532 A 6.2618814 6.3632426 0 1 1 1.7118812,7.7221532 A 6.2618814 6.3632426 0 1 1 14.235644 7.7221532 z"
+ transform="matrix(0.8783303,0,0,0.8643392,0.996403,1.3254404)" />
+ </g>
+</svg>
=== added file 'data/icons/scalable/status/user-away.svg'
--- data/icons/scalable/status/user-away.svg 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/user-away.svg 2010-03-16 11:29:18 +0000
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg4908"
+ sodipodi:version="0.32"
+ inkscape:version="0.44+devel"
+ sodipodi:docbase="/home/andreas/project/gossip/16x16"
+ sodipodi:docname="status-away.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/andreas/project/gossip/16x16/status-away.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:modified="true">
+ <defs
+ id="defs4910">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5917">
+ <stop
+ style="stop-color:#f80000;stop-opacity:1"
+ offset="0"
+ id="stop5919" />
+ <stop
+ style="stop-color:#e70000;stop-opacity:1"
+ offset="1"
+ id="stop5921" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5917"
+ id="linearGradient5923"
+ x1="6.5096536"
+ y1="8.5893564"
+ x2="9.9108915"
+ y2="11.540099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9925682,6.043956e-8,1.1147803e-2)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627417"
+ inkscape:cx="13.206814"
+ inkscape:cy="4.0564985"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1674"
+ inkscape:window-height="969"
+ inkscape:window-x="0"
+ inkscape:window-y="26" />
+ <metadata
+ id="metadata4913">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="fill:url(#linearGradient5923);fill-opacity:1;fill-rule:evenodd;stroke:#8a0000;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 1.5,13.5 L 14.499999,13.5 L 7.9789933,1.4999999 L 1.5,13.5 z "
+ id="path4944"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="opacity:0.3;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000012px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 3.2186016,12.488535 L 12.832121,12.488535 L 8.0098272,3.5671249 L 3.2186016,12.488535 z "
+ id="path4946"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
=== added file 'data/icons/scalable/status/user-busy.svg'
--- data/icons/scalable/status/user-busy.svg 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/user-busy.svg 2010-03-16 11:29:18 +0000
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg6941"
+ sodipodi:version="0.32"
+ inkscape:version="0.44+devel"
+ sodipodi:docbase="/home/andreas/project/gossip/16x16"
+ sodipodi:docname="status-busy.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/andreas/project/gossip/16x16/status-busy.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:modified="true">
+ <defs
+ id="defs6943">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5899">
+ <stop
+ style="stop-color:#fce94f;stop-opacity:1"
+ offset="0"
+ id="stop5901" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1"
+ offset="1"
+ id="stop5903" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5899"
+ id="radialGradient5905"
+ cx="9.466115"
+ cy="8.9839392"
+ fx="9.466115"
+ fy="8.9839392"
+ r="6.7474474"
+ gradientTransform="matrix(1.1671849,-3.2679277e-3,2.7524467e-3,1.0150183,-1.6222549,-0.2024225)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.696217"
+ inkscape:cx="17.665904"
+ inkscape:cy="9.7718474"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1674"
+ inkscape:window-height="969"
+ inkscape:window-x="0"
+ inkscape:window-y="26" />
+ <metadata
+ id="metadata6946">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient5905);fill-opacity:1;stroke:#8d7300;stroke-width:0.97113222;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path4926"
+ sodipodi:cx="7.9737625"
+ sodipodi:cy="7.7221532"
+ sodipodi:rx="6.2618814"
+ sodipodi:ry="6.3632426"
+ d="M 14.235644 7.7221532 A 6.2618814 6.3632426 0 1 1 1.7118812,7.7221532 A 6.2618814 6.3632426 0 1 1 14.235644 7.7221532 z"
+ transform="matrix(1.0380267,0,0,1.0214918,-0.2769782,0.1118841)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.14770162;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path5897"
+ sodipodi:cx="7.9737625"
+ sodipodi:cy="7.7221532"
+ sodipodi:rx="6.2618814"
+ sodipodi:ry="6.3632426"
+ d="M 14.235644 7.7221532 A 6.2618814 6.3632426 0 1 1 1.7118812,7.7221532 A 6.2618814 6.3632426 0 1 1 14.235644 7.7221532 z"
+ transform="matrix(0.8783303,0,0,0.8643392,0.996403,1.3254404)" />
+ <rect
+ style="opacity:1;fill:#eeeeec;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5886"
+ width="9.000001"
+ height="9"
+ x="5.5"
+ y="5.5"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5969"
+ width="7"
+ height="7"
+ x="6.5"
+ y="6.5"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#8d7300;fill-opacity:1;stroke:none;stroke-width:1.46393549;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path5888"
+ sodipodi:cx="10.676733"
+ sodipodi:cy="7.8460393"
+ sodipodi:rx="1.4415842"
+ sodipodi:ry="1.4866337"
+ d="M 12.118317 7.8460393 A 1.4415842 1.4866337 0 1 1 9.2351488,7.8460393 A 1.4415842 1.4866337 0 1 1 12.118317 7.8460393 z"
+ transform="matrix(0.6936814,0,0,0.6726606,2.5937487,2.7222784)" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#888a85;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 7.4772272,10.5 L 11.522773,10.5"
+ id="path5883" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 7.4872926,12.5 L 11.524094,12.5"
+ id="path5885" />
+ </g>
+</svg>
=== added file 'data/icons/scalable/status/user-invisible.svg'
--- data/icons/scalable/status/user-invisible.svg 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/user-invisible.svg 2010-03-16 11:29:18 +0000
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg4908"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/andreas/project/gossip/16x16"
+ sodipodi:docname="user-invisible.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/Users/kwwii/Desktop/user-invisible.png"
+ inkscape:export-xdpi="270"
+ inkscape:export-ydpi="270"
+ sodipodi:modified="true">
+ <defs
+ id="defs4910" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#efebe7"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="49.332695"
+ inkscape:cx="8.0156251"
+ inkscape:cy="8.0034278"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1343"
+ inkscape:window-height="894"
+ inkscape:window-x="18"
+ inkscape:window-y="36"
+ gridtolerance="10000">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2386"
+ visible="true"
+ enabled="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4913">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 8,2 L 2,7 L 4,14 L 12,14 L 14,7 L 8,2 z M 8.03125,3.28125 L 12.875,7.34375 L 11.28125,13 L 4.75,13 L 3.15625,7.34375 L 8.03125,3.28125 z"
+ id="path3169" />
+ <path
+ style="fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;stroke-miterlimit:4;stroke-dasharray:1, 24;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 7.90625 1 C 7.7115832 1.0193883 7.5268771 1.0954437 7.375 1.21875 L 1.375 6.21875 C 1.0663414 6.4776493 0.94315913 6.8964687 1.0625 7.28125 L 3.0625 14.28125 C 3.1850026 14.699518 3.5642702 14.99029 4 15 L 12 15 C 12.447322 15.004039 12.842922 14.710529 12.96875 14.28125 L 14.96875 7.28125 C 15.088091 6.8964689 14.964909 6.4776491 14.65625 6.21875 L 8.65625 1.21875 C 8.4462475 1.047164 8.1755683 0.96821579 7.90625 1 z M 8 2 L 14 7 L 12 14 L 4 14 L 2 7 L 8 2 z "
+ id="path2388" />
+ <path
+ style="opacity:0.38251367;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 8,2 L 14,7 L 12,14 L 4,14 L 2,7 L 8,2 z"
+ id="path3182" />
+ </g>
+</svg>
=== added file 'data/icons/scalable/status/user-offline.svg'
--- data/icons/scalable/status/user-offline.svg 1970-01-01 00:00:00 +0000
+++ data/icons/scalable/status/user-offline.svg 2010-03-16 11:29:18 +0000
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg6941"
+ sodipodi:version="0.32"
+ inkscape:version="0.44+devel"
+ sodipodi:docbase="/home/andreas/project/gossip/16x16"
+ sodipodi:docname="status-offline.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/andreas/project/gossip/16x16/status-offline.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:modified="true">
+ <defs
+ id="defs6943">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7922">
+ <stop
+ style="stop-color:#e8e8e6;stop-opacity:1"
+ offset="0"
+ id="stop7924" />
+ <stop
+ style="stop-color:#babdb6;stop-opacity:1"
+ offset="1"
+ id="stop7926" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7922"
+ id="linearGradient7928"
+ x1="0.67574239"
+ y1="0.81831664"
+ x2="9.8658419"
+ y2="10.594059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.8666667,1.0666667,1.0666666)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.197802"
+ inkscape:cx="15.038145"
+ inkscape:cy="7.8865336"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1674"
+ inkscape:window-height="969"
+ inkscape:window-x="0"
+ inkscape:window-y="26" />
+ <metadata
+ id="metadata6946">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <rect
+ style="opacity:1;fill:url(#linearGradient7928);fill-opacity:1;stroke:#555753;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect6949"
+ width="13"
+ height="13"
+ x="1.5"
+ y="1.4999999"
+ rx="1.4641089"
+ ry="1.4641089" />
+ <rect
+ style="opacity:0.4;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect7920"
+ width="11"
+ height="11"
+ x="2.5"
+ y="2.5"
+ rx="0.45049509"
+ ry="0.45049506" />
+ </g>
+</svg>
=== added file 'data/indicator-me.service.in'
--- data/indicator-me.service.in 1970-01-01 00:00:00 +0000
+++ data/indicator-me.service.in 2010-03-16 11:29:18 +0000
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.ayatana.indicator.me
+Exec=@libexecdir@/indicator-me-service
=== added directory 'po'
=== renamed directory 'po' => 'po.moved'
=== added file 'po/POTFILES.in'
--- po/POTFILES.in 1970-01-01 00:00:00 +0000
+++ po/POTFILES.in 2010-03-16 11:29:18 +0000
@@ -0,0 +1,7 @@
+[encoding: UTF-8]
+src/indicator-me.c
+src/status-provider.c
+src/status-provider-pidgin.c
+src/status-provider-telepathy.c
+src/me-service.c
+src/me-service-dbus.c
=== added directory 'src'
=== renamed directory 'src' => 'src.moved'
=== added file 'src/Makefile.am'
--- src/Makefile.am 1970-01-01 00:00:00 +0000
+++ src/Makefile.am 2010-03-16 11:29:18 +0000
@@ -0,0 +1,116 @@
+
+libexec_PROGRAMS = indicator-me-service
+
+###################
+# Indicator Stuff
+###################
+
+melibdir = $(INDICATORDIR)
+melib_LTLIBRARIES = libme.la
+libme_la_SOURCES = \
+ about-me-menu-item.c \
+ about-me-menu-item.h \
+ indicator-me.c \
+ dbus-shared-names.h \
+ me-service-client.h
+libme_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror
+libme_la_LIBADD = $(APPLET_LIBS)
+libme_la_LDFLAGS = -module -avoid-version
+
+################
+# Status Stuff
+################
+
+indicator_me_service_SOURCES = \
+ entry-menu-item.c \
+ entry-menu-item.h \
+ me-service.c \
+ me-service-dbus.h \
+ me-service-dbus.c \
+ me-service-server.h \
+ me-service-gwibber.c \
+ me-service-gwibber.h \
+ status-provider.h \
+ status-provider.c \
+ status-provider-mc5.h \
+ status-provider-mc5.c \
+ status-provider-mc5-marshal.h \
+ status-provider-mc5-marshal.c \
+ status-provider-pidgin.h \
+ status-provider-pidgin.c \
+ status-provider-pidgin-marshal.h \
+ status-provider-pidgin-marshal.c \
+ status-provider-telepathy.h \
+ status-provider-telepathy.c \
+ status-provider-telepathy-marshal.h \
+ status-provider-telepathy-marshal.c
+indicator_me_service_CFLAGS = $(MESERVICE_CFLAGS) -Wall -Werror
+indicator_me_service_LDADD = $(MESERVICE_LIBS)
+
+me-service-client.h: $(srcdir)/me-service.xml
+ dbus-binding-tool \
+ --prefix=_me_service_client \
+ --mode=glib-client \
+ --output=me-service-client.h \
+ $(srcdir)/me-service.xml
+
+me-service-server.h: $(srcdir)/me-service.xml
+ dbus-binding-tool \
+ --prefix=_me_service_server \
+ --mode=glib-server \
+ --output=me-service-server.h \
+ $(srcdir)/me-service.xml
+
+status-provider-pidgin-marshal.h: $(srcdir)/status-provider-pidgin.list
+ glib-genmarshal --header \
+ --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \
+ > status-provider-pidgin-marshal.h
+
+status-provider-pidgin-marshal.c: $(srcdir)/status-provider-pidgin.list
+ glib-genmarshal --body \
+ --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \
+ > status-provider-pidgin-marshal.c
+
+status-provider-telepathy-marshal.h: $(srcdir)/status-provider-telepathy.list
+ glib-genmarshal --header \
+ --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \
+ > status-provider-telepathy-marshal.h
+
+status-provider-telepathy-marshal.c: $(srcdir)/status-provider-telepathy.list
+ glib-genmarshal --body \
+ --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \
+ > status-provider-telepathy-marshal.c
+
+status-provider-mc5-marshal.h: $(srcdir)/status-provider-mc5.list
+ glib-genmarshal --header \
+ --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \
+ > status-provider-mc5-marshal.h
+
+status-provider-mc5-marshal.c: $(srcdir)/status-provider-mc5.list
+ glib-genmarshal --body \
+ --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \
+ > status-provider-mc5-marshal.c
+
+###############
+# Other Stuff
+###############
+
+BUILT_SOURCES = \
+ me-service-client.h \
+ me-service-server.h \
+ status-provider-mc5-marshal.h \
+ status-provider-mc5-marshal.c \
+ status-provider-pidgin-marshal.h \
+ status-provider-pidgin-marshal.c \
+ status-provider-telepathy-marshal.h \
+ status-provider-telepathy-marshal.c
+
+EXTRA_DIST = \
+ me-service.xml \
+ status-provider-mc5.list \
+ status-provider-pidgin.list \
+ status-provider-telepathy.list
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
=== added file 'src/about-me-menu-item.c'
--- src/about-me-menu-item.c 1970-01-01 00:00:00 +0000
+++ src/about-me-menu-item.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,311 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * David Barth <david.barth@xxxxxxxxxxxxx>
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib/gstdio.h>
+
+#include <gtk/gtk.h>
+#include "about-me-menu-item.h"
+
+static GObject* about_me_menu_item_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params);
+static void about_me_menu_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void about_me_menu_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+struct _AboutMeMenuItemPrivate {
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *hbox;
+ gchar *realname;
+};
+
+enum {
+ PROP_0,
+ PROP_REALNAME
+};
+
+G_DEFINE_TYPE (AboutMeMenuItem, about_me_menu_item, GTK_TYPE_MENU_ITEM)
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ABOUT_ME_TYPE_MENU_ITEM, AboutMeMenuItemPrivate))
+
+static void
+about_me_menu_item_class_init (AboutMeMenuItemClass *item_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (item_class);
+
+ gobject_class->constructor = about_me_menu_item_constructor;
+ gobject_class->set_property = about_me_menu_item_set_property;
+ gobject_class->get_property = about_me_menu_item_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_REALNAME,
+ g_param_spec_string ("realname",
+ "Realname",
+ "The \"Realname\" for the user",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (gobject_class, sizeof (AboutMeMenuItemPrivate));
+}
+
+static void
+about_me_menu_item_init (AboutMeMenuItem *self)
+{
+ AboutMeMenuItemPrivate *priv = GET_PRIVATE (self);
+
+ priv->label = NULL;
+ priv->image = NULL;
+ priv->realname = NULL;
+}
+
+static void
+about_me_menu_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AboutMeMenuItem *menu_item = ABOUT_ME_MENU_ITEM (object);
+ AboutMeMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+ switch (prop_id)
+ {
+ case PROP_REALNAME:
+ g_assert (priv->realname == NULL);
+ priv->realname = g_strdup (g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+about_me_menu_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AboutMeMenuItem *menu_item = ABOUT_ME_MENU_ITEM (object);
+ AboutMeMenuItemPrivate *priv = GET_PRIVATE (menu_item);
+
+ switch (prop_id)
+ {
+ case PROP_REALNAME:
+ g_value_set_string (value, priv->realname);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+#define DEFAULT_PIXELS_PER_EM 10.0f
+
+static gdouble
+get_pixels_per_em (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), DEFAULT_PIXELS_PER_EM);
+
+ /* Note: taken from indicator-session */
+ GtkStyle * style = gtk_widget_get_style(widget);
+
+ PangoLayout * layout = pango_layout_new(gtk_widget_get_pango_context(widget));
+ pango_layout_set_text(layout, "M", -1);
+ pango_layout_set_font_description(layout, style->font_desc);
+
+ gint width;
+ pango_layout_get_pixel_size(layout, &width, NULL);
+
+ gint point = pango_font_description_get_size(style->font_desc);
+ gdouble dpi = gdk_screen_get_resolution(gdk_screen_get_default());
+
+ return ((point * dpi) / 72.0f) / PANGO_SCALE;
+}
+
+
+/* from n-osd */
+static GdkPixbuf*
+load_icon (const gchar* filename,
+ gint icon_size)
+{
+ GdkPixbuf* buffer = NULL;
+ GdkPixbuf* pixbuf = NULL;
+ GtkIconTheme* theme = NULL;
+ GError* error = NULL;
+
+ /* sanity check */
+ g_return_val_if_fail (filename, NULL);
+
+ theme = gtk_icon_theme_get_default ();
+ buffer = gtk_icon_theme_load_icon (theme,
+ filename,
+ icon_size,
+ GTK_ICON_LOOKUP_FORCE_SVG |
+ GTK_ICON_LOOKUP_GENERIC_FALLBACK |
+ GTK_ICON_LOOKUP_FORCE_SIZE,
+ &error);
+ if (error)
+ {
+ g_print ("loading icon '%s' caused error: '%s'",
+ filename,
+ error->message);
+ g_error_free (error);
+ error = NULL;
+ pixbuf = NULL;
+ }
+ else
+ {
+ /* copy and unref buffer so on an icon-theme change old
+ ** icons are not kept in memory due to dangling
+ ** references, this also makes sure we do not need to
+ ** connect to GtkWidget::style-set signal for the
+ ** GdkPixbuf we get from gtk_icon_theme_load_icon() */
+ pixbuf = gdk_pixbuf_copy (buffer);
+ g_object_unref (buffer);
+ }
+
+ return pixbuf;
+}
+
+gboolean
+about_me_menu_item_load_avatar (AboutMeMenuItem *self, const gchar *file)
+{
+ g_return_val_if_fail (ABOUT_IS_ME_MENU_ITEM (self), FALSE);
+
+ AboutMeMenuItemPrivate *priv = GET_PRIVATE (self);
+
+ g_debug ("loading avatar from file %s", file);
+
+ struct stat buf;
+ if (! (g_stat (file, &buf) == 0 && buf.st_size > 0)) {
+ g_warning ("%s: not found or empty", file);
+ return FALSE;
+ }
+
+ if (buf.st_size > 1024*1024) {
+ g_warning ("avatar file too large (%lld)", (long long)buf.st_size);
+ return FALSE;
+ }
+
+ GError *error = NULL;
+ int size = get_pixels_per_em (priv->image) * 3;
+
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale (file, -1, size, TRUE,
+ &error);
+ if (pixbuf == NULL) {
+ if (error != NULL) {
+ g_warning ("Couldn't read file %s: %s", file, error->message);
+ g_error_free (error);
+ }
+ return FALSE;
+ }
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
+
+ g_object_unref (pixbuf);
+
+ return TRUE;
+}
+
+static void
+image_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ gpointer user_data)
+{
+ gint max = MAX (allocation->width, allocation->height);
+
+ gtk_widget_set_size_request (widget, max, max);
+}
+
+static GObject*
+about_me_menu_item_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GtkWidget *hbox;
+ GtkWidget *align;
+ AboutMeMenuItemPrivate *priv;
+ object = G_OBJECT_CLASS (about_me_menu_item_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_params);
+
+ priv = GET_PRIVATE (object);
+
+ GtkWidget *frame = gtk_frame_new (NULL);
+ gdouble pixels_per_em = get_pixels_per_em (frame);
+ GdkPixbuf *pixbuf = load_icon ("stock_person", pixels_per_em * 3);
+ priv->image = gtk_image_new_from_pixbuf (pixbuf);
+ g_signal_connect (frame, "size-allocate", G_CALLBACK (image_size_allocate), NULL);
+ gtk_misc_set_padding (GTK_MISC (priv->image), 2, 2);
+ gtk_container_add (GTK_CONTAINER (frame), priv->image);
+
+ align = gtk_alignment_new (0, 0.3, 0, 0);
+ priv->label = gtk_label_new (priv->realname);
+ gtk_misc_set_padding (GTK_MISC (priv->label), 2, 2);
+ gtk_container_add (GTK_CONTAINER (align), priv->label);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, DEFAULT_PIXELS_PER_EM);
+
+ gtk_container_add (GTK_CONTAINER (object), hbox);
+ gtk_widget_show_all (GTK_WIDGET(object));
+
+ priv->hbox = hbox;
+
+ return object;
+}
+
+/**
+ * about_me_menu_item_new:
+ * @realname: the name to display in the new menu item.
+ * @returns: a new #AboutMeMenuItem.
+ *
+ * Creates a new #AboutMeMenuItem with a name.
+ **/
+GtkWidget*
+about_me_menu_item_new (const gchar *realname)
+{
+ return g_object_new (ABOUT_ME_TYPE_MENU_ITEM,
+ "realname", realname,
+ NULL);
+}
+
+#define __ABOUT_ME_MENU_ITEM_C__
=== added file 'src/about-me-menu-item.h'
--- src/about-me-menu-item.h 1970-01-01 00:00:00 +0000
+++ src/about-me-menu-item.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,66 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright 2010 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of either or both of the following licenses:
+ *
+ * 1) the GNU Lesser General Public License version 3, as published by the
+ * Free Software Foundation; and/or
+ * 2) the GNU Lesser General Public License version 2.1, as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 and version 2.1 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authors:
+ * David Barth <david.barth@xxxxxxxxxxxxx>
+ * Cody Russell <crussell@xxxxxxxxxxxxx>
+ */
+
+#ifndef __ABOUT_ME_MENU_ITEM_H__
+#define __ABOUT_ME_MENU_ITEM_H__
+
+#include <gtk/gtkmenuitem.h>
+
+G_BEGIN_DECLS
+
+#define ABOUT_ME_TYPE_MENU_ITEM (about_me_menu_item_get_type ())
+#define ABOUT_ME_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ABOUT_ME_TYPE_MENU_ITEM, AboutMeMenuItem))
+#define ABOUT_ME_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), ABOUT_ME_TYPE_MENU_ITEM, AboutMeMenuItemClass))
+#define ABOUT_IS_ME_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ABOUT_ME_TYPE_MENU_ITEM))
+#define ABOUT_IS_ME_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), ABOUT_ME_TYPE_MENU_ITEM))
+#define ABOUT_ME_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ABOUT_ME_TYPE_MENU_ITEM, AboutMeMenuItemClass))
+
+
+typedef struct _AboutMeMenuItem AboutMeMenuItem;
+typedef struct _AboutMeMenuItemClass AboutMeMenuItemClass;
+typedef struct _AboutMeMenuItemPrivate AboutMeMenuItemPrivate;
+
+struct _AboutMeMenuItem
+{
+ GtkMenuItem parent_instance;
+
+ AboutMeMenuItemPrivate *priv;
+};
+
+struct _AboutMeMenuItemClass
+{
+ GtkMenuItemClass parent_class;
+};
+
+
+GType about_me_menu_item_get_type (void) G_GNUC_CONST;
+GtkWidget *about_me_menu_item_new (const gchar *name);
+gboolean about_me_menu_item_load_avatar (AboutMeMenuItem *self, const gchar *file);
+
+G_END_DECLS
+
+#endif /* __ABOUT_ME_MENU_ITEM_H__ */
=== added file 'src/dbus-shared-names.h'
--- src/dbus-shared-names.h 1970-01-01 00:00:00 +0000
+++ src/dbus-shared-names.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,40 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __DBUS_SHARED_NAMES_H__
+#define __DBUS_SHARED_NAMES_H__ 1
+
+#define INDICATOR_ME_DBUS_NAME "org.ayatana.indicator.me"
+#define INDICATOR_ME_DBUS_VERSION 1
+#define INDICATOR_ME_DBUS_OBJECT "/org/ayatana/indicator/me/menu"
+#define INDICATOR_ME_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/me/service"
+#define INDICATOR_ME_SERVICE_DBUS_INTERFACE "org.ayatana.indicator.me.service"
+
+#define DBUSMENU_ENTRY_MENUITEM_TYPE "x-canonical-entry-item"
+#define DBUSMENU_ENTRY_MENUITEM_PROP_TEXT "text"
+
+#define DBUSMENU_ABOUT_ME_MENUITEM_TYPE "x-canonical-about-me-item"
+#define DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME "name"
+#define DBUSMENU_ABOUT_ME_MENUITEM_PROP_ICON "icon"
+
+#endif /* __DBUS_SHARED_NAMES_H__ */
=== added file 'src/entry-menu-item.c'
--- src/entry-menu-item.c 1970-01-01 00:00:00 +0000
+++ src/entry-menu-item.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,136 @@
+/*
+An indicator to show information that is in messaging applications
+that the user is using.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ David Barth <david.barth@xxxxxxxxxxxxx>
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gdk/gdk.h>
+#include <glib/gi18n.h>
+#include "entry-menu-item.h"
+#include "dbus-shared-names.h"
+
+#include "me-service-gwibber.h"
+
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+enum {
+ LAST_SIGNAL
+};
+
+/* static guint signals[LAST_SIGNAL] = { }; */
+
+typedef struct _EntryMenuItemPrivate EntryMenuItemPrivate;
+struct _EntryMenuItemPrivate
+{
+ void * placeholder;
+};
+
+#define ENTRY_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ENTRY_MENU_ITEM_TYPE, EntryMenuItemPrivate))
+
+/* Prototypes */
+static void entry_menu_item_class_init (EntryMenuItemClass *klass);
+static void entry_menu_item_init (EntryMenuItem *self);
+static void entry_menu_item_dispose (GObject *object);
+static void entry_menu_item_finalize (GObject *object);
+static void handle_event (DbusmenuMenuitem *mi, const gchar *name,
+ const GValue *value, guint timestamp);
+
+G_DEFINE_TYPE (EntryMenuItem, entry_menu_item, DBUSMENU_TYPE_MENUITEM);
+
+static void
+entry_menu_item_class_init (EntryMenuItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (EntryMenuItemPrivate));
+
+ object_class->dispose = entry_menu_item_dispose;
+ object_class->finalize = entry_menu_item_finalize;
+
+ DbusmenuMenuitemClass *mclass = DBUSMENU_MENUITEM_CLASS(klass);
+ mclass->handle_event = handle_event;
+
+ return;
+}
+
+static void
+entry_menu_item_init (EntryMenuItem *self)
+{
+ g_debug("Building new Entry Menu Item");
+ /* EntryMenuItemPrivate * priv = ENTRY_MENU_ITEM_GET_PRIVATE(self); */
+
+ return;
+}
+
+static void
+entry_menu_item_dispose (GObject *object)
+{
+ /* EntryMenuItem * self = ENTRY_MENU_ITEM(object);
+ EntryMenuItemPrivate * priv = ENTRY_MENU_ITEM_GET_PRIVATE(self); */
+
+ G_OBJECT_CLASS (entry_menu_item_parent_class)->dispose (object);
+}
+
+static void
+entry_menu_item_finalize (GObject *object)
+{
+ /*
+ EntryMenuItem * self = ENTRY_MENU_ITEM(object);
+ EntryMenuItemPrivate * priv = ENTRY_MENU_ITEM_GET_PRIVATE(self);
+ */
+
+ G_OBJECT_CLASS (entry_menu_item_parent_class)->finalize (object);
+
+ return;
+}
+
+EntryMenuItem *
+entry_menu_item_new ()
+{
+ EntryMenuItem * self = g_object_new(ENTRY_MENU_ITEM_TYPE, NULL);
+ /* EntryMenuItemPrivate * priv = ENTRY_MENU_ITEM_GET_PRIVATE(self); */
+
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_ENTRY_MENUITEM_TYPE);
+
+ return self;
+}
+
+/* When the entry menu item is clicked on it emits a dbus signal
+ for the corresponding bottom-half service to act upon */
+static void
+handle_event (DbusmenuMenuitem *mi, const gchar *name,
+ const GValue *value, guint timestamp)
+{
+ /* EntryMenuItemPrivate * priv = ENTRY_MENU_ITEM_GET_PRIVATE(self); */
+
+ g_debug ("handle_event");
+ if (g_strcmp0 (name, "send") == 0) {
+ gwibber_send (g_value_get_string (value));
+ dbusmenu_menuitem_property_set (mi, ENTRY_MENUITEM_PROP_TEXT, "");
+ }
+
+ return;
+}
=== added file 'src/entry-menu-item.h'
--- src/entry-menu-item.h 1970-01-01 00:00:00 +0000
+++ src/entry-menu-item.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,62 @@
+/*
+An indicator to show information that is in messaging applications
+that the user is using.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ David Barth <david.barth@xxxxxxxxxxxxx>
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __ENTRY_MENU_ITEM_H__
+#define __ENTRY_MENU_ITEM_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+
+G_BEGIN_DECLS
+
+#define ENTRY_MENU_ITEM_TYPE (entry_menu_item_get_type ())
+#define ENTRY_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ENTRY_MENU_ITEM_TYPE, EntryMenuItem))
+#define ENTRY_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ENTRY_MENU_ITEM_TYPE, EntryMenuItemClass))
+#define IS_ENTRY_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ENTRY_MENU_ITEM_TYPE))
+#define IS_ENTRY_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ENTRY_MENU_ITEM_TYPE))
+#define ENTRY_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ENTRY_MENU_ITEM_TYPE, EntryMenuItemClass))
+
+#define ENTRY_MENU_ITEM_SIGNAL_ACTIVATE "activate"
+#define ENTRY_MENUITEM_PROP_TEXT "text"
+
+typedef struct _EntryMenuItem EntryMenuItem;
+typedef struct _EntryMenuItemClass EntryMenuItemClass;
+
+struct _EntryMenuItemClass {
+ DbusmenuMenuitemClass parent_class;
+};
+
+struct _EntryMenuItem {
+ DbusmenuMenuitem parent;
+};
+
+GType entry_menu_item_get_type (void);
+EntryMenuItem * entry_menu_item_new ();
+const gchar * entry_menu_item_get_text (EntryMenuItem * appitem);
+
+G_END_DECLS
+
+#endif /* __ENTRY_MENU_ITEM_H__ */
+
=== added file 'src/indicator-me.c'
--- src/indicator-me.c 1970-01-01 00:00:00 +0000
+++ src/indicator-me.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,358 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ A menu that should be close to the user, it's the user's status,
+ their friends. All about them. It's a user-focused-menu.
+
+ Copyright 2009 Canonical Ltd.
+
+ Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+ Cody Russell <cody.russell@xxxxxxxxxxxxx>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 3, as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranties of
+ MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-gtk/menu.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libindicator/indicator.h>
+#include <libindicator/indicator-object.h>
+#include <libindicator/indicator-service-manager.h>
+#include <libindicator/indicator-image-helper.h>
+#include <libido/idoentrymenuitem.h>
+
+#include "about-me-menu-item.h"
+
+#include "dbus-shared-names.h"
+#include "me-service-client.h"
+
+#define INDICATOR_ME_TYPE (indicator_me_get_type ())
+#define INDICATOR_ME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_ME_TYPE, IndicatorMe))
+#define INDICATOR_ME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_ME_TYPE, IndicatorMeClass))
+#define IS_INDICATOR_ME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_ME_TYPE))
+#define IS_INDICATOR_ME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_ME_TYPE))
+#define INDICATOR_ME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_ME_TYPE, IndicatorMeClass))
+
+#define DEFAULT_ICON "user-offline"
+
+typedef struct _IndicatorMe IndicatorMe;
+typedef struct _IndicatorMeClass IndicatorMeClass;
+
+struct _IndicatorMeClass {
+ IndicatorObjectClass parent_class;
+};
+
+struct _IndicatorMe {
+ IndicatorObject parent;
+ IndicatorServiceManager * service;
+};
+
+GType indicator_me_get_type (void);
+
+/* Indicator stuff */
+INDICATOR_SET_VERSION
+INDICATOR_SET_TYPE(INDICATOR_ME_TYPE)
+
+/* Globals */
+static GtkImage * status_image = NULL;
+static GtkLabel *label = NULL;
+static DBusGProxy * status_proxy = NULL;
+
+/* Prototypes */
+static GtkLabel * get_label (IndicatorObject * io);
+static GtkImage * get_icon (IndicatorObject * io);
+static GtkMenu * get_menu (IndicatorObject * io);
+
+static void indicator_me_class_init (IndicatorMeClass *klass);
+static void indicator_me_init (IndicatorMe *self);
+static void indicator_me_dispose (GObject *object);
+static void indicator_me_finalize (GObject *object);
+static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata);
+static void status_icon_cb (DBusGProxy * proxy, char * icons, GError *error, gpointer userdata);
+
+G_DEFINE_TYPE (IndicatorMe, indicator_me, INDICATOR_OBJECT_TYPE);
+
+static void
+indicator_me_class_init (IndicatorMeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = indicator_me_dispose;
+ object_class->finalize = indicator_me_finalize;
+
+ IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
+ io_class->get_label = get_label;
+ io_class->get_image = get_icon;
+ io_class->get_menu = get_menu;
+
+ return;
+}
+
+static void
+indicator_me_init (IndicatorMe *self)
+{
+
+ /* Init variables */
+ self->service = NULL;
+
+ /* Do stuff with them */
+ self->service = indicator_service_manager_new_version(INDICATOR_ME_DBUS_NAME, INDICATOR_ME_DBUS_VERSION);
+ g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self);
+
+ return;
+}
+
+static void
+indicator_me_dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (indicator_me_parent_class)->dispose (object);
+ return;
+}
+
+static void
+indicator_me_finalize (GObject *object)
+{
+
+ G_OBJECT_CLASS (indicator_me_parent_class)->finalize (object);
+ return;
+}
+
+static void
+username_cb (DBusGProxy * proxy, char * username, GError *error, gpointer userdata)
+{
+ if (label == NULL)
+ label = GTK_LABEL(gtk_label_new(NULL));
+
+ if (username != NULL && username[0] != '\0') {
+ g_debug ("Updating username label");
+ gtk_label_set_text (label, username);
+ gtk_widget_show(GTK_WIDGET(label));
+ }
+}
+
+static GtkLabel *
+get_label (IndicatorObject * io)
+{
+ if (label == NULL) {
+ /* Create the label if it doesn't exist already */
+ username_cb (NULL, NULL, NULL, NULL);
+ }
+
+ return label;
+}
+
+static GtkImage *
+get_icon (IndicatorObject * io)
+{
+ if (status_image == NULL) {
+ /* Will create the status icon if it doesn't exist already */
+ status_icon_cb(NULL, DEFAULT_ICON, NULL, NULL);
+ }
+ return status_image;
+}
+
+static void
+status_icon_cb (DBusGProxy * proxy, char * icons, GError *error, gpointer userdata)
+{
+ g_return_if_fail(icons != NULL);
+ g_return_if_fail(icons[0] != '\0');
+
+ if (status_image == NULL) {
+ status_image = indicator_image_helper (DEFAULT_ICON "-panel");
+ gtk_widget_show(GTK_WIDGET(status_image));
+ }
+
+ gchar *panel_icon = g_strconcat (icons, "-panel", NULL);
+ indicator_image_helper_update (status_image, panel_icon);
+ g_free (panel_icon);
+
+ return;
+}
+
+static void
+status_icon_changed (DBusGProxy * proxy, gchar * icon, gpointer userdata)
+{
+ g_debug("Changing status icon: '%s'", icon);
+
+ return status_icon_cb(proxy, icon, NULL, NULL);
+}
+
+static void
+connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata)
+{
+ if (connected) {
+ if (status_proxy == NULL) {
+ GError * error = NULL;
+
+ DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+
+ status_proxy = dbus_g_proxy_new_for_name_owner(sbus,
+ INDICATOR_ME_DBUS_NAME,
+ INDICATOR_ME_SERVICE_DBUS_OBJECT,
+ INDICATOR_ME_SERVICE_DBUS_INTERFACE,
+ &error);
+
+ if (error != NULL) {
+ g_warning("Unable to get status proxy: %s", error->message);
+ g_error_free(error);
+ }
+
+ dbus_g_proxy_add_signal(status_proxy, "StatusIconsChanged", G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(status_proxy, "StatusIconsChanged", G_CALLBACK(status_icon_changed), NULL, NULL);
+ }
+
+ org_ayatana_indicator_me_service_status_icons_async(status_proxy, status_icon_cb, NULL);
+
+ /* query the service for the username to display */
+ org_ayatana_indicator_me_service_pretty_user_name_async(status_proxy, username_cb, NULL);
+
+ } else {
+ /* If we're disconnecting, go back to offline */
+ status_icon_cb(NULL, DEFAULT_ICON, NULL, NULL);
+ }
+
+ return;
+}
+
+static void
+entry_prop_change_cb (DbusmenuMenuitem *mi, gchar *prop, GValue *value, GtkEntry *entry)
+{
+ if (g_strcmp0 (prop, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) == 0) {
+ gtk_entry_set_text (entry, g_value_get_string (value));
+ }
+}
+
+static void
+entry_activate_cb (GtkEntry *entry, DbusmenuMenuitem *gmi)
+{
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, gtk_entry_get_text (entry));
+
+ g_debug ("user typed: %s", g_value_get_string (&value));
+
+ dbusmenu_menuitem_handle_event (gmi, "send", &value, gtk_get_current_event_time());
+}
+
+static gboolean
+menu_visibility_changed (GtkWidget *widget,
+ IdoEntryMenuItem *menuitem)
+{
+ gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), GTK_WIDGET (menuitem));
+
+ return FALSE;
+}
+
+static void
+entry_parent_changed (GtkWidget *widget,
+ gpointer user_data)
+{
+ GtkWidget *parent = gtk_widget_get_parent (widget);
+
+ if (parent && GTK_IS_MENU_SHELL (parent))
+ {
+ g_signal_connect (parent,
+ "map", G_CALLBACK (menu_visibility_changed),
+ widget);
+ }
+}
+
+static gboolean
+new_entry_item (DbusmenuMenuitem * newitem,
+ DbusmenuMenuitem * parent,
+ DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+ /* Note: not checking parent, it's reasonable for it to be NULL */
+
+ IdoEntryMenuItem *ido = IDO_ENTRY_MENU_ITEM (ido_entry_menu_item_new ());
+ GtkEntry *entry = GTK_ENTRY(ido_entry_menu_item_get_entry (ido));
+ if (dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) != NULL)
+ gtk_entry_set_text(entry, dbusmenu_menuitem_property_get(newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT));
+ gtk_entry_set_width_chars (entry, 23); /* set some nice aspect ratio for the menu */
+ gtk_entry_set_max_length (entry, 140); /* enforce current gwibber limit */
+
+ g_signal_connect (ido,
+ "notify::parent", G_CALLBACK (entry_parent_changed),
+ NULL);
+
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
+ /* disconnect the activate signal that newitem_base connected with the wrong
+ widget, ie menuitem, and re-connect it with the /entry/ instead */
+ gulong signal_id = g_signal_handler_find (GTK_MENU_ITEM (ido), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, parent);
+ g_signal_handler_disconnect(GTK_MENU_ITEM (ido), signal_id);
+
+ g_signal_connect (DBUSMENU_MENUITEM (newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK (entry_prop_change_cb), entry);
+ g_signal_connect (GTK_ENTRY (entry), "activate", G_CALLBACK (entry_activate_cb), newitem);
+
+ return TRUE;
+}
+
+/* Whenever we have a property change on a DbusmenuMenuitem
+ we need to be responsive to that. */
+static void
+about_me_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, AboutMeMenuItem *item)
+{
+ g_return_if_fail (ABOUT_IS_ME_MENU_ITEM (item));
+
+ if (!g_strcmp0(prop, DBUSMENU_ABOUT_ME_MENUITEM_PROP_ICON)) {
+ /* reload the avatar icon */
+ about_me_menu_item_load_avatar (item, g_value_get_string(value));
+ } else {
+ g_warning("Indicator Item property '%s' unknown", prop);
+ }
+
+ return;
+}
+
+static gboolean
+new_about_me_item (DbusmenuMenuitem * newitem,
+ DbusmenuMenuitem * parent,
+ DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+ /* Note: not checking parent, it's reasonable for it to be NULL */
+
+ const gchar *name = dbusmenu_menuitem_property_get (newitem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME);
+ AboutMeMenuItem *about = ABOUT_ME_MENU_ITEM (about_me_menu_item_new (name));
+ if (about != NULL) {
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(about), parent);
+ const gchar *avatar = dbusmenu_menuitem_property_get (newitem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_ICON);
+ about_me_menu_item_load_avatar (about, avatar);
+ g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(about_me_prop_change_cb), about);
+ }
+
+ return TRUE;
+}
+
+/* Builds the dbusmenu for the service. */
+static GtkMenu *
+get_menu (IndicatorObject * io)
+{
+ DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_ME_DBUS_NAME, INDICATOR_ME_DBUS_OBJECT);
+ DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu);
+
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_ENTRY_MENUITEM_TYPE, new_entry_item);
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_ABOUT_ME_MENUITEM_TYPE, new_about_me_item);
+
+ return GTK_MENU (menu);
+}
=== added file 'src/me-service-dbus.c'
--- src/me-service-dbus.c 1970-01-01 00:00:00 +0000
+++ src/me-service-dbus.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,223 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dbus/dbus-glib.h>
+
+#include "dbus-shared-names.h"
+#include "me-service-dbus.h"
+
+static void status_service_dbus_class_init (StatusServiceDbusClass *klass);
+static void status_service_dbus_init (StatusServiceDbus *self);
+static void status_service_dbus_dispose (GObject *object);
+static void status_service_dbus_finalize (GObject *object);
+static gboolean _me_service_server_watch (StatusServiceDbus * service, GError ** error);
+static gboolean _me_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error);
+static gboolean _me_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error);
+
+#include "me-service-server.h"
+
+/* Private */
+typedef struct _StatusServiceDbusPrivate StatusServiceDbusPrivate;
+struct _StatusServiceDbusPrivate
+{
+ gchar * name;
+ gchar * icon;
+};
+
+#define STATUS_SERVICE_DBUS_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusPrivate))
+
+/* Signals */
+enum {
+ USER_CHANGED,
+ STATUS_ICONS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/* GObject Boilerplate */
+G_DEFINE_TYPE (StatusServiceDbus, status_service_dbus, G_TYPE_OBJECT);
+
+static void
+status_service_dbus_class_init (StatusServiceDbusClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof(StatusServiceDbusPrivate));
+
+ object_class->dispose = status_service_dbus_dispose;
+ object_class->finalize = status_service_dbus_finalize;
+
+ /**
+ StatusServiceDbus::user-changed:
+ @arg0: The #StatusServiceDbus object.
+ @arg1: The place to put the new user name
+
+ Signals that the user name has changed and gives the
+ new user name.
+ */
+ signals[USER_CHANGED] = g_signal_new("user-changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(StatusServiceDbusClass, user_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ /**
+ StatusServiceDbus::status-icons-changed:
+ @arg0: The #StatusServiceDbus object.
+ @arg1: The list of icon names representing the statuses in
+ the order they should be displayed. Left to right.
+
+ Signals that the user status set has changed and that
+ new icons may need to be loaded. The list of icons will
+ always be complete.
+ */
+ signals[STATUS_ICONS_CHANGED] = g_signal_new("status-icons-changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(StatusServiceDbusClass, status_icons_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ dbus_g_object_type_install_info(STATUS_SERVICE_DBUS_TYPE, &dbus_glib__me_service_server_object_info);
+
+ return;
+}
+
+static void
+status_service_dbus_init (StatusServiceDbus *self)
+{
+
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ dbus_g_connection_register_g_object(connection,
+ INDICATOR_ME_SERVICE_DBUS_OBJECT,
+ G_OBJECT(self));
+
+ StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
+ priv->name = NULL;
+ priv->icon = NULL;
+
+ return;
+}
+
+static void
+status_service_dbus_dispose (GObject *object)
+{
+
+ G_OBJECT_CLASS (status_service_dbus_parent_class)->dispose (object);
+ return;
+}
+
+static void
+status_service_dbus_finalize (GObject *object)
+{
+
+ G_OBJECT_CLASS (status_service_dbus_parent_class)->finalize (object);
+ return;
+}
+
+static gboolean
+_me_service_server_watch (StatusServiceDbus * service, GError ** error)
+{
+
+ return TRUE;
+}
+
+static gboolean
+_me_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error)
+{
+ if (!IS_STATUS_SERVICE_DBUS(service)) {
+ g_warning("NO BAD EVIL!");
+ return FALSE;
+ }
+
+ StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
+ if (priv->icon == NULL) {
+ *icon = g_strdup("");
+ } else {
+ *icon = g_strdup(priv->icon);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+_me_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error)
+{
+ if (!IS_STATUS_SERVICE_DBUS(service)) {
+ g_warning("NO BAD EVIL!");
+ return FALSE;
+ }
+
+ StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
+ if (priv->name == NULL) {
+ *username = g_strdup("");
+ } else {
+ *username = g_strdup(priv->name);
+ }
+
+ return TRUE;
+}
+
+void
+status_service_dbus_set_status (StatusServiceDbus * self, const gchar * icon)
+{
+ g_return_if_fail(IS_STATUS_SERVICE_DBUS(self));
+
+ g_debug("Setting icon to: %s", icon);
+
+ StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
+
+ if (priv->icon != NULL) {
+ g_free(priv->icon);
+ }
+ priv->icon = g_strdup(icon);
+
+ g_signal_emit(G_OBJECT(self), signals[STATUS_ICONS_CHANGED], 0, priv->icon, TRUE);
+ return;
+}
+
+void
+status_service_dbus_set_username (StatusServiceDbus * self, const gchar * username)
+{
+ g_return_if_fail(IS_STATUS_SERVICE_DBUS(self));
+
+ g_debug("Setting username to: %s", username);
+
+ StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
+
+ if (priv->name != NULL) {
+ g_free(priv->name);
+ }
+ priv->name = g_strdup(username);
+
+ g_signal_emit(G_OBJECT(self), signals[USER_CHANGED], 0, priv->name, TRUE);
+ return;
+}
=== added file 'src/me-service-dbus.h'
--- src/me-service-dbus.h 1970-01-01 00:00:00 +0000
+++ src/me-service-dbus.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,60 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STATUS_SERVICE_DBUS_H__
+#define __STATUS_SERVICE_DBUS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define STATUS_SERVICE_DBUS_TYPE (status_service_dbus_get_type ())
+#define STATUS_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbus))
+#define STATUS_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusClass))
+#define IS_STATUS_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_SERVICE_DBUS_TYPE))
+#define IS_STATUS_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_SERVICE_DBUS_TYPE))
+#define STATUS_SERVICE_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusClass))
+
+typedef struct _StatusServiceDbus StatusServiceDbus;
+typedef struct _StatusServiceDbusClass StatusServiceDbusClass;
+
+struct _StatusServiceDbusClass {
+ GObjectClass parent_class;
+
+ /* Signals */
+ gboolean (*user_changed) (StatusServiceDbus * self, gchar ** name, gpointer user_data);
+ gboolean (*status_icons_changed) (StatusServiceDbus * self, GArray ** icons, gpointer user_data);
+
+};
+
+struct _StatusServiceDbus {
+ GObject parent;
+};
+
+GType status_service_dbus_get_type (void);
+void status_service_dbus_set_status (StatusServiceDbus * self, const gchar * icon);
+void status_service_dbus_set_username (StatusServiceDbus * self, const gchar * username);
+
+G_END_DECLS
+
+#endif
=== added file 'src/me-service-gwibber.c'
--- src/me-service-gwibber.c 1970-01-01 00:00:00 +0000
+++ src/me-service-gwibber.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,84 @@
+/*
+
+Logic to send messages via gwibber
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ David Barth <david.barth@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#define GWIBBER_ADDRESS "com.Gwibber.Service"
+#define GWIBBER_OBJECT "/com/gwibber/Service"
+#define GWIBBER_INTERFACE "com.Gwibber.Service"
+
+static DBusGProxy * gwibber_proxy = NULL;
+
+/*
+ static */ void
+gwibber_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
+{
+ g_debug ("gwibber_send_response");
+
+ return;
+}
+
+static void
+setup_gwibber_proxy (void) {
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_return_if_fail(bus != NULL);
+
+ if (gwibber_proxy == NULL) {
+ gwibber_proxy = dbus_g_proxy_new_for_name(bus,
+ GWIBBER_ADDRESS,
+ GWIBBER_OBJECT,
+ GWIBBER_INTERFACE);
+ }
+ g_return_if_fail (gwibber_proxy != NULL);
+
+ return;
+}
+
+void
+gwibber_send (const gchar *msg)
+{
+ setup_gwibber_proxy ();
+
+ if (gwibber_proxy == NULL) {
+ g_warning ("Can not get a gwibber proxy object");
+ }
+
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, msg);
+
+ g_debug ("gwibber_send: %s\n", msg);
+
+ dbus_g_proxy_begin_call(gwibber_proxy,
+ "SendMessage",
+ gwibber_response,
+ NULL,
+ NULL,
+ G_TYPE_VALUE,
+ &value,
+ G_TYPE_INVALID);
+
+ g_value_unset(&value);
+
+ return;
+}
=== added file 'src/me-service-gwibber.h'
--- src/me-service-gwibber.h 1970-01-01 00:00:00 +0000
+++ src/me-service-gwibber.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,35 @@
+/*
+
+Logic to send messages via gwibber
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ David Barth <david.barth@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __ME_SERVICE_GWIBBER_H__
+#define __ME_SERVICE_GWIBBER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void gwibber_send (const gchar *msg);
+
+G_END_DECLS
+
+#endif /* __ME_SERVICE_GWIBBER_H__ */
+
=== added file 'src/me-service.c'
--- src/me-service.c 1970-01-01 00:00:00 +0000
+++ src/me-service.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,447 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ A small wrapper utility to load indicators and put them as menu items
+ into the gnome-panel using it's applet interface.
+
+ Copyright 2009 Canonical Ltd.
+
+ Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 3, as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranties of
+ MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include <glib/gi18n.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <gio/gio.h>
+
+#include <gconf/gconf-client.h>
+
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include <libindicator/indicator-service.h>
+
+#include "dbus-shared-names.h"
+
+#include "me-service-dbus.h"
+
+#include "status-provider.h"
+#include "status-provider-mc5.h"
+#include "status-provider-pidgin.h"
+#include "status-provider-telepathy.h"
+
+#include "entry-menu-item.h"
+
+typedef StatusProvider * (*newfunc) (void);
+#define STATUS_PROVIDER_CNT 3
+static newfunc status_provider_newfuncs[STATUS_PROVIDER_CNT] = {
+ status_provider_mc5_new,
+ status_provider_pidgin_new,
+ status_provider_telepathy_new
+};
+static StatusProvider * status_providers[STATUS_PROVIDER_CNT] = { 0 };
+
+static const gchar * status_strings [STATUS_PROVIDER_STATUS_LAST] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ N_("Available"),
+ /* STATUS_PROVIDER_STATUS_AWAY, */ N_("Away"),
+ /* STATUS_PROVIDER_STATUS_DND */ N_("Busy"),
+ /* STATUS_PROVIDER_STATUS_INVISIBLE */ N_("Invisible"),
+ /* STATUS_PROVIDER_STATUS_OFFLINE, */ N_("Offline"),
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ N_("Offline")
+};
+
+static const gchar * status_icons[STATUS_PROVIDER_STATUS_LAST] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ "user-available",
+ /* STATUS_PROVIDER_STATUS_AWAY, */ "user-away",
+ /* STATUS_PROVIDER_STATUS_DND, */ "user-busy",
+ /* STATUS_PROVIDER_STATUS_INVISIBLE, */ "user-invisible",
+ /* STATUS_PROVIDER_STATUS_OFFLINE */ "user-offline",
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED */"user-offline"
+};
+
+
+static DbusmenuMenuitem * root_menuitem = NULL;
+static DbusmenuMenuitem * status_menuitems[STATUS_PROVIDER_STATUS_LAST] = {0};
+static GMainLoop * mainloop = NULL;
+static StatusServiceDbus * dbus_interface = NULL;
+static StatusProviderStatus global_status = STATUS_PROVIDER_STATUS_DISCONNECTED;
+static GFileMonitor *avatar_monitor = NULL;
+
+static void
+status_update (void) {
+ StatusProviderStatus oldglobal = global_status;
+ global_status = STATUS_PROVIDER_STATUS_DISCONNECTED;
+ gboolean indeterminate = FALSE;
+
+ /* Ask everyone what they think the status should be, if
+ they're more connected, up the global level */
+ StatusProviderStatus i;
+ for (i = 0; i < STATUS_PROVIDER_CNT; i++) {
+ if (status_providers[i] == NULL) continue;
+ StatusProviderStatus localstatus = status_provider_get_status(status_providers[i]);
+ g_debug ("provider[%d]: %s", i, status_strings[localstatus]);
+
+ if (localstatus >= STATUS_PROVIDER_STATUS_OFFLINE)
+ /* offline and disconnected is similar for some providers
+ so it's not meaningful to determine the 'indeterminate' status
+ */
+ continue;
+
+ if (localstatus != global_status) {
+ if (global_status < STATUS_PROVIDER_STATUS_OFFLINE)
+ /* at least one provider was maintaining a status better than 'offline'
+ and there's now another one with something different */
+ indeterminate = TRUE;
+ global_status = localstatus;
+ }
+ }
+
+ /* Configure the icon on the panel */
+ status_service_dbus_set_status(dbus_interface, indeterminate ? "user-indeterminate" : status_icons[global_status]);
+
+ g_debug("Global status changed to: %s", indeterminate ? "indeterminate" : status_strings[global_status]);
+
+ /* If we're now disconnected, make setting the statuses
+ insensitive. */
+ if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) {
+ StatusProviderStatus i;
+ for (i = STATUS_PROVIDER_STATUS_ONLINE;
+ i < STATUS_PROVIDER_STATUS_LAST; i++) {
+ if (status_menuitems[i] == NULL) continue;
+ dbusmenu_menuitem_property_set_bool(status_menuitems[i],
+ DBUSMENU_MENUITEM_PROP_ENABLED,
+ FALSE);
+ }
+ return;
+ }
+
+ /* Ensure items are sensititive if they were previoulsy disabled */
+ if (oldglobal == STATUS_PROVIDER_STATUS_DISCONNECTED) {
+ StatusProviderStatus i;
+ for (i = STATUS_PROVIDER_STATUS_ONLINE;
+ i < STATUS_PROVIDER_STATUS_LAST; i++) {
+ if (status_menuitems[i] == NULL) continue;
+ dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ }
+ }
+
+ /* add a radio mark to the user status entry */
+ for (i = STATUS_PROVIDER_STATUS_ONLINE;
+ i < STATUS_PROVIDER_STATUS_LAST; i++) {
+ if (status_menuitems[i] == NULL) continue;
+ if (indeterminate
+ || (i != global_status)) {
+ dbusmenu_menuitem_property_set_int (status_menuitems[i],
+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
+ } else {
+ dbusmenu_menuitem_property_set_int (status_menuitems[i],
+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
+ }
+ }
+
+ return;
+}
+
+static void
+status_menu_click (DbusmenuMenuitem * mi, guint timestamp, gpointer data)
+{
+ StatusProviderStatus status = (StatusProviderStatus)GPOINTER_TO_INT(data);
+ g_debug("Setting status: %d", status);
+ int i;
+ for (i = 0; i < STATUS_PROVIDER_CNT; i++) {
+ status_provider_set_status(status_providers[i], status);
+ }
+
+ return;
+}
+
+static void
+spawn_on_activate_cb (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
+{
+ GError * error = NULL;
+
+ if (!g_spawn_command_line_async(user_data, &error)) {
+ g_warning("Unable to start %s: %s", (char *)user_data, error->message);
+ g_error_free(error);
+ }
+}
+
+static gboolean
+program_is_installed (gchar *program)
+{
+ gchar *cmd = g_find_program_in_path(program);
+ if (cmd != NULL) {
+ g_free(cmd);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+build_accounts_menuitems (gpointer data)
+{
+ DbusmenuMenuitem * root = DBUSMENU_MENUITEM(data);
+ g_return_if_fail(root != NULL);
+
+ if (program_is_installed ("empathy-accounts")) {
+ DbusmenuMenuitem *im_accounts_mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(im_accounts_mi, DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Chat Accounts..."));
+ dbusmenu_menuitem_child_append(root, im_accounts_mi);
+ g_signal_connect(G_OBJECT(im_accounts_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(spawn_on_activate_cb), "empathy-accounts");
+ }
+
+ if (program_is_installed ("gwibber-accounts")) {
+ DbusmenuMenuitem *tw_accounts_mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(tw_accounts_mi, DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Broadcast Accounts..."));
+ dbusmenu_menuitem_child_append(root, tw_accounts_mi);
+ g_signal_connect(G_OBJECT(tw_accounts_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(spawn_on_activate_cb), "gwibber-accounts");
+ }
+
+ if (program_is_installed ("ubuntuone-preferences")) {
+ DbusmenuMenuitem *u1_accounts_mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(u1_accounts_mi, DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Ubuntu One..."));
+ dbusmenu_menuitem_child_append(root, u1_accounts_mi);
+ g_signal_connect(G_OBJECT(u1_accounts_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(spawn_on_activate_cb), "ubuntuone-preferences");
+ }
+}
+
+static gboolean
+build_providers (gpointer data)
+{
+ int i;
+ for (i = 0; i < STATUS_PROVIDER_CNT; i++) {
+ status_providers[i] = status_provider_newfuncs[i]();
+
+ if (status_providers[i] != NULL) {
+ g_signal_connect(G_OBJECT(status_providers[i]), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, G_CALLBACK(status_update), NULL);
+ }
+ }
+
+ status_update();
+
+ return FALSE;
+}
+
+#define GCONF_ANONYMOUS "/system/indicator/me/anonymous"
+
+static gboolean
+anonymous_mode (void)
+{
+ GConfClient *context = NULL;
+ GConfValue *option = NULL;
+ gboolean value = FALSE; /* not anonymous, by default */
+
+ context = gconf_client_get_default ();
+ if (! context) {
+ g_warning ("Couldn't get a gconf context");
+ return FALSE;
+ }
+
+ option = gconf_client_get (context, GCONF_ANONYMOUS, NULL);
+ if (option != NULL &&
+ option->type == GCONF_VALUE_BOOL)
+ value = gconf_value_get_bool (option);
+
+ g_object_unref (context);
+
+ return value;
+}
+
+static void
+avatar_changed_cb (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data)
+{
+ g_debug("avatar changed!");
+
+ g_return_if_fail (DBUSMENU_IS_MENUITEM (user_data));
+
+ DbusmenuMenuitem *mi = DBUSMENU_MENUITEM (user_data);
+
+ /* whatever happened, we just update the icon property
+ and let the indicator reload the image */
+ gchar * path = g_file_get_path (file);
+ dbusmenu_menuitem_property_set (mi, DBUSMENU_ABOUT_ME_MENUITEM_PROP_ICON, path);
+}
+
+static void
+build_user_item (DbusmenuMenuitem * root)
+{
+ struct passwd * pwd = NULL;
+
+ if (anonymous_mode ())
+ return;
+
+ pwd = getpwuid(getuid());
+
+ if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0') {
+ status_service_dbus_set_username(dbus_interface, pwd->pw_name);
+ } else {
+ g_warning ("PWD: %s", (pwd == NULL ? "(pwd null)" : (pwd->pw_name == NULL ? "(pw_name null)" : pwd->pw_name)));
+
+ /* that's kind of an anonymous mode too if ever that can happen */
+ return;
+ }
+
+ DbusmenuMenuitem * useritem = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set_bool(useritem, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
+ dbusmenu_menuitem_property_set(useritem, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_ABOUT_ME_MENUITEM_TYPE);
+ dbusmenu_menuitem_child_append(root, useritem);
+
+ /* avatar icon */
+ gchar *filename = g_build_filename (g_get_home_dir (), ".face", NULL);
+ dbusmenu_menuitem_property_set (useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_ICON, filename);
+ GFile *file = g_file_new_for_path (filename);
+ avatar_monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ if (avatar_monitor != NULL)
+ g_signal_connect (G_OBJECT (avatar_monitor), "changed", G_CALLBACK (avatar_changed_cb), useritem);
+
+ g_free (filename);
+
+ gchar *gam = g_find_program_in_path("gnome-about-me");
+ if (gam != NULL) {
+ dbusmenu_menuitem_property_set_bool(useritem, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
+ g_signal_connect(G_OBJECT(useritem),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(spawn_on_activate_cb), "gnome-about-me");
+ g_free(gam);
+ }
+
+ if (pwd != NULL && pwd->pw_gecos != NULL) {
+ gchar * name = g_strdup(pwd->pw_gecos);
+ gchar * walker = name;
+ while (*walker != '\0' && *walker != ',') { walker++; }
+ *walker = '\0';
+
+ if (name[0] != '\0') {
+ dbusmenu_menuitem_property_set(useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME, name);
+ } else {
+ /* fallback on the username, at least we know it's not null from above */
+ dbusmenu_menuitem_property_set(useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME, pwd->pw_name);
+ }
+
+ g_free(name);
+ }
+
+ return;
+}
+
+static gboolean
+build_menu (gpointer data)
+{
+ DbusmenuMenuitem * root = DBUSMENU_MENUITEM(data);
+ g_return_val_if_fail(root != NULL, FALSE);
+
+ build_user_item(root);
+
+ DbusmenuMenuitem *entry = DBUSMENU_MENUITEM (entry_menu_item_new());
+ dbusmenu_menuitem_child_append(root, entry);
+
+ StatusProviderStatus i;
+ for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) {
+ if (i == STATUS_PROVIDER_STATUS_DISCONNECTED) {
+ /* We don't want an item for the disconnected status. Users
+ can't set that value through the menu :) */
+ continue;
+ }
+
+ status_menuitems[i] = dbusmenu_menuitem_new();
+
+ dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[i]));
+ dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ICON_NAME, status_icons[i]);
+ dbusmenu_menuitem_property_set (status_menuitems[i],
+ DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
+ DBUSMENU_MENUITEM_TOGGLE_RADIO);
+ dbusmenu_menuitem_property_set_int (status_menuitems[i],
+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
+ if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) {
+ dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
+ }
+ g_signal_connect(G_OBJECT(status_menuitems[i]), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(status_menu_click), GINT_TO_POINTER(i));
+
+ dbusmenu_menuitem_child_append(root, status_menuitems[i]);
+
+ g_debug("Built %s", status_strings[i]);
+ }
+
+ DbusmenuMenuitem *separator = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE,
+ DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_child_append(root, separator);
+
+ build_accounts_menuitems(root);
+
+ return FALSE;
+}
+
+void
+service_shutdown (IndicatorService * service, gpointer user_data)
+{
+ g_debug("Service shutting down");
+
+ if (avatar_monitor != NULL)
+ g_object_unref (avatar_monitor);
+
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ /* Setting up i18n and gettext. Apparently, we need
+ all of these. */
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ textdomain (GETTEXT_PACKAGE);
+
+ IndicatorService * service = indicator_service_new_version(INDICATOR_ME_DBUS_NAME, INDICATOR_ME_DBUS_VERSION);
+ g_signal_connect(G_OBJECT(service), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL);
+
+ g_idle_add(build_providers, NULL);
+
+ root_menuitem = dbusmenu_menuitem_new();
+ DbusmenuServer * server = dbusmenu_server_new(INDICATOR_ME_DBUS_OBJECT);
+ dbusmenu_server_set_root(server, root_menuitem);
+
+ g_idle_add(build_menu, root_menuitem);
+
+ dbus_interface = g_object_new(STATUS_SERVICE_DBUS_TYPE, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ return 0;
+}
+
=== added file 'src/me-service.xml'
--- src/me-service.xml 1970-01-01 00:00:00 +0000
+++ src/me-service.xml 2010-03-16 11:29:18 +0000
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ayatana.indicator.me.service">
+
+<!-- Methods -->
+ <method name="Watch">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true" />
+ </method>
+ <method name="StatusIcons">
+ <arg type="s" name="icons" direction="out" />
+ </method>
+ <method name="PrettyUserName">
+ <arg type="s" name="name" direction="out" />
+ </method>
+
+<!-- Signals -->
+ <signal name="UserChanged">
+ <arg type="s" name="name" direction="out" />
+ </signal>
+ <signal name="StatusIconsChanged">
+ <arg type="s" name="icons" direction="out" />
+ </signal>
+
+ </interface>
+</node>
=== added file 'src/status-provider-mc5.c'
--- src/status-provider-mc5.c 1970-01-01 00:00:00 +0000
+++ src/status-provider-mc5.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,322 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <telepathy-glib/account-manager.h>
+
+#include "status-provider.h"
+#include "status-provider-mc5.h"
+#include "status-provider-mc5-marshal.h"
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+static gchar * sp_to_mc_map[STATUS_PROVIDER_STATUS_LAST] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ "available",
+ /* STATUS_PROVIDER_STATUS_AWAY, */ "away",
+ /* STATUS_PROVIDER_STATUS_DND */ "busy",
+ /* STATUS_PROVIDER_STATUS_INVISIBLE*/ "hidden",
+ /* STATUS_PROVIDER_STATUS_OFFLINE */ "offline",
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED*/NULL
+};
+
+static TpConnectionPresenceType sp_to_tp_map[STATUS_PROVIDER_STATUS_LAST] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ TP_CONNECTION_PRESENCE_TYPE_AVAILABLE,
+ /* STATUS_PROVIDER_STATUS_AWAY, */ TP_CONNECTION_PRESENCE_TYPE_AWAY,
+ /* STATUS_PROVIDER_STATUS_DND */ TP_CONNECTION_PRESENCE_TYPE_BUSY,
+ /* STATUS_PROVIDER_STATUS_INVISIBLE*/ TP_CONNECTION_PRESENCE_TYPE_HIDDEN,
+ /* STATUS_PROVIDER_STATUS_OFFLINE */ TP_CONNECTION_PRESENCE_TYPE_OFFLINE,
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ TP_CONNECTION_PRESENCE_TYPE_UNSET
+};
+
+static StatusProviderStatus tp_to_sp_map[TP_CONNECTION_PRESENCE_TYPE_ERROR + 1] = {
+ /* TP_CONNECTION_PRESENCE_TYPE_UNSET */ STATUS_PROVIDER_STATUS_DISCONNECTED,
+ /* TP_CONNECTION_PRESENCE_TYPE_OFFLINE */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* TP_CONNECTION_PRESENCE_TYPE_AVAILABLE */ STATUS_PROVIDER_STATUS_ONLINE,
+ /* TP_CONNECTION_PRESENCE_TYPE_AWAY */ STATUS_PROVIDER_STATUS_AWAY,
+ /* TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY */ STATUS_PROVIDER_STATUS_AWAY,
+ /* TP_CONNECTION_PRESENCE_TYPE_HIDDEN */ STATUS_PROVIDER_STATUS_INVISIBLE,
+ /* TP_CONNECTION_PRESENCE_TYPE_BUSY */ STATUS_PROVIDER_STATUS_DND,
+ /* TP_CONNECTION_PRESENCE_TYPE_UNKNOWN */ STATUS_PROVIDER_STATUS_DISCONNECTED,
+ /* TP_CONNECTION_PRESENCE_TYPE_ERROR */ STATUS_PROVIDER_STATUS_DISCONNECTED
+};
+
+typedef struct _StatusProviderMC5Private StatusProviderMC5Private;
+struct _StatusProviderMC5Private {
+ TpAccountManager * manager;
+ StatusProviderStatus status;
+ DBusGProxy * dbus_proxy;
+};
+
+#define STATUS_PROVIDER_MC5_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Private))
+#define MC5_WELL_KNOWN_NAME "org.freedesktop.Telepathy.AccountManager"
+
+/* Prototypes */
+/* GObject stuff */
+static void status_provider_mc5_class_init (StatusProviderMC5Class *klass);
+static void status_provider_mc5_init (StatusProviderMC5 *self);
+static void status_provider_mc5_dispose (GObject *object);
+static void status_provider_mc5_finalize (GObject *object);
+/* Internal Funcs */
+static void set_status (StatusProvider * sp, StatusProviderStatus status);
+static StatusProviderStatus get_status (StatusProvider * sp);
+static void presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp);
+static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self);
+static void mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata);
+
+G_DEFINE_TYPE (StatusProviderMC5, status_provider_mc5, STATUS_PROVIDER_TYPE);
+
+/* Create the class. We over ride a few functions but nothing
+ really shocking. Most interesting is the set and get status. */
+static void
+status_provider_mc5_class_init (StatusProviderMC5Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (StatusProviderMC5Private));
+
+ object_class->dispose = status_provider_mc5_dispose;
+ object_class->finalize = status_provider_mc5_finalize;
+
+ StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass);
+
+ spclass->set_status = set_status;
+ spclass->get_status = get_status;
+
+ return;
+}
+
+/* Build our telepathy account manager instance if we don't
+ have one. */
+static void
+build_eam (StatusProviderMC5 * self)
+{
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
+ static TpDBusDaemon *daemon = NULL;
+ GError *error = NULL;
+
+ if (priv->manager != NULL) {
+ return;
+ }
+ /* the daemon is used to communicate via DBus */
+ daemon = tp_dbus_daemon_dup(&error);
+
+ if (daemon == NULL)
+ {
+ g_debug("Cannot create DBus daemon: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ priv->manager = TP_ACCOUNT_MANAGER (g_object_new (TP_TYPE_ACCOUNT_MANAGER,
+ "dbus-daemon", daemon,
+ "dbus-connection", ((TpProxy *) daemon)->dbus_connection,
+ "bus-name", "org.freedesktop.Telepathy.AccountManager",
+ "object-path", "/org/freedesktop/Telepathy/AccountManager",
+ NULL));
+ g_signal_connect(G_OBJECT(priv->manager), "most-available-presence-changed", G_CALLBACK(presence_changed), self);
+
+ return;
+}
+
+/* Creating an instance of the status provider. We set the variables
+ and create an TpAccountManager object. It does all the hard
+ work in this module of tracking MissionControl and enumerating the
+ accounts and all that jazz. */
+static void
+status_provider_mc5_init (StatusProviderMC5 *self)
+{
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
+
+ priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
+ priv->manager = NULL;
+
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
+ all non-DBus stuff should be done */
+
+ GError * error = NULL;
+
+ /* Set up the dbus Proxy */
+ priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &error);
+ if (error != NULL) {
+ g_warning("Unable to connect to DBus events: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Configure the name owner changing */
+ dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK(dbus_namechange),
+ self, NULL);
+
+ org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, MC5_WELL_KNOWN_NAME, mc5_exists_cb, self);
+
+ return;
+}
+
+/* Unref the account manager and move on. Sadly, we're
+ leaving the show. */
+static void
+status_provider_mc5_dispose (GObject *object)
+{
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(object);
+
+ if (priv->manager != NULL) {
+ g_object_unref(priv->manager);
+ priv->manager = NULL;
+ }
+
+ if (priv->dbus_proxy != NULL) {
+ g_object_unref(priv->dbus_proxy);
+ priv->dbus_proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (status_provider_mc5_parent_class)->dispose (object);
+ return;
+}
+
+/* Pass to superclass */
+static void
+status_provider_mc5_finalize (GObject *object)
+{
+
+ G_OBJECT_CLASS (status_provider_mc5_parent_class)->finalize (object);
+ return;
+}
+
+/* Watch for MC5 Coming on and off the bus. */
+static void
+dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self)
+{
+ /* g_debug("DBUS NAMECHANGE: %s %s %s", name, prev, new); */
+
+ if (prev[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
+ g_debug("MC5 Coming online");
+ build_eam(self);
+ }
+ if (new[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
+ g_debug("MC5 going offline");
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
+ if (priv->manager != NULL) {
+ g_object_unref(priv->manager);
+ priv->manager = NULL;
+ }
+
+ priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
+ g_signal_emit(G_OBJECT(self), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
+ }
+
+ return;
+}
+
+/* Callback for the Dbus command to do HasOwner on
+ the MC5 service. If it exists, we want to have an
+ account manager. */
+static void
+mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata)
+{
+ if (error) {
+ g_warning("Unable to check if MC5 is running: %s", error->message);
+ return;
+ }
+
+ if (exists) {
+ build_eam(STATUS_PROVIDER_MC5(userdata));
+ }
+
+ return;
+}
+
+/**
+ status_provider_mc5_new:
+
+ Creates a new #StatusProviderMC5 object. No parameters or anything
+ like that. Just a convience function.
+
+ Return value: A new instance of #StatusProviderMC5
+*/
+StatusProvider *
+status_provider_mc5_new (void)
+{
+ return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_MC5_TYPE, NULL));
+}
+
+/* Setting the status in the empathy account manager. We're
+ basically requesting a global status. This may or may not
+ get applied to all accounts. It's really the best we can
+ hope to do. */
+static void
+set_status (StatusProvider * sp, StatusProviderStatus status)
+{
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
+
+ build_eam(STATUS_PROVIDER_MC5(sp));
+ tp_account_manager_set_all_requested_presences(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], "");
+
+ return;
+}
+
+/* Gets the status, uses the cached value that we have. Asking
+ would just be painful. */
+static StatusProviderStatus
+get_status (StatusProvider * sp)
+{
+ g_return_val_if_fail(IS_STATUS_PROVIDER_MC5(sp), STATUS_PROVIDER_STATUS_DISCONNECTED);
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
+
+ if (priv->manager == NULL) {
+ return STATUS_PROVIDER_STATUS_DISCONNECTED;
+ }
+
+ return priv->status;
+}
+
+/* A signal handler for when the TpAccountManager believes
+ that the global status has changed. It roughly calculates this
+ by finding the most available of all accounts that are active. */
+static void
+presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp)
+{
+ StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
+
+ g_debug("MC5 Status changed: %d %s %s", type, type_str, message);
+
+ if (priv->status != tp_to_sp_map[type]) {
+ priv->status = tp_to_sp_map[type];
+ g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
+ }
+
+ return;
+}
+
=== added file 'src/status-provider-mc5.h'
--- src/status-provider-mc5.h 1970-01-01 00:00:00 +0000
+++ src/status-provider-mc5.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,56 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STATUS_PROVIDER_MC5_H__
+#define __STATUS_PROVIDER_MC5_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "status-provider.h"
+
+G_BEGIN_DECLS
+
+#define STATUS_PROVIDER_MC5_TYPE (status_provider_mc5_get_type ())
+#define STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5))
+#define STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class))
+#define IS_STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_MC5_TYPE))
+#define IS_STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_MC5_TYPE))
+#define STATUS_PROVIDER_MC5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class))
+
+
+typedef struct _StatusProviderMC5Class StatusProviderMC5Class;
+struct _StatusProviderMC5Class {
+ StatusProviderClass parent_class;
+};
+
+typedef struct _StatusProviderMC5 StatusProviderMC5;
+struct _StatusProviderMC5 {
+ StatusProvider parent;
+};
+
+GType status_provider_mc5_get_type (void);
+StatusProvider * status_provider_mc5_new (void);
+
+G_END_DECLS
+
+#endif
=== added file 'src/status-provider-mc5.list'
--- src/status-provider-mc5.list 1970-01-01 00:00:00 +0000
+++ src/status-provider-mc5.list 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+VOID:UINT,STRING
=== added file 'src/status-provider-pidgin.c'
--- src/status-provider-pidgin.c 1970-01-01 00:00:00 +0000
+++ src/status-provider-pidgin.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,431 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "status-provider.h"
+#include "status-provider-pidgin.h"
+#include "status-provider-pidgin-marshal.h"
+
+#include <dbus/dbus-glib.h>
+
+typedef enum {
+ PG_STATUS_UNKNOWN,
+ PG_STATUS_OFFLINE,
+ PG_STATUS_AVAILABLE,
+ PG_STATUS_UNAVAILABLE,
+ PG_STATUS_INVISIBLE,
+ PG_STATUS_AWAY,
+ PG_STATUS_EXTENDEND_AWAY,
+ PG_STATUS_MOBILE,
+ PG_STATUS_TUNE
+} pg_status_t;
+
+static const StatusProviderStatus pg_to_sp_map[] = {
+ /* PG_STATUS_UNKNOWN, */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* PG_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* PG_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE,
+ /* PG_STATUS_UNAVAILABLE, */ STATUS_PROVIDER_STATUS_DND,
+ /* PG_STATUS_INVISIBLE, */ STATUS_PROVIDER_STATUS_INVISIBLE,
+ /* PG_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY,
+ /* PG_STATUS_EXTENDEND_AWAY, */ STATUS_PROVIDER_STATUS_AWAY,
+ /* PG_STATUS_MOBILE, */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* PG_STATUS_TUNE */ STATUS_PROVIDER_STATUS_OFFLINE
+};
+
+static const pg_status_t sp_to_pg_map[STATUS_PROVIDER_STATUS_LAST] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ PG_STATUS_AVAILABLE,
+ /* STATUS_PROVIDER_STATUS_AWAY, */ PG_STATUS_AWAY,
+ /* STATUS_PROVIDER_STATUS_DND */ PG_STATUS_UNAVAILABLE,
+ /* STATUS_PROVIDER_STATUS_INVISIBLE*/ PG_STATUS_INVISIBLE,
+ /* STATUS_PROVIDER_STATUS_OFFLINE */ PG_STATUS_OFFLINE,
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ PG_STATUS_OFFLINE
+};
+
+typedef struct _StatusProviderPidginPrivate StatusProviderPidginPrivate;
+struct _StatusProviderPidginPrivate {
+ DBusGProxy * proxy;
+ DBusGProxy * dbus_proxy;
+ pg_status_t pg_status;
+};
+
+#define STATUS_PROVIDER_PIDGIN_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginPrivate))
+
+/* Prototypes */
+/* GObject stuff */
+static void status_provider_pidgin_class_init (StatusProviderPidginClass *klass);
+static void status_provider_pidgin_init (StatusProviderPidgin *self);
+static void status_provider_pidgin_dispose (GObject *object);
+static void status_provider_pidgin_finalize (GObject *object);
+/* Internal Funcs */
+static void set_status (StatusProvider * sp, StatusProviderStatus status);
+static StatusProviderStatus get_status (StatusProvider * sp);
+static void setup_pidgin_proxy (StatusProviderPidgin * self);
+static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self);
+
+G_DEFINE_TYPE (StatusProviderPidgin, status_provider_pidgin, STATUS_PROVIDER_TYPE);
+
+static void
+status_provider_pidgin_class_init (StatusProviderPidginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (StatusProviderPidginPrivate));
+
+ object_class->dispose = status_provider_pidgin_dispose;
+ object_class->finalize = status_provider_pidgin_finalize;
+
+ StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass);
+
+ spclass->set_status = set_status;
+ spclass->get_status = get_status;
+
+ return;
+}
+
+static void
+type_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ GError * error = NULL;
+ gint status = 0;
+ if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) {
+ g_warning("Unable to get type from Pidgin: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(userdata);
+ if (status != priv->pg_status) {
+ priv->pg_status = status;
+
+ g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE);
+ }
+
+ return;
+}
+
+static void
+saved_status_to_type (StatusProviderPidgin * spp, gint savedstatus)
+{
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp);
+
+ g_debug("Pidgin figuring out type for %d", savedstatus);
+ dbus_g_proxy_begin_call(priv->proxy,
+ "PurpleSavedstatusGetType", type_cb, spp, NULL,
+ G_TYPE_INT, savedstatus, G_TYPE_INVALID);
+
+ return;
+}
+
+static void
+savedstatus_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ GError * error = NULL;
+ gint status = 0;
+ if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) {
+ g_warning("Unable to get saved status from Pidgin: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ saved_status_to_type(STATUS_PROVIDER_PIDGIN(userdata), status);
+ return;
+}
+
+
+static void
+changed_status (DBusGProxy * proxy, gint savedstatus, GError ** error, StatusProviderPidgin * spp)
+{
+ saved_status_to_type(spp, savedstatus);
+ return;
+}
+
+static void
+proxy_destroy (DBusGProxy * proxy, StatusProviderPidgin * spp)
+{
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp);
+
+ priv->proxy = NULL;
+ priv->pg_status = PG_STATUS_OFFLINE;
+
+ g_signal_emit(G_OBJECT(spp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE);
+ return;
+}
+
+static void
+status_provider_pidgin_init (StatusProviderPidgin *self)
+{
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self);
+
+ priv->proxy = NULL;
+ priv->pg_status = PG_STATUS_OFFLINE;
+
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
+ all non-DBus stuff should be done */
+
+ GError * error = NULL;
+
+ /* Set up the dbus Proxy */
+ priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &error);
+ if (error != NULL) {
+ g_warning("Unable to connect to DBus events: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Configure the name owner changing */
+ dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK(dbus_namechange),
+ self, NULL);
+
+ setup_pidgin_proxy(self);
+
+ return;
+}
+
+/* Watch to see if the Pidgin comes up on Dbus */
+static void
+dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self)
+{
+ g_return_if_fail(name != NULL);
+ g_return_if_fail(new != NULL);
+
+ if (g_strcmp0(name, "im.pidgin.purple.PurpleService") == 0) {
+ setup_pidgin_proxy(self);
+ }
+ return;
+}
+
+/* Setup the Pidgin proxy so that we can talk to it
+ and get signals from it. */
+static void
+setup_pidgin_proxy (StatusProviderPidgin * self)
+{
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self);
+
+ if (priv->proxy != NULL) {
+ g_debug("Odd, we were asked to set up a Pidgin proxy when we already had one.");
+ return;
+ }
+
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
+ all non-DBus stuff should be done */
+
+ GError * error = NULL;
+
+ /* Set up the Pidgin Proxy */
+ priv->proxy = dbus_g_proxy_new_for_name_owner (bus,
+ "im.pidgin.purple.PurpleService",
+ "/im/pidgin/purple/PurpleObject",
+ "im.pidgin.purple.PurpleInterface",
+ &error);
+ /* Report any errors */
+ if (error != NULL) {
+ g_debug("Unable to get Pidgin proxy: %s", error->message);
+ g_error_free(error);
+ }
+
+ /* If we have a proxy, let's start using it */
+ if (priv->proxy != NULL) {
+ /* Set the proxy to NULL if it's destroyed */
+ g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy);
+ /* If it's destroyed, let's clean up as well */
+ g_signal_connect(G_OBJECT(priv->proxy), "destroy",
+ G_CALLBACK(proxy_destroy), self);
+
+ /* Watching for the status change coming from the
+ Pidgin side of things. */
+ g_debug("Adding Pidgin Signals");
+ dbus_g_object_register_marshaller(_status_provider_pidgin_marshal_VOID__INT_INT,
+ G_TYPE_NONE,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->proxy,
+ "SavedstatusChanged",
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(priv->proxy,
+ "SavedstatusChanged",
+ G_CALLBACK(changed_status),
+ (void *)self,
+ NULL);
+
+ /* Get the current status to update our cached
+ value of the status. */
+ dbus_g_proxy_begin_call(priv->proxy,
+ "PurpleSavedstatusGetCurrent",
+ savedstatus_cb,
+ self,
+ NULL,
+ G_TYPE_INVALID);
+ }
+
+ return;
+}
+
+static void
+status_provider_pidgin_dispose (GObject *object)
+{
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(object);
+
+ if (priv->proxy != NULL) {
+ g_object_unref(priv->proxy);
+ priv->proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (status_provider_pidgin_parent_class)->dispose (object);
+ return;
+}
+
+static void
+status_provider_pidgin_finalize (GObject *object)
+{
+
+ G_OBJECT_CLASS (status_provider_pidgin_parent_class)->finalize (object);
+ return;
+}
+
+/**
+ status_provider_pidgin_new:
+
+ Creates a new #StatusProviderPidgin object. No parameters or anything
+ like that. Just a convience function.
+
+ Return value: A new instance of #StatusProviderPidgin
+*/
+StatusProvider *
+status_provider_pidgin_new (void)
+{
+ return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_PIDGIN_TYPE, NULL));
+}
+
+/* Takes the status provided generically for Status providers
+ and turns it into a Pidgin status and sends it to Pidgin. */
+static void
+set_status (StatusProvider * sp, StatusProviderStatus status)
+{
+ gchar * message = "";
+
+ g_return_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp));
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp);
+
+ g_debug("\tPidgin set status to %d", status);
+ if (priv->proxy == NULL) {
+ return;
+ }
+
+ priv->pg_status = sp_to_pg_map[status];
+ gint status_val = 0;
+ gboolean ret = FALSE;
+ GError * error = NULL;
+
+ ret = dbus_g_proxy_call(priv->proxy,
+ "PurpleSavedstatusFindTransientByTypeAndMessage", &error,
+ G_TYPE_INT, priv->pg_status,
+ G_TYPE_STRING, message,
+ G_TYPE_INVALID,
+ G_TYPE_INT, &status_val,
+ G_TYPE_INVALID);
+
+ if (!ret) {
+ if (error != NULL) {
+ g_error_free(error);
+ }
+ error = NULL;
+ status_val = 0;
+ g_debug("No Pidgin saved status to apply");
+ }
+
+ if (status_val == 0) {
+ ret = dbus_g_proxy_call(priv->proxy,
+ "PurpleSavedstatusNew", &error,
+ G_TYPE_STRING, message,
+ G_TYPE_INT, priv->pg_status,
+ G_TYPE_INVALID,
+ G_TYPE_INT, &status_val,
+ G_TYPE_INVALID);
+
+ if (!ret) {
+ status_val = 0;
+ if (error != NULL) {
+ g_warning("Unable to create Pidgin status for %d: %s", status, error->message);
+ g_error_free(error);
+ } else {
+ g_warning("Unable to create Pidgin status for %d", status);
+ }
+ error = NULL;
+ }
+ }
+
+ if (status_val == 0) {
+ return;
+ }
+
+ ret = dbus_g_proxy_call(priv->proxy,
+ "PurpleSavedstatusActivate", &error,
+ G_TYPE_INT, status_val,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ if (!ret) {
+ if (error != NULL) {
+ g_warning("Pidgin unable to change to status: %s", error->message);
+ g_error_free(error);
+ } else {
+ g_warning("Pidgin unable to change to status");
+ }
+ error = NULL;
+ }
+
+ g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE);
+ return;
+}
+
+/* Takes the cached Pidgin status and makes it into the generic
+ Status provider status. If there is no Pidgin proxy then it
+ returns the disconnected state. */
+static StatusProviderStatus
+get_status (StatusProvider * sp)
+{
+ g_return_val_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp), STATUS_PROVIDER_STATUS_DISCONNECTED);
+ StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp);
+
+ if (priv->proxy == NULL) {
+ return STATUS_PROVIDER_STATUS_DISCONNECTED;
+ }
+
+ return pg_to_sp_map[priv->pg_status];
+}
=== added file 'src/status-provider-pidgin.h'
--- src/status-provider-pidgin.h 1970-01-01 00:00:00 +0000
+++ src/status-provider-pidgin.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,56 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STATUS_PROVIDER_PIDGIN_H__
+#define __STATUS_PROVIDER_PIDGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "status-provider.h"
+
+G_BEGIN_DECLS
+
+#define STATUS_PROVIDER_PIDGIN_TYPE (status_provider_pidgin_get_type ())
+#define STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidgin))
+#define STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass))
+#define IS_STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_PIDGIN_TYPE))
+#define IS_STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_PIDGIN_TYPE))
+#define STATUS_PROVIDER_PIDGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass))
+
+
+typedef struct _StatusProviderPidginClass StatusProviderPidginClass;
+struct _StatusProviderPidginClass {
+ StatusProviderClass parent_class;
+};
+
+typedef struct _StatusProviderPidgin StatusProviderPidgin;
+struct _StatusProviderPidgin {
+ StatusProvider parent;
+};
+
+GType status_provider_pidgin_get_type (void);
+StatusProvider * status_provider_pidgin_new (void);
+
+G_END_DECLS
+
+#endif
=== added file 'src/status-provider-pidgin.list'
--- src/status-provider-pidgin.list 1970-01-01 00:00:00 +0000
+++ src/status-provider-pidgin.list 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+VOID:INT,INT
=== added file 'src/status-provider-telepathy.c'
--- src/status-provider-telepathy.c 1970-01-01 00:00:00 +0000
+++ src/status-provider-telepathy.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,383 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "status-provider.h"
+#include "status-provider-telepathy.h"
+#include "status-provider-telepathy-marshal.h"
+
+#include <dbus/dbus-glib.h>
+
+typedef enum {
+ MC_STATUS_UNSET,
+ MC_STATUS_OFFLINE,
+ MC_STATUS_AVAILABLE,
+ MC_STATUS_AWAY,
+ MC_STATUS_EXTENDED_AWAY,
+ MC_STATUS_HIDDEN,
+ MC_STATUS_DND
+} mc_status_t;
+
+static StatusProviderStatus mc_to_sp_map[] = {
+ /* MC_STATUS_UNSET, */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* MC_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE,
+ /* MC_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE,
+ /* MC_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY,
+ /* MC_STATUS_EXTENDED_AWAY, */ STATUS_PROVIDER_STATUS_AWAY,
+ /* MC_STATUS_HIDDEN, */ STATUS_PROVIDER_STATUS_INVISIBLE,
+ /* MC_STATUS_DND */ STATUS_PROVIDER_STATUS_DND
+};
+
+static mc_status_t sp_to_mc_map[] = {
+ /* STATUS_PROVIDER_STATUS_ONLINE, */ MC_STATUS_AVAILABLE,
+ /* STATUS_PROVIDER_STATUS_AWAY, */ MC_STATUS_AWAY,
+ /* STATUS_PROVIDER_STATUS_DND */ MC_STATUS_DND,
+ /* STATUS_PROVIDER_STATUS_INVISIBLE*/ MC_STATUS_HIDDEN,
+ /* STATUS_PROVIDER_STATUS_OFFLINE */ MC_STATUS_OFFLINE,
+ /* STATUS_PROVIDER_STATUS_DISCONNECTED*/MC_STATUS_OFFLINE
+};
+
+typedef struct _StatusProviderTelepathyPrivate StatusProviderTelepathyPrivate;
+struct _StatusProviderTelepathyPrivate {
+ DBusGProxy * proxy;
+ DBusGProxy * dbus_proxy;
+ mc_status_t mc_status;
+};
+
+#define STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyPrivate))
+
+/* Prototypes */
+/* GObject stuff */
+static void status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass);
+static void status_provider_telepathy_init (StatusProviderTelepathy *self);
+static void status_provider_telepathy_dispose (GObject *object);
+static void status_provider_telepathy_finalize (GObject *object);
+/* Internal Funcs */
+static void build_telepathy_proxy (StatusProviderTelepathy * self);
+static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self);
+static void set_status (StatusProvider * sp, StatusProviderStatus status);
+static StatusProviderStatus get_status (StatusProvider * sp);
+static void changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp);
+static void proxy_destroy (DBusGProxy * proxy, StatusProvider * sp);
+static void get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata);
+
+G_DEFINE_TYPE (StatusProviderTelepathy, status_provider_telepathy, STATUS_PROVIDER_TYPE);
+
+static void
+status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (StatusProviderTelepathyPrivate));
+
+ object_class->dispose = status_provider_telepathy_dispose;
+ object_class->finalize = status_provider_telepathy_finalize;
+
+ StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass);
+
+ spclass->set_status = set_status;
+ spclass->get_status = get_status;
+
+ return;
+}
+
+
+static void
+status_provider_telepathy_init (StatusProviderTelepathy *self)
+{
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self);
+
+ priv->proxy = NULL;
+ priv->dbus_proxy = NULL;
+ priv->mc_status = MC_STATUS_OFFLINE;
+
+ GError * error = NULL;
+
+ /* Grabbing the session bus */
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+ if (bus == NULL) {
+ g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Set up the dbus Proxy */
+ priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &error);
+ if (error != NULL) {
+ g_warning("Unable to connect to DBus events: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Configure the name owner changing */
+ dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK(dbus_namechange),
+ self, NULL);
+
+ build_telepathy_proxy(self);
+
+ return;
+}
+
+/* Builds up the proxy to Mission Control and configures all of the
+ signals for getting info from the proxy. Also does a call to get
+ the inital value of the status. */
+static void
+build_telepathy_proxy (StatusProviderTelepathy * self)
+{
+ g_debug("Building Telepathy Proxy");
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self);
+
+ if (priv->proxy != NULL) {
+ g_debug("Hmm, being asked to build a proxy we alredy have.");
+ return;
+ }
+
+ GError * error = NULL;
+
+ /* Grabbing the session bus */
+ DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+ if (session_bus == NULL) {
+ g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Get the proxy to Mission Control */
+ priv->proxy = dbus_g_proxy_new_for_name_owner(session_bus,
+ "org.freedesktop.Telepathy.MissionControl",
+ "/org/freedesktop/Telepathy/MissionControl",
+ "org.freedesktop.Telepathy.MissionControl",
+ &error);
+
+ if (priv->proxy != NULL) {
+ /* If it goes, we set the proxy to NULL */
+ g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy);
+ /* And we clean up other variables associated */
+ g_signal_connect(G_OBJECT(priv->proxy), "destroy",
+ G_CALLBACK(proxy_destroy), self);
+
+ /* Set up the signal handler for watching when status changes. */
+ dbus_g_object_register_marshaller(_status_provider_telepathy_marshal_VOID__UINT_STRING,
+ G_TYPE_NONE,
+ G_TYPE_UINT,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->proxy,
+ "PresenceChanged",
+ G_TYPE_UINT,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(priv->proxy,
+ "PresenceChanged",
+ G_CALLBACK(changed_status),
+ (void *)self,
+ NULL);
+
+ /* Do a get here, to init the status */
+ dbus_g_proxy_begin_call(priv->proxy,
+ "GetStatus",
+ get_status_async,
+ self,
+ NULL,
+ G_TYPE_INVALID);
+ } else {
+ g_warning("Unable to connect to Mission Control");
+ if (error != NULL) {
+ g_error_free(error);
+ }
+ }
+
+ return;
+}
+
+/* Watch to see if the Mission Control comes up on Dbus */
+static void
+dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self)
+{
+ g_return_if_fail(name != NULL);
+ g_return_if_fail(new != NULL);
+
+ if (g_strcmp0(name, "org.freedesktop.Telepathy.MissionControl") == 0) {
+ build_telepathy_proxy(self);
+ }
+ return;
+}
+
+static void
+status_provider_telepathy_dispose (GObject *object)
+{
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(object);
+
+ if (priv->proxy != NULL) {
+ g_object_unref(priv->proxy);
+ priv->proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (status_provider_telepathy_parent_class)->dispose (object);
+ return;
+}
+
+static void
+status_provider_telepathy_finalize (GObject *object)
+{
+
+ G_OBJECT_CLASS (status_provider_telepathy_parent_class)->finalize (object);
+ return;
+}
+
+/**
+ status_provider_telepathy_new:
+
+ Creates a new #StatusProviderTelepathy object. No parameters or anything
+ like that. Just a convience function.
+
+ Return value: A new instance of #StatusProviderTelepathy
+*/
+StatusProvider *
+status_provider_telepathy_new (void)
+{
+ return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_TELEPATHY_TYPE, NULL));
+}
+
+static void
+set_status (StatusProvider * sp, StatusProviderStatus status)
+{
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp);
+ if (priv->proxy == NULL) {
+ priv->mc_status = MC_STATUS_OFFLINE;
+ return;
+ }
+
+ priv->mc_status = sp_to_mc_map[status];
+
+ guint mcstatus = MC_STATUS_UNSET;
+ gboolean ret = FALSE;
+ GError * error = NULL;
+
+ ret = dbus_g_proxy_call(priv->proxy,
+ "GetPresence", &error,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &priv->mc_status,
+ G_TYPE_INVALID);
+
+ /* If we can't get the get call to work, let's not set */
+ if (!ret) {
+ if (error != NULL) {
+ g_error_free(error);
+ }
+ return;
+ }
+
+ /* If the get call doesn't return a status, that means that there
+ are no clients connected. We don't want to connect them by telling
+ MC that we're going online -- we'd like to be more passive than that. */
+ if (mcstatus == MC_STATUS_UNSET) {
+ return;
+ }
+
+ ret = dbus_g_proxy_call(priv->proxy,
+ "SetPresence", &error,
+ G_TYPE_UINT, priv->mc_status,
+ G_TYPE_STRING, "",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ if (!ret) {
+ if (error != NULL) {
+ g_warning("Unable to set Mission Control Presence: %s", error->message);
+ g_error_free(error);
+ } else {
+ g_warning("Unable to set Mission Control Presence");
+ }
+ return;
+ }
+
+ return;
+}
+
+static StatusProviderStatus
+get_status (StatusProvider * sp)
+{
+ g_return_val_if_fail(IS_STATUS_PROVIDER_TELEPATHY(sp), STATUS_PROVIDER_STATUS_DISCONNECTED);
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp);
+
+ if (priv->proxy == NULL) {
+ return STATUS_PROVIDER_STATUS_DISCONNECTED;
+ }
+
+ return mc_to_sp_map[priv->mc_status];
+}
+
+static void
+changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp)
+{
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp);
+ priv->mc_status = status;
+ g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE);
+}
+
+static void
+proxy_destroy (DBusGProxy * proxy, StatusProvider * sp)
+{
+ g_debug("Signal: Mission Control proxy destroyed");
+ g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, STATUS_PROVIDER_STATUS_OFFLINE, TRUE);
+ return;
+}
+
+static void
+get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ GError * error = NULL;
+ guint status = 0;
+ if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_UINT, &status, G_TYPE_INVALID)) {
+ g_warning("Unable to get type from Mission Control: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(userdata);
+
+ gboolean changed = FALSE;
+ if (status != priv->mc_status) {
+ changed = TRUE;
+ }
+
+ priv->mc_status = status;
+
+ if (changed) {
+ g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE);
+ }
+
+ return;
+}
=== added file 'src/status-provider-telepathy.h'
--- src/status-provider-telepathy.h 1970-01-01 00:00:00 +0000
+++ src/status-provider-telepathy.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,56 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STATUS_PROVIDER_TELEPATHY_H__
+#define __STATUS_PROVIDER_TELEPATHY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "status-provider.h"
+
+G_BEGIN_DECLS
+
+#define STATUS_PROVIDER_TELEPATHY_TYPE (status_provider_telepathy_get_type ())
+#define STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathy))
+#define STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass))
+#define IS_STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TELEPATHY_TYPE))
+#define IS_STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TELEPATHY_TYPE))
+#define STATUS_PROVIDER_TELEPATHY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass))
+
+
+typedef struct _StatusProviderTelepathyClass StatusProviderTelepathyClass;
+struct _StatusProviderTelepathyClass {
+ StatusProviderClass parent_class;
+};
+
+typedef struct _StatusProviderTelepathy StatusProviderTelepathy;
+struct _StatusProviderTelepathy {
+ StatusProvider parent;
+};
+
+GType status_provider_telepathy_get_type (void);
+StatusProvider * status_provider_telepathy_new (void);
+
+G_END_DECLS
+
+#endif
=== added file 'src/status-provider-telepathy.list'
--- src/status-provider-telepathy.list 1970-01-01 00:00:00 +0000
+++ src/status-provider-telepathy.list 2010-03-16 11:29:18 +0000
@@ -0,0 +1,1 @@
+VOID:UINT,STRING
=== added file 'src/status-provider.c'
--- src/status-provider.c 1970-01-01 00:00:00 +0000
+++ src/status-provider.c 2010-03-16 11:29:18 +0000
@@ -0,0 +1,101 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "status-provider.h"
+
+/* Signals */
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/* GObject Boilerplate */
+static void status_provider_class_init (StatusProviderClass *klass);
+static void status_provider_init (StatusProvider *self);
+
+G_DEFINE_TYPE (StatusProvider, status_provider, G_TYPE_OBJECT);
+
+static void
+status_provider_class_init (StatusProviderClass *klass)
+{
+ // GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ klass->status_changed = NULL;
+
+ klass->set_status = NULL;
+ klass->get_status = NULL;
+
+ /**
+ StatusProvider::status-changed:
+ @arg0: The #StatusProvider object.
+ @arg1: The new status #StatusProviderStatus
+
+ Should be emitted by subclasses everytime that the status
+ changes externally to us.
+ */
+ signals[STATUS_CHANGED] = g_signal_new(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(StatusProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ return;
+}
+
+static void
+status_provider_init (StatusProvider *self)
+{
+
+ return;
+}
+
+void
+status_provider_set_status (StatusProvider * sp, StatusProviderStatus status)
+{
+ g_return_if_fail(IS_STATUS_PROVIDER(sp));
+
+ StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp);
+ g_return_if_fail(class != NULL);
+ g_return_if_fail(class->set_status != NULL);
+
+ return class->set_status(sp, status);
+}
+
+StatusProviderStatus
+status_provider_get_status (StatusProvider * sp)
+{
+ g_return_val_if_fail(IS_STATUS_PROVIDER(sp), STATUS_PROVIDER_STATUS_OFFLINE);
+
+ StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp);
+ g_return_val_if_fail(class->get_status != NULL, STATUS_PROVIDER_STATUS_OFFLINE);
+
+ return class->get_status(sp);
+}
+
=== added file 'src/status-provider.h'
--- src/status-provider.h 1970-01-01 00:00:00 +0000
+++ src/status-provider.h 2010-03-16 11:29:18 +0000
@@ -0,0 +1,78 @@
+/*
+A small wrapper utility to load indicators and put them as menu items
+into the gnome-panel using it's applet interface.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STATUS_PROVIDER_H__
+#define __STATUS_PROVIDER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define STATUS_PROVIDER_TYPE (status_provider_get_type ())
+#define STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TYPE, StatusProvider))
+#define STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TYPE, StatusProviderClass))
+#define IS_STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TYPE))
+#define IS_STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TYPE))
+#define STATUS_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TYPE, StatusProviderClass))
+
+typedef enum
+{
+ STATUS_PROVIDER_STATUS_ONLINE,
+ STATUS_PROVIDER_STATUS_AWAY,
+ STATUS_PROVIDER_STATUS_DND,
+ STATUS_PROVIDER_STATUS_INVISIBLE,
+ STATUS_PROVIDER_STATUS_OFFLINE,
+ STATUS_PROVIDER_STATUS_DISCONNECTED,
+ /* Leave as last */
+ STATUS_PROVIDER_STATUS_LAST
+}
+StatusProviderStatus;
+
+#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED "status-changed"
+#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID (g_signal_lookup(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, STATUS_PROVIDER_TYPE))
+
+typedef struct _StatusProvider StatusProvider;
+struct _StatusProvider {
+ GObject parent;
+};
+
+typedef struct _StatusProviderClass StatusProviderClass;
+struct _StatusProviderClass {
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*status_changed) (StatusProviderStatus newstatus);
+
+ /* Virtual Functions */
+ void (*set_status) (StatusProvider * sp, StatusProviderStatus newstatus);
+ StatusProviderStatus (*get_status) (StatusProvider * sp);
+};
+
+GType status_provider_get_type (void);
+
+void status_provider_set_status (StatusProvider * sp, StatusProviderStatus status);
+StatusProviderStatus status_provider_get_status (StatusProvider * sp);
+
+G_END_DECLS
+
+#endif