├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── README.md ├── configure.ac ├── package.sh ├── pkg ├── arch │ ├── PKGBUILD │ └── volnoti-0.1-3.src.tar.gz └── gentoo │ └── volnoti-0.1.ebuild ├── prepare.sh ├── res ├── Makefile.am ├── progressbar_empty.png ├── progressbar_empty.xcf ├── progressbar_full.png ├── progressbar_full.xcf ├── volume_high.png ├── volume_high.svg ├── volume_low.png ├── volume_low.svg ├── volume_medium.png ├── volume_medium.svg ├── volume_muted.png ├── volume_muted.svg ├── volume_off.png └── volume_off.svg └── src ├── Makefile.am ├── client.c ├── common.c ├── common.h ├── daemon.c ├── gopt.c ├── gopt.h ├── notification.c ├── notification.h ├── specs.xml ├── value-client-stub.h └── value-daemon-stub.h /AUTHORS: -------------------------------------------------------------------------------- 1 | David Brazdil 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/ChangeLog -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell commands `./configure; make; make install' should 16 | configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 230 | parse its `' header file. The option `-nodtk' can be used as 231 | a workaround. If GNU CC is not installed, it is therefore recommended 232 | to try 233 | 234 | ./configure CC="cc" 235 | 236 | and if that doesn't work, try 237 | 238 | ./configure CC="cc -nodtk" 239 | 240 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 241 | directory contains several dysfunctional programs; working variants of 242 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 243 | in your `PATH', put it _after_ `/usr/bin'. 244 | 245 | On Haiku, software installed for all users goes in `/boot/common', 246 | not `/usr/local'. It is recommended to use the following options: 247 | 248 | ./configure --prefix=/boot/common 249 | 250 | Specifying the System Type 251 | ========================== 252 | 253 | There may be some features `configure' cannot figure out 254 | automatically, but needs to determine by the type of machine the package 255 | will run on. Usually, assuming the package is built to be run on the 256 | _same_ architectures, `configure' can figure that out, but if it prints 257 | a message saying it cannot guess the machine type, give it the 258 | `--build=TYPE' option. TYPE can either be a short name for the system 259 | type, such as `sun4', or a canonical name which has the form: 260 | 261 | CPU-COMPANY-SYSTEM 262 | 263 | where SYSTEM can have one of these forms: 264 | 265 | OS 266 | KERNEL-OS 267 | 268 | See the file `config.sub' for the possible values of each field. If 269 | `config.sub' isn't included in this package, then this package doesn't 270 | need to know the machine type. 271 | 272 | If you are _building_ compiler tools for cross-compiling, you should 273 | use the option `--target=TYPE' to select the type of system they will 274 | produce code for. 275 | 276 | If you want to _use_ a cross compiler, that generates code for a 277 | platform different from the build platform, you should specify the 278 | "host" platform (i.e., that on which the generated programs will 279 | eventually be run) with `--host=TYPE'. 280 | 281 | Sharing Defaults 282 | ================ 283 | 284 | If you want to set default values for `configure' scripts to share, 285 | you can create a site shell script called `config.site' that gives 286 | default values for variables like `CC', `cache_file', and `prefix'. 287 | `configure' looks for `PREFIX/share/config.site' if it exists, then 288 | `PREFIX/etc/config.site' if it exists. Or, you can set the 289 | `CONFIG_SITE' environment variable to the location of the site script. 290 | A warning: not all `configure' scripts look for a site script. 291 | 292 | Defining Variables 293 | ================== 294 | 295 | Variables not defined in a site shell script can be set in the 296 | environment passed to `configure'. However, some packages may run 297 | configure again during the build, and the customized values of these 298 | variables may be lost. In order to avoid this problem, you should set 299 | them in the `configure' command line, using `VAR=value'. For example: 300 | 301 | ./configure CC=/usr/local2/bin/gcc 302 | 303 | causes the specified `gcc' to be used as the C compiler (unless it is 304 | overridden in the site shell script). 305 | 306 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 307 | an Autoconf bug. Until the bug is fixed you can use this workaround: 308 | 309 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 310 | 311 | `configure' Invocation 312 | ====================== 313 | 314 | `configure' recognizes the following options to control how it 315 | operates. 316 | 317 | `--help' 318 | `-h' 319 | Print a summary of all of the options to `configure', and exit. 320 | 321 | `--help=short' 322 | `--help=recursive' 323 | Print a summary of the options unique to this package's 324 | `configure', and exit. The `short' variant lists options used 325 | only in the top level, while the `recursive' variant lists options 326 | also present in any nested packages. 327 | 328 | `--version' 329 | `-V' 330 | Print the version of Autoconf used to generate the `configure' 331 | script, and exit. 332 | 333 | `--cache-file=FILE' 334 | Enable the cache: use and save the results of the tests in FILE, 335 | traditionally `config.cache'. FILE defaults to `/dev/null' to 336 | disable caching. 337 | 338 | `--config-cache' 339 | `-C' 340 | Alias for `--cache-file=config.cache'. 341 | 342 | `--quiet' 343 | `--silent' 344 | `-q' 345 | Do not print messages saying which checks are being made. To 346 | suppress all normal output, redirect it to `/dev/null' (any error 347 | messages will still be shown). 348 | 349 | `--srcdir=DIR' 350 | Look for the package's source code in directory DIR. Usually 351 | `configure' can determine that directory automatically. 352 | 353 | `--prefix=DIR' 354 | Use DIR as the installation prefix. *note Installation Names:: 355 | for more details, including other options available for fine-tuning 356 | the installation locations. 357 | 358 | `--no-create' 359 | `-n' 360 | Run the configure checks, but stop before creating any output 361 | files. 362 | 363 | `configure' also accepts some other, not widely useful, options. Run 364 | `configure --help' for more details. 365 | 366 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src res 2 | EXTRA_DIST = README.md INSTALL COPYING AUTHORS NEWS ChangeLog 3 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Volnoti 2 | ========= 3 | 4 | Volnoti is a lightweight volume notification daemon for GNU/Linux and 5 | other POSIX operating systems. It is based on GTK+ and D-Bus and should 6 | work with any sensible window manager. The original aim was to create 7 | a volume notification daemon for lightweight window managers like LXDE 8 | or XMonad. It is known to work with a wide range of WMs, including 9 | GNOME, KDE, Xfce, LXDE, XMonad, i3 and many others. The source code 10 | is heavily based on the GNOME notification-daemon. 11 | 12 | Distribution packages 13 | --------------------- 14 | 15 | - Arch Linux - available in [AUR](https://aur.archlinux.org/packages.php?ID=55159) 16 | - Gentoo - [ebuild](https://bugs.gentoo.org/show_bug.cgi?id=395595) in Bugzilla 17 | 18 | Dependencies 19 | ------------ 20 | 21 | You need the following libraries to compile Volnoti yourself. Please 22 | install them through the package manager of your distribution, or follow 23 | installation instructions on the projects' websites. 24 | 25 | - [D-Bus](http://dbus.freedesktop.org) 26 | - [D-Bus Glib](http://dbus.freedesktop.org/releases/dbus-glib) 27 | - [GTK+ 2.0](http://www.gtk.org) 28 | - [GDK-Pixbuf 2.0](http://www.gtk.org) 29 | 30 | You can compile it with standard `GCC`, with `make` and `pkg-config` 31 | installed, and you will need `autoconf` and `automake` if you choose 32 | to compile the Git version. 33 | 34 | Compilation from Git 35 | -------------------- 36 | 37 | Start by downloading the source code from GitHub: 38 | 39 | $ git clone git://github.com/davidbrazdil/volnoti.git 40 | $ cd volnoti 41 | 42 | Let Autotools create the configuration scripts: 43 | 44 | $ ./prepare.sh 45 | 46 | Then just follow the basic GNU routine: 47 | 48 | $ ./configure --prefix=/usr 49 | $ make 50 | $ sudo make install 51 | 52 | You can have the `.tar.gz` source archive prepared simply by calling 53 | a provided script: 54 | 55 | $ ./package.sh 56 | 57 | Compilation from source archive 58 | ------------------------------- 59 | 60 | Download the `.tar.gz` source archive from the GitHub page, and then 61 | extract its contents by calling: 62 | 63 | $ tar xvzf volnoti-*.tar.gz 64 | 65 | Then just follow the basic GNU routine: 66 | 67 | $ ./configure --prefix=/usr 68 | $ make 69 | $ sudo make install 70 | 71 | Running the application 72 | ----------------------- 73 | 74 | Firstly, you need to running the daemon (add it to your startup 75 | applications): 76 | 77 | $ volnoti 78 | 79 | Consult the output of `volnoti --help` if you want to see debug output 80 | ot don't want the application to run as a daemon. You can also change 81 | some parameters of the notifications (like their duration time) through 82 | the parameters of the daemon. 83 | 84 | Once the daemon is running, you can run for example: 85 | 86 | $ volnoti-show 25 87 | 88 | to show a notification for volume level 25%. To show a notification for 89 | muted sound, call: 90 | 91 | $ volnoti-show -m 92 | 93 | The best way to do this is to create simple script and attach it to 94 | the hot-keys on your keyboard. But this depends on your window manager 95 | and system configuration. 96 | 97 | Theming 98 | ------- 99 | 100 | Some parameters of the notifications can be changed through the 101 | parameters of the daemon. To learn more, run: 102 | 103 | $ volnoti --help 104 | 105 | All the images are stored in `/usr/share/pixmaps/volnoti` (depending 106 | on the chosen prefix during configuration phase) and it should be 107 | easy to replace them with your favourite icons. 108 | 109 | Credits 110 | ------- 111 | 112 | - Faenza Icon Set (tiheum.deviantart.com) 113 | - Notification-daemon (www.gnome.org) 114 | - Gopt (www.purposeful.co.uk/software/gopt) 115 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.68]) 5 | AC_INIT([volnoti], [0.2], []) 6 | AC_CONFIG_SRCDIR([src/daemon.c]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | 9 | AM_INIT_AUTOMAKE([1.10 -Wall no-define]) 10 | # AC_CONFIG_FILES([Makefile]) 11 | 12 | # Checks for programs. 13 | AC_PROG_CC 14 | AM_PROG_CC_C_O 15 | 16 | # Checks for libraries. 17 | PKG_CHECK_MODULES([DBUS], [dbus-1]) 18 | PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1]) 19 | PKG_CHECK_MODULES([GTK], [gtk+-2.0]) 20 | PKG_CHECK_MODULES([CAIRO], [cairo]) 21 | PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0]) 22 | 23 | # Checks for header files. 24 | AC_CHECK_HEADERS([stdlib.h string.h unistd.h]) 25 | 26 | # Checks for typedefs, structures, and compiler characteristics. 27 | AC_C_INLINE 28 | AC_TYPE_SIZE_T 29 | 30 | # Checks for library functions. 31 | AC_FUNC_MALLOC 32 | AC_CHECK_FUNCS([strchr strcspn]) 33 | 34 | AC_OUTPUT([ 35 | Makefile 36 | src/Makefile 37 | res/Makefile 38 | ]) 39 | -------------------------------------------------------------------------------- /package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./prepare.sh 3 | ./configure 4 | make dist 5 | -------------------------------------------------------------------------------- /pkg/arch/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: David Brazdil 2 | pkgname=volnoti 3 | pkgver=0.1 4 | pkgrel=3 5 | pkgdesc="Lightweight volume notification" 6 | url="https://www.github.com/davidbrazdil/volnoti" 7 | arch=('x86_64' 'i686') 8 | license=('GPLv3') 9 | depends=('dbus-core' 'dbus-glib' 'gtk2' 'gdk-pixbuf2') 10 | makedepends=('gcc' 'make' 'pkg-config') 11 | conflicts=() 12 | replaces=() 13 | backup=() 14 | # install='foo.install' 15 | source=("http://github.com/downloads/davidbrazdil/volnoti/${pkgname}-${pkgver}.tar.gz") 16 | md5sums=('f1e7a3730528b8808228415990d398f9') 17 | 18 | build() { 19 | cd "${srcdir}/${pkgname}-${pkgver}" 20 | ./configure --prefix=/usr 21 | make 22 | } 23 | 24 | package() { 25 | cd "${srcdir}/${pkgname}-${pkgver}" 26 | make DESTDIR="${pkgdir}" install 27 | install -Dm644 COPYING "$pkgdir/usr/share/licenses/$pkgname/COPYING" 28 | } 29 | 30 | # vim:set ts=2 sw=2 et: 31 | 32 | -------------------------------------------------------------------------------- /pkg/arch/volnoti-0.1-3.src.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/pkg/arch/volnoti-0.1-3.src.tar.gz -------------------------------------------------------------------------------- /pkg/gentoo/volnoti-0.1.ebuild: -------------------------------------------------------------------------------- 1 | # Copyright 1999-2011 Gentoo Foundation 2 | # Distributed under the terms of the GNU General Public License v3 3 | # $Header: /var/cvsroot/gentoo-x86/media-sound/volti/volnoti-0.1.ebuild $ 4 | 5 | EAPI=4 6 | 7 | inherit toolchain-funcs 8 | 9 | SLOT="0" 10 | MY_P="${PN}-${PV}" 11 | IUSE="" 12 | 13 | DESCRIPTION="Lightweight volume notification" 14 | HOMEPAGE="https://github.com/davidbrazdil/volnoti" 15 | SRC_URI="mirror://github/davidbrazdil/volnoti/${MY_P}.tar.gz" 16 | 17 | LICENSE="GPL-3" 18 | KEYWORDS="~amd64 ~x86" 19 | 20 | RDEPEND="sys-apps/dbus 21 | dev-libs/dbus-glib 22 | x11-libs/gtk+ 23 | x11-libs/gdk-pixbuf" 24 | DEPEND="dev-util/pkgconfig" 25 | 26 | S=${WORKDIR}/${MY_P} 27 | 28 | src_compile() { 29 | tc-export CC 30 | emake 31 | } 32 | -------------------------------------------------------------------------------- /prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | autoreconf --force --install 3 | -------------------------------------------------------------------------------- /res/Makefile.am: -------------------------------------------------------------------------------- 1 | datadir = $(datarootdir)/pixmaps/@PACKAGE@/ 2 | ICONS = progressbar_empty.png progressbar_full.png \ 3 | volume_high.svg volume_medium.svg \ 4 | volume_low.svg volume_off.svg volume_muted.svg 5 | 6 | data_DATA = $(ICONS) 7 | EXTRA_DIST = $(ICONS) 8 | -------------------------------------------------------------------------------- /res/progressbar_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/progressbar_empty.png -------------------------------------------------------------------------------- /res/progressbar_empty.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/progressbar_empty.xcf -------------------------------------------------------------------------------- /res/progressbar_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/progressbar_full.png -------------------------------------------------------------------------------- /res/progressbar_full.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/progressbar_full.xcf -------------------------------------------------------------------------------- /res/volume_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/volume_high.png -------------------------------------------------------------------------------- /res/volume_high.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 21 | 25 | 29 | 30 | 39 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 55 | 59 | 63 | 67 | 72 | 78 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /res/volume_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/volume_low.png -------------------------------------------------------------------------------- /res/volume_low.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 21 | 25 | 29 | 30 | 39 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 55 | 59 | 64 | 69 | 74 | 79 | 84 | 89 | 94 | 99 | 104 | 109 | 114 | 120 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /res/volume_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/volume_medium.png -------------------------------------------------------------------------------- /res/volume_medium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 21 | 25 | 29 | 30 | 39 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 55 | 60 | 65 | 70 | 75 | 80 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 122 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /res/volume_muted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/volume_muted.png -------------------------------------------------------------------------------- /res/volume_muted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 21 | 25 | 29 | 30 | 39 | 41 | 45 | 49 | 50 | 59 | 60 | 62 | 63 | 65 | image/svg+xml 66 | 68 | 69 | 70 | 71 | 75 | 79 | 83 | 88 | 93 | 98 | 103 | 108 | 113 | 119 | 124 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /res/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brazdil/volnoti/4af7c8e54ecc499097121909f02ecb42a8a60d24/res/volume_off.png -------------------------------------------------------------------------------- /res/volume_off.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 21 | 25 | 29 | 30 | 39 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = subdir-objects 2 | ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} 3 | AM_CONFIG_HEADER = ../config.h 4 | 5 | EXTRA_DIST = specs.xml 6 | 7 | AM_CPPFLAGS = \ 8 | @DBUS_CFLAGS@ \ 9 | @DBUS_GLIB_CFLAGS@ \ 10 | @GTK_CFLAGS@ \ 11 | @CAIRO_CFLAGS@ \ 12 | @GDK_PIXBUF_CFLAGS@ \ 13 | -DPREFIX="\"$(datarootdir)/pixmaps/@PACKAGE@/\"" 14 | 15 | COMMON = common.c common.h gopt.c gopt.h 16 | 17 | bin_PROGRAMS = volnoti volnoti-show 18 | 19 | volnoti_SOURCES = daemon.c notification.c notification.h \ 20 | value-daemon-stub.h $(COMMON) 21 | volnoti_LDADD = \ 22 | @DBUS_LIBS@ \ 23 | @DBUS_GLIB_LIBS@ \ 24 | @GTK_LIBS@ \ 25 | @CAIRO_LIBS@ \ 26 | @GDK_PIXBUF_LIBS@ 27 | 28 | volnoti_show_SOURCES = client.c value-client-stub.h $(COMMON) 29 | volnoti_show_LDADD = \ 30 | @DBUS_LIBS@ \ 31 | @DBUS_GLIB_LIBS@ 32 | 33 | interface_xml = specs.xml 34 | 35 | value-daemon-stub.h: $(interface_xml) 36 | dbus-binding-tool --prefix=volume_object --mode=glib-server \ 37 | $< > $@ 38 | 39 | value-client-stub.h: $(interface_xml) 40 | dbus-binding-tool --prefix=volume_object --mode=glib-client \ 41 | $< > $@ 42 | -------------------------------------------------------------------------------- /src/client.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | * Copyright (C) 2011 David Brazdil 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "common.h" 26 | #include "gopt.h" 27 | 28 | #include "value-client-stub.h" 29 | 30 | static void print_usage(const char* filename, int failure) { 31 | g_print("Usage: %s [-v] [-m] \n" 32 | " -h\t--help\t\thelp\n" 33 | " -v\t--verbose\tverbose\n" 34 | " -m\t--mute\t\tmuted\n" 35 | " \t\tint 0-100\n", filename); 36 | if (failure) 37 | exit(EXIT_FAILURE); 38 | else 39 | exit(EXIT_SUCCESS); 40 | } 41 | 42 | int main(int argc, const char* argv[]) { 43 | void *options = gopt_sort(&argc, argv, gopt_start( 44 | gopt_option('h', 0, gopt_shorts('h', '?'), gopt_longs("help", "HELP")), 45 | gopt_option('m', 0, gopt_shorts('m'), gopt_longs("mute")), 46 | gopt_option('v', GOPT_REPEAT, gopt_shorts('v'), gopt_longs("verbose")))); 47 | int help = gopt(options, 'h'); 48 | int debug = gopt(options, 'v'); 49 | int muted = gopt(options, 'm'); 50 | gopt_free(options); 51 | 52 | if (help) 53 | print_usage(argv[0], FALSE); 54 | 55 | gint volume; 56 | if (muted) { 57 | if (argc > 2) { 58 | print_usage(argv[0], TRUE); 59 | } else if (argc == 2) { 60 | if (sscanf(argv[1], "%d", &volume) != 1) 61 | print_usage(argv[0], TRUE); 62 | 63 | if (volume > 100 || volume < 0) 64 | print_usage(argv[0], TRUE); 65 | } else { 66 | volume = 0; 67 | } 68 | } else { 69 | if (argc != 2) 70 | print_usage(argv[0], TRUE); 71 | 72 | if (sscanf(argv[1], "%d", &volume) != 1) 73 | print_usage(argv[0], TRUE); 74 | 75 | if (volume > 100 || volume < 0) 76 | print_usage(argv[0], TRUE); 77 | } 78 | 79 | DBusGConnection *bus = NULL; 80 | DBusGProxy *proxy = NULL; 81 | GError *error = NULL; 82 | 83 | // initialize GObject 84 | g_type_init(); 85 | 86 | // connect to D-Bus 87 | print_debug("Connecting to D-Bus...", debug); 88 | bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); 89 | if (error != NULL) 90 | handle_error("Couldn't connect to D-Bus", 91 | error->message, 92 | TRUE); 93 | print_debug_ok(debug); 94 | 95 | // get the proxy 96 | print_debug("Getting proxy...", debug); 97 | proxy = dbus_g_proxy_new_for_name(bus, 98 | VALUE_SERVICE_NAME, 99 | VALUE_SERVICE_OBJECT_PATH, 100 | VALUE_SERVICE_INTERFACE); 101 | if (proxy == NULL) 102 | handle_error("Couldn't get a proxy for D-Bus", 103 | "Unknown(dbus_g_proxy_new_for_name)", 104 | TRUE); 105 | print_debug_ok(debug); 106 | 107 | print_debug("Sending volume...", debug); 108 | uk_ac_cam_db538_VolumeNotification_notify(proxy, volume, muted, &error); 109 | if (error != NULL) { 110 | handle_error("Failed to send notification", error->message, FALSE); 111 | g_clear_error(&error); 112 | return EXIT_FAILURE; 113 | } 114 | print_debug_ok(debug); 115 | 116 | return EXIT_SUCCESS; 117 | } 118 | -------------------------------------------------------------------------------- /src/common.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | * Copyright (C) 2011 David Brazdil 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "common.h" 23 | 24 | void handle_error(const char* msg, const char* reason, gboolean fatal) { 25 | g_printerr("ERROR: %s (%s)\n", msg, reason); 26 | if (fatal) 27 | exit(EXIT_FAILURE); 28 | } 29 | 30 | void print_debug(const gchar *msg, int debug) { 31 | if (debug) 32 | g_print("%s", msg); 33 | } 34 | 35 | void print_debug_ok(int debug) { 36 | if (debug) 37 | g_print(" OK\n"); 38 | } 39 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | * Copyright (C) 2011 David Brazdil 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef INCLUDE_COMMON_DEFS_H 20 | #define INCLUDE_COMMON_DEFS_H 21 | 22 | #define VALUE_SERVICE_NAME "uk.ac.cam.db538.volume-notification" 23 | #define VALUE_SERVICE_OBJECT_PATH "/VolumeNotification" 24 | /* And we're interested in using it through this interface. 25 | This must match the entry in the interface definition XML. */ 26 | #define VALUE_SERVICE_INTERFACE "uk.ac.cam.db538.VolumeNotification" 27 | 28 | void handle_error(const char* msg, const char* reason, gboolean fatal); 29 | void print_debug(const gchar *msg, int debug); 30 | void print_debug_ok(int debug); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/daemon.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | * Copyright (C) 2011 David Brazdil 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "common.h" 25 | #include "gopt.h" 26 | #include "notification.h" 27 | 28 | #define IMAGE_PATH PREFIX 29 | 30 | typedef struct { 31 | GObject parent; 32 | 33 | gint volume; 34 | gboolean muted; 35 | 36 | GtkWindow *notification; 37 | 38 | GdkPixbuf *icon_high; 39 | GdkPixbuf *icon_medium; 40 | GdkPixbuf *icon_low; 41 | GdkPixbuf *icon_off; 42 | GdkPixbuf *icon_muted; 43 | 44 | GdkPixbuf *image_progressbar_empty; 45 | GdkPixbuf *image_progressbar_full; 46 | GdkPixbuf *image_progressbar; 47 | gint width_progressbar; 48 | gint height_progressbar; 49 | 50 | gint time_left; 51 | gint timeout; 52 | gboolean debug; 53 | Settings settings; 54 | } VolumeObject; 55 | 56 | typedef struct { 57 | GObjectClass parent; 58 | } VolumeObjectClass; 59 | 60 | GType volume_object_get_type(void); 61 | gboolean volume_object_notify(VolumeObject* obj, 62 | gint value_in, 63 | gboolean muted, 64 | GError** error); 65 | 66 | #define VOLUME_TYPE_OBJECT \ 67 | (volume_object_get_type()) 68 | #define VOLUME_OBJECT(object) \ 69 | (G_TYPE_CHECK_INSTANCE_CAST ((object), \ 70 | VOLUME_TYPE_OBJECT, VolumeObject)) 71 | #define VOLUME_OBJECT_CLASS(klass) \ 72 | (G_TYPE_CHECK_CLASS_CAST ((klass), \ 73 | VOLUME_TYPE_OBJECT, VolumeObjectClass)) 74 | #define VOLUME_IS_OBJECT(object) \ 75 | (G_TYPE_CHECK_INSTANCE_TYPE ((object), \ 76 | VOLUME_TYPE_OBJECT)) 77 | #define VOLUME_IS_OBJECT_CLASS(klass) \ 78 | (G_TYPE_CHECK_CLASS_TYPE ((klass), \ 79 | VOLUME_TYPE_OBJECT)) 80 | #define VOLUME_OBJECT_GET_CLASS(obj) \ 81 | (G_TYPE_INSTANCE_GET_CLASS ((obj), \ 82 | VOLUME_TYPE_OBJECT, VolumeObjectClass)) 83 | 84 | G_DEFINE_TYPE(VolumeObject, volume_object, G_TYPE_OBJECT) 85 | 86 | #include "value-daemon-stub.h" 87 | 88 | static void volume_object_init(VolumeObject* obj) { 89 | g_assert(obj != NULL); 90 | obj->notification = NULL; 91 | } 92 | 93 | static void volume_object_class_init(VolumeObjectClass* klass) { 94 | g_assert(klass != NULL); 95 | 96 | dbus_g_object_type_install_info(VOLUME_TYPE_OBJECT, 97 | &dbus_glib_volume_object_object_info); 98 | } 99 | 100 | static gboolean 101 | time_handler(VolumeObject *obj) 102 | { 103 | g_assert(obj != NULL); 104 | 105 | obj->time_left--; 106 | 107 | if (obj->time_left <= 0) { 108 | print_debug("Destroying notification...", obj->debug); 109 | destroy_notification(obj->notification); 110 | obj->notification = NULL; 111 | print_debug_ok(obj->debug); 112 | return FALSE; 113 | } 114 | 115 | return TRUE; 116 | } 117 | 118 | gboolean volume_object_notify(VolumeObject* obj, 119 | gint value, 120 | gboolean muted, 121 | GError** error) { 122 | g_assert(obj != NULL); 123 | 124 | if (muted) { 125 | obj->muted = TRUE; 126 | } else { 127 | obj->muted = FALSE; 128 | } 129 | obj->volume = (value > 100) ? 100 : value; 130 | 131 | if (obj->notification == NULL) { 132 | print_debug("Creating new notification...", obj->debug); 133 | obj->notification = create_notification(obj->settings); 134 | gtk_widget_realize(GTK_WIDGET(obj->notification)); 135 | g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) obj); 136 | print_debug_ok(obj->debug); 137 | } 138 | 139 | // choose icon 140 | if (obj->muted) 141 | set_notification_icon(GTK_WINDOW(obj->notification), obj->icon_muted); 142 | else if (obj->volume >= 75) 143 | set_notification_icon(GTK_WINDOW(obj->notification), obj->icon_high); 144 | else if (obj->volume >= 50) 145 | set_notification_icon(GTK_WINDOW(obj->notification), obj->icon_medium); 146 | else if (obj->volume >= 25) 147 | set_notification_icon(GTK_WINDOW(obj->notification), obj->icon_low); 148 | else 149 | set_notification_icon(GTK_WINDOW(obj->notification), obj->icon_off); 150 | 151 | // prepare and set progress bar 152 | gint width_full = obj->width_progressbar * obj->volume / 100; 153 | gdk_pixbuf_copy_area(obj->image_progressbar_full, 0, 0, width_full, obj->height_progressbar, 154 | obj->image_progressbar, 0, 0); 155 | gdk_pixbuf_copy_area(obj->image_progressbar_empty, width_full, 0, obj->width_progressbar - width_full, obj->height_progressbar, 156 | obj->image_progressbar, width_full, 0); 157 | set_progressbar_image(GTK_WINDOW(obj->notification), obj->image_progressbar); 158 | 159 | obj->time_left = obj->timeout; 160 | gtk_widget_show_all(GTK_WIDGET(obj->notification)); 161 | 162 | return TRUE; 163 | } 164 | 165 | static void print_usage(const char* filename, int failure) { 166 | Settings settings = get_default_settings(); 167 | g_print("Usage: %s [arguments]\n" 168 | " -h\t\t--help\t\t\thelp\n" 169 | " -v\t\t--verbose\t\tverbose\n" 170 | " -n\t\t--no-daemon\t\tdo not daemonize\n" 171 | "\n" 172 | "Configuration:\n" 173 | " -t \t--timeout \t\tnotification timeout in seconds\n" 174 | " -a \t--alpha \t\ttransparency level (0.0 - 1.0, default %.2f)\n" 175 | " -r \t--corner-radius \tradius of the round corners in pixels (default %d)\n" 176 | , filename, settings.alpha, settings.corner_radius); 177 | if (failure) 178 | exit(EXIT_FAILURE); 179 | else 180 | exit(EXIT_SUCCESS); 181 | } 182 | 183 | int main(int argc, char* argv[]) { 184 | Settings settings = get_default_settings(); 185 | int timeout = 3; 186 | 187 | void *options = gopt_sort(&argc, (const char**) argv, gopt_start( 188 | gopt_option('h', 0, gopt_shorts('h', '?'), gopt_longs("help", "HELP")), 189 | gopt_option('n', 0, gopt_shorts('n'), gopt_longs("no-daemon")), 190 | gopt_option('t', GOPT_ARG, gopt_shorts('t'), gopt_longs("timeout")), 191 | gopt_option('a', GOPT_ARG, gopt_shorts('a'), gopt_longs("alpha")), 192 | gopt_option('r', GOPT_ARG, gopt_shorts('r'), gopt_longs("corner-radius")), 193 | gopt_option('v', GOPT_REPEAT, gopt_shorts('v'), gopt_longs("verbose")))); 194 | 195 | int help = gopt(options, 'h'); 196 | int debug = gopt(options, 'v'); 197 | int no_daemon = gopt(options, 'n'); 198 | 199 | if (gopt(options, 't')) { 200 | if (sscanf(gopt_arg_i(options, 't', 0), "%d", &timeout) != 1) 201 | print_usage(argv[0], TRUE); 202 | } 203 | 204 | if (gopt(options, 'a')) { 205 | if (sscanf(gopt_arg_i(options, 'a', 0), "%f", &settings.alpha) != 1 || settings.alpha < 0.0f || settings.alpha > 1.0f) 206 | print_usage(argv[0], TRUE); 207 | } 208 | 209 | if (gopt(options, 'r')) { 210 | if (sscanf(gopt_arg_i(options, 'r', 0), "%d", &settings.corner_radius) != 1) 211 | print_usage(argv[0], TRUE); 212 | } 213 | 214 | gopt_free(options); 215 | 216 | if (help) 217 | print_usage(argv[0], FALSE); 218 | 219 | DBusGConnection *bus = NULL; 220 | DBusGProxy *bus_proxy = NULL; 221 | VolumeObject *status = NULL; 222 | GMainLoop *main_loop = NULL; 223 | GError *error = NULL; 224 | guint result; 225 | 226 | // initialize GObject and GTK 227 | g_type_init(); 228 | g_log_set_always_fatal(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); 229 | gtk_init(&argc, &argv); 230 | 231 | // create main loop 232 | main_loop = g_main_loop_new(NULL, FALSE); 233 | if (main_loop == NULL) 234 | handle_error("Couldn't create GMainLoop", "Unknown(OOM?)", TRUE); 235 | 236 | // connect to D-Bus 237 | print_debug("Connecting to D-Bus...", debug); 238 | bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); 239 | if (error != NULL) 240 | handle_error("Couldn't connect to D-Bus", 241 | error->message, 242 | TRUE); 243 | print_debug_ok(debug); 244 | 245 | // get the proxy 246 | print_debug("Getting proxy...", debug); 247 | bus_proxy = dbus_g_proxy_new_for_name(bus, 248 | DBUS_SERVICE_DBUS, 249 | DBUS_PATH_DBUS, 250 | DBUS_INTERFACE_DBUS); 251 | if (bus_proxy == NULL) 252 | handle_error("Couldn't get a proxy for D-Bus", 253 | "Unknown(dbus_g_proxy_new_for_name)", 254 | TRUE); 255 | print_debug_ok(debug); 256 | 257 | // register the service 258 | print_debug("Registering the service...", debug); 259 | if (!dbus_g_proxy_call(bus_proxy, 260 | "RequestName", 261 | &error, 262 | 263 | G_TYPE_STRING, 264 | VALUE_SERVICE_NAME, 265 | G_TYPE_UINT, 266 | 0, 267 | G_TYPE_INVALID, 268 | 269 | G_TYPE_UINT, 270 | &result, 271 | G_TYPE_INVALID)) 272 | handle_error("D-Bus.RequestName RPC failed", 273 | error->message, 274 | TRUE); 275 | if (result != 1) 276 | handle_error("Failed to get the primary well-known name.", 277 | "RequestName result != 1", TRUE); 278 | print_debug_ok(debug); 279 | 280 | // create the Volume object 281 | print_debug("Preparing data...", debug); 282 | status = g_object_new(VOLUME_TYPE_OBJECT, NULL); 283 | if (status == NULL) 284 | handle_error("Failed to create one VolumeObject instance.", 285 | "Unknown(OOM?)", TRUE); 286 | 287 | status->debug = debug; 288 | status->timeout = timeout; 289 | status->settings = settings; 290 | 291 | // volume icons 292 | status->icon_high = gdk_pixbuf_new_from_file(IMAGE_PATH "volume_high.svg", &error); 293 | if (error != NULL) 294 | handle_error("Couldn't load volume_high.svg.", error->message, TRUE); 295 | status->icon_medium = gdk_pixbuf_new_from_file(IMAGE_PATH "volume_medium.svg", &error); 296 | if (error != NULL) 297 | handle_error("Couldn't load volume_medium.svg.", error->message, TRUE); 298 | status->icon_low = gdk_pixbuf_new_from_file(IMAGE_PATH "volume_low.svg", &error); 299 | if (error != NULL) 300 | handle_error("Couldn't load volume_low.svg.", error->message, TRUE); 301 | status->icon_off = gdk_pixbuf_new_from_file(IMAGE_PATH "volume_off.svg", &error); 302 | if (error != NULL) 303 | handle_error("Couldn't load volume_off.svg.", error->message, TRUE); 304 | status->icon_muted = gdk_pixbuf_new_from_file(IMAGE_PATH "volume_muted.svg", &error); 305 | if (error != NULL) 306 | handle_error("Couldn't load volume_muted.svg.", error->message, TRUE); 307 | 308 | // progress bar 309 | status->image_progressbar_empty = gdk_pixbuf_new_from_file(IMAGE_PATH "progressbar_empty.png", &error); 310 | if (error != NULL) 311 | handle_error("Couldn't load progressbar_empty.png.", error->message, TRUE); 312 | status->image_progressbar_full = gdk_pixbuf_new_from_file(IMAGE_PATH "progressbar_full.png", &error); 313 | if (error != NULL) 314 | handle_error("Couldn't load progressbar_full.png.", error->message, TRUE); 315 | 316 | // check that the images are of the same size 317 | if (gdk_pixbuf_get_width(status->image_progressbar_empty) != gdk_pixbuf_get_width(status->image_progressbar_full) || 318 | gdk_pixbuf_get_height(status->image_progressbar_empty) != gdk_pixbuf_get_height(status->image_progressbar_full) || 319 | gdk_pixbuf_get_bits_per_sample(status->image_progressbar_empty) != gdk_pixbuf_get_bits_per_sample(status->image_progressbar_full)) 320 | handle_error("Progress bar images aren't of the same size or don't have the same number of bits per sample.", "Unknown(OOM?)", TRUE); 321 | 322 | // create pixbuf for combined image 323 | status->width_progressbar = gdk_pixbuf_get_width(status->image_progressbar_empty); 324 | status->height_progressbar = gdk_pixbuf_get_height(status->image_progressbar_empty); 325 | status->image_progressbar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 326 | TRUE, 327 | gdk_pixbuf_get_bits_per_sample(status->image_progressbar_empty), 328 | status->width_progressbar, 329 | status->height_progressbar); 330 | 331 | print_debug_ok(debug); 332 | 333 | // register the Volume object 334 | print_debug("Registering volume object...", debug); 335 | dbus_g_connection_register_g_object(bus, 336 | VALUE_SERVICE_OBJECT_PATH, 337 | G_OBJECT(status)); 338 | print_debug_ok(debug); 339 | 340 | // daemonize 341 | if (!no_daemon) { 342 | print_debug("Daemonizing...\n", debug); 343 | if (daemon(0, 0) != 0) 344 | handle_error("failed to daemonize", "unknown", FALSE); 345 | } 346 | 347 | // Run forever 348 | print_debug("Running the main loop...\n", debug); 349 | g_main_loop_run(main_loop); 350 | return EXIT_FAILURE; 351 | } 352 | -------------------------------------------------------------------------------- /src/gopt.c: -------------------------------------------------------------------------------- 1 | /* gopt.c version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */ 2 | /* 3 | I, Tom Vajzovic, am the author of this software and its documentation and 4 | permanently abandon all copyright and other intellectual property rights in 5 | them, including the right to be identified as the author. 6 | 7 | I am fairly certain that this software does what the documentation says it 8 | does, but I cannot guarantee that it does, or that it does what you think it 9 | should, and I cannot guarantee that it will not have undesirable side effects. 10 | 11 | You are free to use, modify and distribute this software as you please, but 12 | you do so at your own risk. If you remove or hide this warning then you are 13 | responsible for any problems encountered by people that you make the software 14 | available to. 15 | 16 | Before modifying or distributing this software I ask that you would please 17 | read http://www.purposeful.co.uk/tfl/ 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include "gopt.h" 24 | 25 | #ifdef USE_SYSEXITS 26 | #include 27 | #else 28 | #define EX_OSERR EXIT_FAILURE 29 | #define EX_USAGE EXIT_FAILURE 30 | #endif 31 | 32 | struct opt_spec_s { 33 | int key; 34 | int flags; 35 | const char *shorts; 36 | const char* const *longs; 37 | }; 38 | typedef struct opt_spec_s opt_spec_t; 39 | 40 | struct opt_s { 41 | int key; 42 | const char *arg; 43 | }; 44 | typedef struct opt_s opt_t; 45 | 46 | void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){ 47 | void *opts; 48 | {{{ 49 | const char* const *arg_p= argv + 1; 50 | size_t opt_count= 1; 51 | for( ; *arg_p; ++arg_p ) 52 | if( '-' == (*arg_p)[0] && (*arg_p)[1] ) 53 | if( '-' == (*arg_p)[1] ) 54 | if( (*arg_p)[2] ) 55 | ++opt_count; 56 | else 57 | break; 58 | else { 59 | const opt_spec_t *opt_spec_p= opt_specs; 60 | for( ; opt_spec_p-> key; ++opt_spec_p ) 61 | if( strchr( opt_spec_p-> shorts, (*arg_p)[1] )){ 62 | opt_count+= opt_spec_p-> flags & GOPT_ARG ? 1 : strlen( (*arg_p) + 1 ); 63 | break; 64 | } 65 | } 66 | opts= malloc( opt_count * sizeof(opt_t) ); 67 | }}} 68 | { 69 | const char **arg_p= argv + 1; 70 | const char **next_operand= arg_p; 71 | opt_t *next_option= opts; 72 | 73 | if( ! opts ){ 74 | perror( argv[0] ); 75 | exit( EX_OSERR ); 76 | } 77 | for( ; *arg_p; ++arg_p ) 78 | if( '-' == (*arg_p)[0] && (*arg_p)[1] ) 79 | if( '-' == (*arg_p)[1] ) 80 | if( (*arg_p)[2] ) 81 | {{{ 82 | const opt_spec_t *opt_spec_p= opt_specs; 83 | const char* const *longs= opt_spec_p-> longs; 84 | next_option-> key= 0; 85 | while( *longs ){ 86 | const char *option_cp= (*arg_p) + 2; 87 | const char *name_cp= *longs; 88 | while( *option_cp && *option_cp == *name_cp ){ 89 | ++option_cp; 90 | ++name_cp; 91 | } 92 | if( '=' == *option_cp || !*option_cp ){ 93 | if( *name_cp ){ 94 | if( next_option-> key ){ 95 | fprintf( stderr, "%s: --%.*s: abbreviated option is ambiguous\n", argv[0], (int)( option_cp -( (*arg_p) + 2 )), (*arg_p) + 2 ); 96 | free( opts ); 97 | exit( EX_USAGE ); 98 | } 99 | next_option-> key= opt_spec_p-> key; 100 | } 101 | else { 102 | next_option-> key= opt_spec_p-> key; 103 | goto found_long; 104 | } 105 | } 106 | if( !*++longs ){ 107 | ++opt_spec_p; 108 | if( opt_spec_p-> key ) 109 | longs= opt_spec_p-> longs; 110 | } 111 | } 112 | if( ! next_option-> key ){ 113 | fprintf( stderr, "%s: --%.*s: unknown option\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); 114 | free( opts ); 115 | exit( EX_USAGE ); 116 | } 117 | for( opt_spec_p= opt_specs; opt_spec_p-> key != next_option-> key; ++opt_spec_p ); 118 | found_long: 119 | 120 | if( !( opt_spec_p-> flags & GOPT_REPEAT )){ 121 | const opt_t *opt_p= opts; 122 | for( ; opt_p != next_option; ++opt_p ) 123 | if( opt_p-> key == opt_spec_p-> key ){ 124 | fprintf( stderr, "%s: --%.*s: option may not be repeated (in any long or short form)\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); 125 | free( opts ); 126 | exit( EX_USAGE ); 127 | } 128 | } 129 | if( opt_spec_p-> flags & GOPT_ARG ){ 130 | next_option-> arg= strchr( (*arg_p) + 2, '=' ) + 1; 131 | if( (char*)0 + 1 == next_option-> arg ){ 132 | ++arg_p; 133 | if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){ 134 | fprintf( stderr, "%s: --%s: option requires an option argument\n", argv[0], (*(arg_p-1)) + 2 ); 135 | free( opts ); 136 | exit( EX_USAGE ); 137 | } 138 | next_option-> arg= *arg_p; 139 | } 140 | } 141 | else { 142 | if( strchr( (*arg_p) + 2, '=' )){ 143 | fprintf( stderr, "%s: --%.*s: option may not take an option argument\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 ); 144 | free( opts ); 145 | exit( EX_USAGE ); 146 | } 147 | next_option-> arg= NULL; 148 | } 149 | ++next_option; 150 | }}} 151 | else { 152 | for( ++arg_p; *arg_p; ++arg_p ) 153 | *next_operand++= *arg_p; 154 | break; 155 | } 156 | else 157 | {{{ 158 | const char *short_opt= (*arg_p) + 1; 159 | for( ;*short_opt; ++short_opt ){ 160 | const opt_spec_t *opt_spec_p= opt_specs; 161 | 162 | for( ; opt_spec_p-> key; ++opt_spec_p ) 163 | if( strchr( opt_spec_p-> shorts, *short_opt )){ 164 | if( !( opt_spec_p-> flags & GOPT_REPEAT )){ 165 | const opt_t *opt_p= opts; 166 | for( ; opt_p != next_option; ++opt_p ) 167 | if( opt_p-> key == opt_spec_p-> key ){ 168 | fprintf( stderr, "%s: -%c: option may not be repeated (in any long or short form)\n", argv[0], *short_opt ); 169 | free( opts ); 170 | exit( EX_USAGE ); 171 | } 172 | } 173 | next_option-> key= opt_spec_p-> key; 174 | 175 | if( opt_spec_p-> flags & GOPT_ARG ){ 176 | if( short_opt[1] ) 177 | next_option-> arg= short_opt + 1; 178 | 179 | else { 180 | ++arg_p; 181 | if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){ 182 | fprintf( stderr, "%s: -%c: option requires an option argument\n", argv[0], *short_opt ); 183 | free( opts ); 184 | exit( EX_USAGE ); 185 | } 186 | next_option-> arg= *arg_p; 187 | } 188 | ++next_option; 189 | goto break_2; 190 | } 191 | next_option-> arg= NULL; 192 | ++next_option; 193 | goto continue_2; 194 | } 195 | fprintf( stderr, "%s: -%c: unknown option\n", argv[0], *short_opt ); 196 | free( opts ); 197 | exit( EX_USAGE ); 198 | continue_2: 0; 199 | } 200 | break_2: 0; 201 | }}} 202 | else 203 | *next_operand++= *arg_p; 204 | 205 | next_option-> key= 0; 206 | *next_operand= NULL; 207 | *argc= next_operand - argv; 208 | } 209 | return opts; 210 | } 211 | 212 | size_t gopt( const void *vptr_opts, int key ){ 213 | const opt_t *opts= vptr_opts; 214 | size_t count= 0; 215 | for( ; opts-> key; ++opts ) 216 | count+= opts-> key == key; 217 | 218 | return count; 219 | } 220 | 221 | size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){ 222 | const opt_t *opts= vptr_opts; 223 | size_t count= 0; 224 | 225 | for( ; opts-> key; ++opts ) 226 | if( opts-> key == key ){ 227 | if( ! count ) 228 | *arg= opts-> arg; 229 | ++count; 230 | } 231 | return count; 232 | } 233 | 234 | const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){ 235 | const opt_t *opts= vptr_opts; 236 | 237 | for( ; opts-> key; ++opts ) 238 | if( opts-> key == key ){ 239 | if( ! i ) 240 | return opts-> arg; 241 | --i; 242 | } 243 | return NULL; 244 | } 245 | 246 | size_t gopt_args( const void *vptr_opts, int key, const char **args, size_t args_len ){ 247 | const char **args_stop= args + args_len; 248 | const char **args_ptr= args; 249 | const opt_t *opts= vptr_opts; 250 | 251 | for( ; opts-> key; ++opts ) 252 | if( opts-> key == key ){ 253 | if( args_stop == args_ptr ) 254 | return args_len + gopt( opts, key ); 255 | 256 | *args_ptr++= opts-> arg; 257 | } 258 | if( args_stop != args_ptr ) 259 | *args_ptr= NULL; 260 | return args_ptr - args; 261 | } 262 | 263 | void gopt_free( void *vptr_opts ){ 264 | free( vptr_opts ); 265 | } 266 | -------------------------------------------------------------------------------- /src/gopt.h: -------------------------------------------------------------------------------- 1 | /* gopt.h version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */ 2 | /* 3 | I, Tom Vajzovic, am the author of this software and its documentation and 4 | permanently abandon all copyright and other intellectual property rights in 5 | them, including the right to be identified as the author. 6 | 7 | I am fairly certain that this software does what the documentation says it 8 | does, but I cannot guarantee that it does, or that it does what you think it 9 | should, and I cannot guarantee that it will not have undesirable side effects. 10 | 11 | You are free to use, modify and distribute this software as you please, but 12 | you do so at your own risk. If you remove or hide this warning then you are 13 | responsible for any problems encountered by people that you make the software 14 | available to. 15 | 16 | Before modifying or distributing this software I ask that you would please 17 | read http://www.purposeful.co.uk/tfl/ 18 | */ 19 | 20 | #ifndef GOPT_H_INCLUDED 21 | #define GOPT_H_INCLUDED 22 | 23 | #define GOPT_ONCE 0 24 | #define GOPT_REPEAT 1 25 | #define GOPT_NOARG 0 26 | #define GOPT_ARG 2 27 | 28 | #define gopt_start(...) (const void*)( const struct { int k; int f; const char *s; const char*const*l; }[]){ __VA_ARGS__, {0}} 29 | #define gopt_option(k,f,s,l) { k, f, s, l } 30 | #define gopt_shorts( ... ) (const char*)(const char[]){ __VA_ARGS__, 0 } 31 | #define gopt_longs( ... ) (const char**)(const char*[]){ __VA_ARGS__, NULL } 32 | 33 | void *gopt_sort( int *argc, const char **argv, const void *opt_specs ); 34 | /* returns a pointer for use in the following calls 35 | * prints to stderr and call exit() on error 36 | */ 37 | size_t gopt( const void *opts, int key ); 38 | /* returns the number of times the option was specified 39 | * which will be 0 or 1 unless GOPT_REPEAT was used 40 | */ 41 | size_t gopt_arg( const void *opts, int key, const char **arg ); 42 | /* returns the number of times the option was specified 43 | * writes a pointer to the option argument from the first (or only) occurance to *arg 44 | */ 45 | const char *gopt_arg_i( const void *opts, int key, size_t i ); 46 | /* returns a pointer to the ith (starting at zero) occurance 47 | * of the option, or NULL if it was not specified that many times 48 | */ 49 | size_t gopt_args( const void *opts, int key, const char **args, size_t args_len ); 50 | /* returns the number of times the option was specified 51 | * writes pointers to the option arguments in the order of occurance to args[]. 52 | * writes at most args_len pointers 53 | * if the return value is less than args_len, also writes a null pointer 54 | */ 55 | void gopt_free( void *opts ); 56 | /* releases memory allocated in the corresponding call to gopt_sort() 57 | * opts can no longer be used 58 | */ 59 | #endif /* GOPT_H_INCLUDED */ 60 | -------------------------------------------------------------------------------- /src/notification.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | 4 | * Copyright (C) 2006-2007 Christian Hammond 5 | * Copyright (C) 2009 Red Hat, Inc. 6 | * Copyright (C) 2011 David Brazdil 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "notification.h" 23 | 24 | #define USE_COMPOSITE 25 | 26 | #define WIDTH 400 27 | #define DEFAULT_X0 0 28 | #define DEFAULT_Y0 0 29 | #define DEFAULT_RADIUS 30 30 | #define DEFAULT_BORDER (DEFAULT_RADIUS * 3 / 2) 31 | 32 | #define IMAGE_SIZE 110 33 | #define IMAGE_PADDING (IMAGE_SIZE / 3) 34 | #define BODY_X_OFFSET (IMAGE_SIZE + 8) 35 | #define MAX_ICON_SIZE IMAGE_SIZE 36 | #define MAX_PROGRESSBAR_SIZE (IMAGE_SIZE * 18 / 10) 37 | 38 | typedef struct { 39 | GtkWidget *win; 40 | GtkWidget *main_vbox; 41 | GtkWidget *iconbox; 42 | GtkWidget *icon; 43 | GtkWidget *progressbarbox; 44 | GtkWidget *progressbar; 45 | 46 | int width; 47 | int height; 48 | int last_width; 49 | int last_height; 50 | 51 | gboolean composited; 52 | Settings settings; 53 | } WindowData; 54 | 55 | Settings 56 | get_default_settings() { 57 | Settings settings; 58 | settings.alpha = 0.5f; 59 | settings.corner_radius = 30; 60 | return settings; 61 | } 62 | 63 | static void 64 | color_reverse(const GdkColor *a, GdkColor *b) { 65 | gdouble red; 66 | gdouble green; 67 | gdouble blue; 68 | gdouble h; 69 | gdouble s; 70 | gdouble v; 71 | 72 | red = (gdouble) a->red / 65535.0; 73 | green = (gdouble) a->green / 65535.0; 74 | blue = (gdouble) a->blue / 65535.0; 75 | 76 | gtk_rgb_to_hsv (red, green, blue, &h, &s, &v); 77 | 78 | /* pivot brightness around the center */ 79 | v = 0.5 + (0.5 - v); 80 | if (v > 1.0) 81 | v = 1.0; 82 | else if (v < 0.0) 83 | v = 0.0; 84 | 85 | /* reduce saturation by 50% */ 86 | s *= 0.5; 87 | 88 | gtk_hsv_to_rgb (h, s, v, &red, &green, &blue); 89 | 90 | b->red = red * 65535.0; 91 | b->green = green * 65535.0; 92 | b->blue = blue * 65535.0; 93 | } 94 | 95 | static GdkPixbuf * 96 | scale_pixbuf (GdkPixbuf *pixbuf, 97 | int max_width, 98 | int max_height, 99 | gboolean no_stretch_hint) 100 | { 101 | int pw; 102 | int ph; 103 | float scale_factor_x = 1.0; 104 | float scale_factor_y = 1.0; 105 | float scale_factor = 1.0; 106 | 107 | pw = gdk_pixbuf_get_width (pixbuf); 108 | ph = gdk_pixbuf_get_height (pixbuf); 109 | 110 | /* Determine which dimension requires the smallest scale. */ 111 | scale_factor_x = (float) max_width / (float) pw; 112 | scale_factor_y = (float) max_height / (float) ph; 113 | 114 | if (scale_factor_x > scale_factor_y) { 115 | scale_factor = scale_factor_y; 116 | } else { 117 | scale_factor = scale_factor_x; 118 | } 119 | 120 | /* always scale down, allow to disable scaling up */ 121 | if (scale_factor < 1.0 || !no_stretch_hint) { 122 | int scale_x; 123 | int scale_y; 124 | 125 | scale_x = (int) (pw * scale_factor); 126 | scale_y = (int) (ph * scale_factor); 127 | return gdk_pixbuf_scale_simple (pixbuf, 128 | scale_x, 129 | scale_y, 130 | GDK_INTERP_BILINEAR); 131 | } else { 132 | return g_object_ref (pixbuf); 133 | } 134 | } 135 | 136 | static void 137 | draw_round_rect(cairo_t* cr, 138 | gdouble aspect, 139 | gdouble x, 140 | gdouble y, 141 | gdouble corner_radius, 142 | gdouble width, 143 | gdouble height) { 144 | gdouble radius = corner_radius / aspect; 145 | 146 | cairo_move_to (cr, x + radius, y); 147 | 148 | // top-right, left of the corner 149 | cairo_line_to (cr, 150 | x + width - radius, 151 | y); 152 | 153 | // top-right, below the corner 154 | cairo_arc (cr, 155 | x + width - radius, 156 | y + radius, 157 | radius, 158 | -90.0f * G_PI / 180.0f, 159 | 0.0f * G_PI / 180.0f); 160 | 161 | // bottom-right, above the corner 162 | cairo_line_to (cr, 163 | x + width, 164 | y + height - radius); 165 | 166 | // bottom-right, left of the corner 167 | cairo_arc (cr, 168 | x + width - radius, 169 | y + height - radius, 170 | radius, 171 | 0.0f * G_PI / 180.0f, 172 | 90.0f * G_PI / 180.0f); 173 | 174 | // bottom-left, right of the corner 175 | cairo_line_to (cr, 176 | x + radius, 177 | y + height); 178 | 179 | // bottom-left, above the corner 180 | cairo_arc (cr, 181 | x + radius, 182 | y + height - radius, 183 | radius, 184 | 90.0f * G_PI / 180.0f, 185 | 180.0f * G_PI / 180.0f); 186 | 187 | // top-left, below the corner 188 | cairo_line_to (cr, 189 | x, 190 | y + radius); 191 | 192 | // top-left, right of the corner 193 | cairo_arc (cr, 194 | x + radius, 195 | y + radius, 196 | radius, 197 | 180.0f * G_PI / 180.0f, 198 | 270.0f * G_PI / 180.0f); 199 | } 200 | 201 | static void 202 | fill_background(GtkWidget *widget, WindowData *windata, cairo_t *cr) { 203 | GdkColor color; 204 | double r, g, b; 205 | 206 | draw_round_rect (cr, 207 | 1.0f, 208 | DEFAULT_X0 + 1, 209 | DEFAULT_Y0 + 1, 210 | windata->settings.corner_radius, 211 | widget->allocation.width - 2, 212 | widget->allocation.height - 2); 213 | 214 | color = widget->style->bg [GTK_STATE_NORMAL]; 215 | r = (float)color.red / 65535.0; 216 | g = (float)color.green / 65535.0; 217 | b = (float)color.blue / 65535.0; 218 | cairo_set_source_rgba (cr, r, g, b, windata->settings.alpha); 219 | cairo_fill_preserve (cr); 220 | 221 | // border 222 | // color = widget->style->text_aa [GTK_STATE_NORMAL]; 223 | // r = (float) color.red / 65535.0; 224 | // g = (float) color.green / 65535.0; 225 | // b = (float) color.blue / 65535.0; 226 | // cairo_set_source_rgba (cr, r, g, b, BACKGROUND_ALPHA / 2); 227 | // cairo_set_line_width (cr, 1); 228 | // cairo_stroke (cr); 229 | } 230 | 231 | static void 232 | update_shape(WindowData *windata) { 233 | GdkBitmap *mask; 234 | cairo_t *cr; 235 | 236 | if (windata->width == windata->last_width 237 | && windata->height == windata->last_height) { 238 | return; 239 | } 240 | 241 | if (windata->width == 0 || windata->height == 0) { 242 | windata->width = MAX(windata->win->allocation.width, 1); 243 | windata->height = MAX(windata->win->allocation.height, 1); 244 | } 245 | 246 | if (windata->composited) { 247 | gtk_widget_shape_combine_mask (windata->win, NULL, 0, 0); 248 | return; 249 | } 250 | 251 | windata->last_width = windata->width; 252 | windata->last_height = windata->height; 253 | mask = (GdkBitmap *) gdk_pixmap_new (NULL, 254 | windata->width, 255 | windata->height, 256 | 1); 257 | if (mask == NULL) { 258 | return; 259 | } 260 | 261 | cr = gdk_cairo_create (mask); 262 | if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) { 263 | cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); 264 | cairo_paint (cr); 265 | 266 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); 267 | cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f); 268 | draw_round_rect (cr, 269 | 1.0f, 270 | DEFAULT_X0, 271 | DEFAULT_Y0, 272 | windata->settings.corner_radius, 273 | windata->width, 274 | windata->height); 275 | cairo_fill (cr); 276 | 277 | gtk_widget_shape_combine_mask (windata->win, mask, 0, 0); 278 | } 279 | cairo_destroy (cr); 280 | 281 | g_object_unref (mask); 282 | } 283 | 284 | 285 | static void 286 | paint_window(GtkWidget *widget, WindowData *windata) { 287 | cairo_t *context; 288 | cairo_surface_t *surface; 289 | cairo_t *cr; 290 | 291 | if (windata->width == 0 || windata->height == 0) { 292 | windata->width = MAX (windata->win->allocation.width, 1); 293 | windata->height = MAX (windata->win->allocation.height, 1); 294 | } 295 | 296 | context = gdk_cairo_create (widget->window); 297 | 298 | cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); 299 | surface = cairo_surface_create_similar (cairo_get_target (context), 300 | CAIRO_CONTENT_COLOR_ALPHA, 301 | widget->allocation.width, 302 | widget->allocation.height); 303 | cr = cairo_create (surface); 304 | 305 | fill_background (widget, windata, cr); 306 | 307 | cairo_destroy (cr); 308 | cairo_set_source_surface (context, surface, 0, 0); 309 | cairo_paint (context); 310 | cairo_surface_destroy (surface); 311 | cairo_destroy (context); 312 | 313 | update_shape (windata); 314 | } 315 | 316 | static void 317 | override_style(GtkWidget *widget, GtkStyle *previous_style) { 318 | GtkStateType state; 319 | GtkStyle *style; 320 | GdkColor fg; 321 | GdkColor bg; 322 | 323 | style = gtk_style_copy (widget->style); 324 | if (previous_style == NULL 325 | || (previous_style != NULL 326 | && (previous_style->bg[GTK_STATE_NORMAL].red != style->bg[GTK_STATE_NORMAL].red 327 | || previous_style->bg[GTK_STATE_NORMAL].green != style->bg[GTK_STATE_NORMAL].green 328 | || previous_style->bg[GTK_STATE_NORMAL].blue != style->bg[GTK_STATE_NORMAL].blue))) { 329 | 330 | state = (GtkStateType) 0; 331 | while (state < (GtkStateType) G_N_ELEMENTS (widget->style->bg)) { 332 | color_reverse (&style->bg[state], &bg); 333 | gtk_widget_modify_bg (widget, state, &bg); 334 | state++; 335 | } 336 | 337 | } 338 | 339 | if (previous_style == NULL 340 | || (previous_style != NULL 341 | && (previous_style->fg[GTK_STATE_NORMAL].red != style->fg[GTK_STATE_NORMAL].red 342 | || previous_style->fg[GTK_STATE_NORMAL].green != style->fg[GTK_STATE_NORMAL].green 343 | || previous_style->fg[GTK_STATE_NORMAL].blue != style->fg[GTK_STATE_NORMAL].blue))) { 344 | 345 | state = (GtkStateType) 0; 346 | while (state < (GtkStateType) G_N_ELEMENTS (widget->style->fg)) { 347 | color_reverse (&style->fg[state], &fg); 348 | gtk_widget_modify_fg (widget, state, &fg); 349 | state++; 350 | } 351 | } 352 | 353 | g_object_unref (style); 354 | } 355 | 356 | static void 357 | destroy_windata(WindowData *windata) { 358 | g_free (windata); 359 | } 360 | 361 | static gboolean 362 | on_configure_event(GtkWidget *widget, GdkEventConfigure *event, WindowData *windata) { 363 | windata->width = event->width; 364 | windata->height = event->height; 365 | 366 | gtk_widget_queue_draw(widget); 367 | 368 | return FALSE; 369 | } 370 | 371 | static void 372 | on_style_set(GtkWidget *widget, GtkStyle *previous_style, WindowData *windata) { 373 | g_signal_handlers_block_by_func (G_OBJECT(widget), on_style_set, windata); 374 | override_style (widget, previous_style); 375 | 376 | gtk_widget_queue_draw (widget); 377 | 378 | g_signal_handlers_unblock_by_func (G_OBJECT(widget), on_style_set, windata); 379 | } 380 | 381 | static void 382 | on_composited_changed(GtkWidget *window, WindowData *windata) { 383 | windata->composited = gdk_screen_is_composited (gtk_widget_get_screen (window)); 384 | update_shape(windata); 385 | } 386 | 387 | static void 388 | on_window_realize(GtkWidget *widget, WindowData *windata) { 389 | } 390 | 391 | static gboolean 392 | on_window_expose (GtkWidget *widget, GdkEventExpose *event, WindowData *windata) { 393 | paint_window (widget, windata); 394 | return FALSE; 395 | } 396 | 397 | static gboolean 398 | on_window_map (GtkWidget *widget, GdkEvent *event, WindowData *windata) { 399 | return FALSE; 400 | } 401 | 402 | GtkWindow* create_notification(Settings settings) { 403 | WindowData *windata; 404 | 405 | GtkWidget *win; 406 | 407 | #ifdef USE_COMPOSITE 408 | GdkColormap *colormap; 409 | GdkScreen *screen; 410 | #endif 411 | 412 | // create WindowData object 413 | windata = g_new0(WindowData, 1); 414 | 415 | // create GTK window 416 | win = gtk_window_new(GTK_WINDOW_POPUP); 417 | gtk_window_set_resizable(GTK_WINDOW (win), FALSE); 418 | gtk_widget_set_app_paintable(win, TRUE); 419 | windata->win = win; 420 | windata->settings = settings; 421 | 422 | // connect signals 423 | g_signal_connect (G_OBJECT (win), 424 | "style-set", 425 | G_CALLBACK (on_style_set), 426 | windata); 427 | g_signal_connect (G_OBJECT (win), 428 | "map-event", 429 | G_CALLBACK (on_window_map), 430 | windata); 431 | g_signal_connect (G_OBJECT (win), 432 | "expose-event", 433 | G_CALLBACK (on_window_expose), 434 | windata); 435 | g_signal_connect (G_OBJECT (win), 436 | "realize", 437 | G_CALLBACK (on_window_realize), 438 | windata); 439 | 440 | // prepare composite 441 | windata->composited = FALSE; 442 | #ifdef USE_COMPOSITE 443 | screen = gtk_window_get_screen (GTK_WINDOW (win)); 444 | colormap = gdk_screen_get_rgba_colormap (screen); 445 | if (colormap != NULL) { 446 | gtk_widget_set_colormap (win, colormap); 447 | if (gdk_screen_is_composited (screen)) { 448 | windata->composited = TRUE; 449 | } 450 | } 451 | g_signal_connect(win, 452 | "composited-changed", 453 | G_CALLBACK (on_composited_changed), 454 | windata); 455 | #endif 456 | 457 | gtk_window_set_title(GTK_WINDOW (win), "Notification"); 458 | gtk_window_set_type_hint(GTK_WINDOW (win), 459 | GDK_WINDOW_TYPE_HINT_NOTIFICATION); 460 | gtk_window_set_default_size(GTK_WINDOW(win), 400, 400); 461 | gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER); 462 | 463 | g_object_set_data_full (G_OBJECT (win), 464 | "windata", windata, 465 | (GDestroyNotify)destroy_windata); 466 | 467 | g_signal_connect (G_OBJECT (win), 468 | "configure-event", 469 | G_CALLBACK (on_configure_event), 470 | windata); 471 | 472 | windata->main_vbox = gtk_vbox_new(FALSE, 0); 473 | g_signal_connect(G_OBJECT(windata->main_vbox), 474 | "style-set", 475 | G_CALLBACK(on_style_set), 476 | windata); 477 | gtk_widget_show(windata->main_vbox); 478 | gtk_container_add(GTK_CONTAINER(win), windata->main_vbox); 479 | gtk_container_set_border_width(GTK_CONTAINER(windata->main_vbox), DEFAULT_BORDER); 480 | 481 | // windata->main_hbox = gtk_hbox_new (FALSE, 0); 482 | // gtk_widget_show (windata->main_hbox); 483 | // gtk_box_pack_start (GTK_BOX (main_vbox), 484 | // windata->main_hbox, 485 | // FALSE, FALSE, 0); 486 | 487 | // icon box 488 | windata->iconbox = gtk_alignment_new (0.5f, 0, 0, 0); 489 | gtk_widget_show (windata->iconbox); 490 | gtk_alignment_set_padding (GTK_ALIGNMENT (windata->iconbox), 491 | 0, IMAGE_PADDING, 0, 0); 492 | gtk_box_pack_start (GTK_BOX (windata->main_vbox), 493 | windata->iconbox, 494 | FALSE, FALSE, 0); 495 | gtk_widget_set_size_request (windata->iconbox, BODY_X_OFFSET, -1); 496 | 497 | // icon 498 | windata->icon = gtk_image_new (); 499 | gtk_widget_show (windata->icon); 500 | gtk_container_add (GTK_CONTAINER (windata->iconbox), windata->icon); 501 | 502 | // progress bar box 503 | windata->progressbarbox = gtk_alignment_new (0.5f, 0, 0, 0); 504 | gtk_widget_show (windata->progressbarbox); 505 | // gtk_alignment_set_padding (GTK_ALIGNMENT (windata->iconbox), 506 | // 5, 0, 0, 0); 507 | gtk_box_pack_start (GTK_BOX (windata->main_vbox), 508 | windata->progressbarbox, 509 | FALSE, FALSE, 0); 510 | gtk_widget_set_size_request (windata->progressbarbox, BODY_X_OFFSET, -1); 511 | 512 | // progress bar 513 | windata->progressbar = gtk_image_new (); 514 | gtk_widget_show (windata->progressbar); 515 | gtk_container_add (GTK_CONTAINER (windata->progressbarbox), windata->progressbar); 516 | 517 | return GTK_WINDOW(win); 518 | } 519 | 520 | void 521 | move_notification (GtkWindow *win, int x, int y) { 522 | gtk_window_move(GTK_WINDOW(win), x, y); 523 | } 524 | 525 | void 526 | destroy_notification (GtkWindow *win) { 527 | gtk_widget_destroy(GTK_WIDGET(win)); 528 | } 529 | 530 | void 531 | set_notification_icon (GtkWindow *nw, GdkPixbuf *pixbuf) { 532 | WindowData *windata; 533 | GdkPixbuf *scaled; 534 | 535 | windata = g_object_get_data (G_OBJECT (nw), "windata"); 536 | 537 | g_assert (windata != NULL); 538 | 539 | scaled = NULL; 540 | if (pixbuf != NULL) { 541 | scaled = scale_pixbuf (pixbuf, 542 | MAX_ICON_SIZE, 543 | MAX_ICON_SIZE, 544 | TRUE); 545 | } 546 | 547 | gtk_image_set_from_pixbuf (GTK_IMAGE (windata->icon), scaled); 548 | 549 | if (scaled != NULL) { 550 | int pixbuf_width = gdk_pixbuf_get_width (scaled); 551 | 552 | gtk_widget_show (windata->icon); 553 | gtk_widget_set_size_request (windata->iconbox, 554 | MAX (BODY_X_OFFSET, pixbuf_width), -1); 555 | g_object_unref (scaled); 556 | } else { 557 | gtk_widget_hide (windata->icon); 558 | gtk_widget_set_size_request (windata->iconbox, 559 | BODY_X_OFFSET, 560 | -1); 561 | } 562 | } 563 | 564 | void 565 | set_progressbar_image (GtkWindow *nw, GdkPixbuf *pixbuf) { 566 | WindowData *windata; 567 | GdkPixbuf *scaled; 568 | 569 | windata = g_object_get_data (G_OBJECT (nw), "windata"); 570 | 571 | g_assert (windata != NULL); 572 | 573 | scaled = NULL; 574 | if (pixbuf != NULL) { 575 | scaled = scale_pixbuf (pixbuf, 576 | MAX_PROGRESSBAR_SIZE, 577 | MAX_PROGRESSBAR_SIZE, 578 | TRUE); 579 | } 580 | 581 | gtk_image_set_from_pixbuf (GTK_IMAGE (windata->progressbar), scaled); 582 | 583 | if (scaled != NULL) { 584 | int pixbuf_width = gdk_pixbuf_get_width (scaled); 585 | 586 | gtk_widget_show (windata->icon); 587 | gtk_widget_set_size_request (windata->progressbarbox, 588 | MAX (BODY_X_OFFSET, pixbuf_width), -1); 589 | g_object_unref (scaled); 590 | } else { 591 | gtk_widget_hide (windata->icon); 592 | gtk_widget_set_size_request (windata->progressbarbox, 593 | BODY_X_OFFSET, 594 | -1); 595 | } 596 | } 597 | -------------------------------------------------------------------------------- /src/notification.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Volnoti - Lightweight Volume Notification 3 | * Copyright (C) 2011 David Brazdil 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef NOTIFICATION_H 20 | #define NOTIFICATION_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | typedef struct { 27 | gfloat alpha; 28 | gint corner_radius; 29 | } Settings; 30 | 31 | Settings get_default_settings(); 32 | GtkWindow* create_notification(Settings settings); 33 | void move_notification(GtkWindow *win, int x, int y); 34 | void set_notification_icon(GtkWindow *nw, GdkPixbuf *pixbuf); 35 | void set_progressbar_image (GtkWindow *nw, GdkPixbuf *pixbuf); 36 | void destroy_notification(GtkWindow *win); 37 | 38 | #endif /* NOTIFICATION_H */ 39 | -------------------------------------------------------------------------------- /src/specs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/value-client-stub.h: -------------------------------------------------------------------------------- 1 | /* Generated by dbus-binding-tool; do not edit! */ 2 | 3 | #include 4 | #include 5 | 6 | G_BEGIN_DECLS 7 | 8 | #ifndef _DBUS_GLIB_ASYNC_DATA_FREE 9 | #define _DBUS_GLIB_ASYNC_DATA_FREE 10 | static 11 | #ifdef G_HAVE_INLINE 12 | inline 13 | #endif 14 | void 15 | _dbus_glib_async_data_free (gpointer stuff) 16 | { 17 | g_slice_free (DBusGAsyncData, stuff); 18 | } 19 | #endif 20 | 21 | #ifndef DBUS_GLIB_CLIENT_WRAPPERS_uk_ac_cam_db538_VolumeNotification 22 | #define DBUS_GLIB_CLIENT_WRAPPERS_uk_ac_cam_db538_VolumeNotification 23 | 24 | static 25 | #ifdef G_HAVE_INLINE 26 | inline 27 | #endif 28 | gboolean 29 | uk_ac_cam_db538_VolumeNotification_notify (DBusGProxy *proxy, const gint IN_volume, GError **error) 30 | 31 | { 32 | return dbus_g_proxy_call (proxy, "notify", error, G_TYPE_INT, IN_volume, G_TYPE_INVALID, G_TYPE_INVALID); 33 | } 34 | 35 | typedef void (*uk_ac_cam_db538_VolumeNotification_notify_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); 36 | 37 | static void 38 | uk_ac_cam_db538_VolumeNotification_notify_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) 39 | { 40 | DBusGAsyncData *data = (DBusGAsyncData*) user_data; 41 | GError *error = NULL; 42 | dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); 43 | (*(uk_ac_cam_db538_VolumeNotification_notify_reply)data->cb) (proxy, error, data->userdata); 44 | return; 45 | } 46 | 47 | static 48 | #ifdef G_HAVE_INLINE 49 | inline 50 | #endif 51 | DBusGProxyCall* 52 | uk_ac_cam_db538_VolumeNotification_notify_async (DBusGProxy *proxy, const gint IN_volume, uk_ac_cam_db538_VolumeNotification_notify_reply callback, gpointer userdata) 53 | 54 | { 55 | DBusGAsyncData *stuff; 56 | stuff = g_slice_new (DBusGAsyncData); 57 | stuff->cb = G_CALLBACK (callback); 58 | stuff->userdata = userdata; 59 | return dbus_g_proxy_begin_call (proxy, "notify", uk_ac_cam_db538_VolumeNotification_notify_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_volume, G_TYPE_INVALID); 60 | } 61 | #endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_uk_ac_cam_db538_VolumeNotification */ 62 | 63 | G_END_DECLS 64 | -------------------------------------------------------------------------------- /src/value-daemon-stub.h: -------------------------------------------------------------------------------- 1 | /* Generated by dbus-binding-tool; do not edit! */ 2 | 3 | 4 | #ifndef __dbus_glib_marshal_volume_object_MARSHAL_H__ 5 | #define __dbus_glib_marshal_volume_object_MARSHAL_H__ 6 | 7 | #include 8 | 9 | G_BEGIN_DECLS 10 | 11 | #ifdef G_ENABLE_DEBUG 12 | #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) 13 | #define g_marshal_value_peek_char(v) g_value_get_char (v) 14 | #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) 15 | #define g_marshal_value_peek_int(v) g_value_get_int (v) 16 | #define g_marshal_value_peek_uint(v) g_value_get_uint (v) 17 | #define g_marshal_value_peek_long(v) g_value_get_long (v) 18 | #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) 19 | #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) 20 | #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) 21 | #define g_marshal_value_peek_enum(v) g_value_get_enum (v) 22 | #define g_marshal_value_peek_flags(v) g_value_get_flags (v) 23 | #define g_marshal_value_peek_float(v) g_value_get_float (v) 24 | #define g_marshal_value_peek_double(v) g_value_get_double (v) 25 | #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) 26 | #define g_marshal_value_peek_param(v) g_value_get_param (v) 27 | #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) 28 | #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) 29 | #define g_marshal_value_peek_object(v) g_value_get_object (v) 30 | #define g_marshal_value_peek_variant(v) g_value_get_variant (v) 31 | #else /* !G_ENABLE_DEBUG */ 32 | /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. 33 | * Do not access GValues directly in your code. Instead, use the 34 | * g_value_get_*() functions 35 | */ 36 | #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int 37 | #define g_marshal_value_peek_char(v) (v)->data[0].v_int 38 | #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint 39 | #define g_marshal_value_peek_int(v) (v)->data[0].v_int 40 | #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint 41 | #define g_marshal_value_peek_long(v) (v)->data[0].v_long 42 | #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong 43 | #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 44 | #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 45 | #define g_marshal_value_peek_enum(v) (v)->data[0].v_long 46 | #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong 47 | #define g_marshal_value_peek_float(v) (v)->data[0].v_float 48 | #define g_marshal_value_peek_double(v) (v)->data[0].v_double 49 | #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer 50 | #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer 51 | #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer 52 | #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer 53 | #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer 54 | #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer 55 | #endif /* !G_ENABLE_DEBUG */ 56 | 57 | 58 | /* BOOLEAN:INT,POINTER */ 59 | extern void dbus_glib_marshal_volume_object_BOOLEAN__INT_POINTER (GClosure *closure, 60 | GValue *return_value, 61 | guint n_param_values, 62 | const GValue *param_values, 63 | gpointer invocation_hint, 64 | gpointer marshal_data); 65 | void 66 | dbus_glib_marshal_volume_object_BOOLEAN__INT_POINTER (GClosure *closure, 67 | GValue *return_value G_GNUC_UNUSED, 68 | guint n_param_values, 69 | const GValue *param_values, 70 | gpointer invocation_hint G_GNUC_UNUSED, 71 | gpointer marshal_data) 72 | { 73 | typedef gboolean (*GMarshalFunc_BOOLEAN__INT_POINTER) (gpointer data1, 74 | gint arg_1, 75 | gpointer arg_2, 76 | gpointer data2); 77 | register GMarshalFunc_BOOLEAN__INT_POINTER callback; 78 | register GCClosure *cc = (GCClosure*) closure; 79 | register gpointer data1, data2; 80 | gboolean v_return; 81 | 82 | g_return_if_fail (return_value != NULL); 83 | g_return_if_fail (n_param_values == 3); 84 | 85 | if (G_CCLOSURE_SWAP_DATA (closure)) 86 | { 87 | data1 = closure->data; 88 | data2 = g_value_peek_pointer (param_values + 0); 89 | } 90 | else 91 | { 92 | data1 = g_value_peek_pointer (param_values + 0); 93 | data2 = closure->data; 94 | } 95 | callback = (GMarshalFunc_BOOLEAN__INT_POINTER) (marshal_data ? marshal_data : cc->callback); 96 | 97 | v_return = callback (data1, 98 | g_marshal_value_peek_int (param_values + 1), 99 | g_marshal_value_peek_pointer (param_values + 2), 100 | data2); 101 | 102 | g_value_set_boolean (return_value, v_return); 103 | } 104 | 105 | G_END_DECLS 106 | 107 | #endif /* __dbus_glib_marshal_volume_object_MARSHAL_H__ */ 108 | 109 | #include 110 | static const DBusGMethodInfo dbus_glib_volume_object_methods[] = { 111 | { (GCallback) volume_object_notify, dbus_glib_marshal_volume_object_BOOLEAN__INT_POINTER, 0 }, 112 | }; 113 | 114 | const DBusGObjectInfo dbus_glib_volume_object_object_info = { 1, 115 | dbus_glib_volume_object_methods, 116 | 1, 117 | "uk.ac.cam.db538.VolumeNotification\0notify\0S\0volume\0I\0i\0\0\0", 118 | "\0", 119 | "\0" 120 | }; 121 | 122 | --------------------------------------------------------------------------------