computer_glamour před 1 měsícem
revize
5182cc75b9
7 změnil soubory, kde provedl 1718 přidání a 0 odebrání
  1. 57 0
      CHANGELOG
  2. 340 0
      COPYING
  3. 271 0
      LICENSE
  4. 24 0
      Makefile
  5. 35 0
      README
  6. 926 0
      gkrellmlaunch.c
  7. 65 0
      updateconfig.sh

+ 57 - 0
CHANGELOG

@@ -0,0 +1,57 @@
+Version History:
+Release 0.5 2002/09/26 13:53:08 
+Ported to GKrellM2
+
+Release 0.4 2002/09/01 19:33:53 
+Split "Update" button on Setup tab into "Add" and "Replace" -> more intuitive
+    
+Release 0.3  2002/02/16 15:33:22
+Made launcherList static.
+Added check to only zip the list in apply_plugin_config if something's been
+changed. (Saves unnecessary deleting & recreation of Panels/Decals.)
+Added unselect signal to the CList: prevents overwritting of previously
+selected entry when user wanted to add a new entry.
+Re-write to remove fixed sizelimitations of arrays.
+Buttons now implemented via a List.
+Configuration tab interface updated to reflect new implementation.
+Added preprocessor checking for correct version of GKrellM (1.2.2+) to
+prevent "undefined symbol: gkrellm_system" errors when compiling withi < 1.2.2
+versions of GKrellM.
+Split Config Info tab to Info & About.
+
+Release 0.2.2  2001/11/05 18:17:17  lee
+Fixed "undefined" behaviour in command creation in buttonPress()
+ -> misplaced close bracket causing memory allocation to < required.
+
+Release 0.2.1  2001/11/01 20:49:32  lee
+Fixed MAX_BUTTONS > 9 crashes Config tab bug.
+
+Revision 0.2  2001/10/31 20:50:12  lee
+Tidied up code: utilised for loops.
+Changed to gkrellm_system() from system() on advice from Bill.
+buttonPress() more intelligent & requires less maintainance.
+Now free()'ing malloc'ed strings.
+Modified Config tab to use scroll bar: helps keep "compact" feel.
+Code now entirely dynamic. To alter no. of buttons, change MAX_BUTTONS.
+
+Revision 0.1  28/10/2001 
+Ready for general release.
+Added ability to show/hide commands in Config.
+ 
+Revision 0.0.4 28/10/2001 
+Code Cleanup: merged multiple entries/strings into arrays
+Added automatic appending of '&' for commands
+ 
+Revision 0.0.3 28/10/2001 
+Added Label configuration of buttons
+ 
+Revision 0.0.2 27/10/2001 
+Added Configuration & Info tab
+Added creation of a panel for each decal 
+-> fixes mouseOver = "highlight all" problem
+Code Cleanup: Merged panel expose events into one function 
+  
+Revision 0.0.1 25/10/2001 
+Initial Version
+Allows more than one button (but limited to 4)
+  

+ 340 - 0
COPYING

@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

+ 271 - 0
LICENSE

@@ -0,0 +1,271 @@
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public License is intended
+to guarantee your freedom to share and change free software--to make sure
+the software is free for all its users. This General Public License applies
+to most of the Free Software Foundation's software and to any other program
+whose authors commit to using it. (Some other Free Software Foundation
+software is covered by the GNU Library General Public License instead.) You
+can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If
+the software is modified by someone else and passed on, we want its
+recipients to know that what they have is not the original, so that any
+problems introduced by others will not reflect on the original authors'
+reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program
+proprietary. To prevent this, we have made it clear that any patent must be
+licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms
+of this General Public License. The "Program", below, refers to any such
+program or work, and a "work based on the Program" means either the Program
+or any derivative work under copyright law: that is to say, a work
+containing the Program or a portion of it, either verbatim or with
+modifications and/or translated into another language. (Hereinafter,
+translation is included without limitation in the term "modification".) Each
+licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running the Program
+is not restricted, and the output from the Program is covered only if its
+contents constitute a work based on the Program (independent of having been
+made by running the Program). Whether that is true depends on what the
+Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code
+as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+License and to the absence of any warranty; and give any other recipients of
+the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute such
+modifications or work under the terms of Section 1 above, provided that you
+also meet all of these conditions:
+
+   * a) You must cause the modified files to carry prominent notices stating
+     that you changed the files and the date of any change.
+
+   * b) You must cause any work that you distribute or publish, that in
+     whole or in part contains or is derived from the Program or any part
+     thereof, to be licensed as a whole at no charge to all third parties
+     under the terms of this License.
+
+   * c) If the modified program normally reads commands interactively when
+     run, you must cause it, when started running for such interactive use
+     in the most ordinary way, to print or display an announcement including
+     an appropriate copyright notice and a notice that there is no warranty
+     (or else, saying that you provide a warranty) and that users may
+     redistribute the program under these conditions, and telling the user
+     how to view a copy of this License. (Exception: if the Program itself
+     is interactive but does not normally print such an announcement, your
+     work based on the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be
+reasonably considered independent and separate works in themselves, then
+this License, and its terms, do not apply to those sections when you
+distribute them as separate works. But when you distribute the same sections
+as part of a whole which is a work based on the Program, the distribution of
+the whole must be on the terms of this License, whose permissions for other
+licensees extend to the entire whole, and thus to each and every part
+regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works
+based on the Program.
+
+In addition, mere aggregation of another work not based on the Program with
+the Program (or with a work based on the Program) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1
+and 2 above provided that you also do one of the following:
+
+   * a) Accompany it with the complete corresponding machine-readable source
+     code, which must be distributed under the terms of Sections 1 and 2
+     above on a medium customarily used for software interchange; or,
+
+   * b) Accompany it with a written offer, valid for at least three years,
+     to give any third party, for a charge no more than your cost of
+     physically performing source distribution, a complete machine-readable
+     copy of the corresponding source code, to be distributed under the
+     terms of Sections 1 and 2 above on a medium customarily used for
+     software interchange; or,
+
+   * c) Accompany it with the information you received as to the offer to
+     distribute corresponding source code. (This alternative is allowed only
+     for noncommercial distribution and only if you received the program in
+     object code or executable form with such an offer, in accord with
+     Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and
+installation of the executable. However, as a special exception, the source
+code distributed need not include anything that is normally distributed (in
+either source or binary form) with the major components (compiler, kernel,
+and so on) of the operating system on which the executable runs, unless that
+component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy the
+source code from the same place counts as distribution of the source code,
+even though third parties are not compelled to copy the source along with
+the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to copy,
+modify, sublicense or distribute the Program is void, and will automatically
+terminate your rights under this License. However, parties who have received
+copies, or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Program or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the
+Program (or any work based on the Program), you indicate your acceptance of
+this License to do so, and all its terms and conditions for copying,
+distributing or modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these terms
+and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein. You are not responsible
+for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot distribute so
+as to satisfy simultaneously your obligations under this License and any
+other pertinent obligations, then as a consequence you may not distribute
+the Program at all. For example, if a patent license would not permit
+royalty-free redistribution of the Program by all those who receive copies
+directly or indirectly through you, then the only way you could satisfy both
+it and this License would be to refrain entirely from distribution of the
+Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system, which is implemented by public license
+practices. Many people have made generous contributions to the wide range of
+software distributed through that system in reliance on consistent
+application of that system; it is up to the author/donor to decide if he or
+she is willing to distribute software through any other system and a
+licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an
+explicit geographical distribution limitation excluding those countries, so
+that distribution is permitted only in or among countries not thus excluded.
+In such case, this License incorporates the limitation as if written in the
+body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of
+the General Public License from time to time. Such new versions will be
+similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make
+exceptions for this. Our decision will be guided by the two goals of
+preserving the free status of all derivatives of our free software and of
+promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
+THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
+PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
+LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
+THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS

+ 24 - 0
Makefile

@@ -0,0 +1,24 @@
+# Sample Makefile for a GKrellM plugin
+
+GTK_INCLUDE = `pkg-config gtk+-2.0 --cflags`
+GTK_LIB = `pkg-config gtk+-2.0 --libs`
+
+
+FLAGS = -O2 -Wall -fPIC $(GTK_INCLUDE) -g
+#LIBS = $(GTK_LIB) $(IMLIB_LIB) -lefence
+LIBS = $(GTK_LIB) $(IMLIB_LIB)
+
+LFLAGS = -shared -W1 
+
+CC = gcc $(CFLAGS) $(FLAGS)
+
+OBJS = gkrellmlaunch.o
+
+gkrellmlaunch.so: $(OBJS)
+	$(CC) $(OBJS) -o gkrellmlaunch.so $(LFLAGS) $(LIBS)
+
+clean:
+	rm -f *.o core *.so* *.bak *~
+
+gkrellmlaunch.o: gkrellmlaunch.c
+

+ 35 - 0
README

@@ -0,0 +1,35 @@
+GKrellM Launch Version 0.5
+Copyright (c) 2001, 2002 Lee Webb
+Release Date: 26/09/2002
+
+Released under the GNU Public License
+
+Description:
+A GKrellM plugin which allows one-click access to frequently used programs 
+(a la Gnome Panel).
+
+To Compile:
+Unpack the tarball & run make.
+Note: Requires GKrellM 2 or higher.
+
+To Install:
+Simply copy gkrellmlaunch.so to the desired plugin directory. 
+
+Note: If you have installed any version prior to 0.3, your configuration will
+not be picked up. This is due to (yet another) change in the way GKrellMLaunch
+stores its configuration. (Sorry folks.)
+You can either fire up the new version and manually input the buttons via the 
+Config tab, or modify you're user_config file:
+
+Pre-0.3 Config layout:
+gkrellmlaunch visible1 1
+gkrellmlaunch cmd1 mozilla
+gkrellmlaunch label1 Mozilla 0.9.8
+
+New 0.3 Config layout:
+gkrellmlaunch visible=1 label=Mozilla_0.9.8 cmd=mozilla
+
+Notice that any spaces in the label are converted to underscores.
+
+Lastest Version:
+Available at http://gkrellmlaunch.sourceforge.net

+ 926 - 0
gkrellmlaunch.c

@@ -0,0 +1,926 @@
+/*  
+ *  $RCSfile: gkrellmlaunch.c,v $
+ *  Revision: $Revision: 1.12 $
+ *  Date: $Date: 2002/09/26 13:53:08 $
+ *
+ *  Copyright (C) 2001 Lee Webb
+ *
+ *  Author: Lee Webb leewebb@users.sourceforge.net
+ *  Latest versions: http://gkrellmlaunch.sourceforge.net
+ *
+ *  Contributions:
+ *  Bill Wilson http://bill.nalens.com/ GTK2 port
+ *  Etan Reisner GTK2 port
+ *
+ *  This program is free software which I release under the GNU General Public
+ *  License. You may redistribute and/or modify this program under the terms
+ *  of that license as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  Requires GKrellM 2 or better
+ *
+ *  gcc -fPIC `pkg-config gtk+-2.0 --cflags` `pkg-config gtk+-2.0 --libs` -c gkrellmlaunch.c
+ *  gcc -shared -Wl -o gkrellmlaunch.so gkrellmlaunch.o
+ *  gkrellm -p gkrellmlaunch.so
+ */
+
+#include <gkrellm2/gkrellm.h>
+
+/*
+ * Make sure we have a compatible version of GKrellM
+ * (Version 2+ is required due to the use of GTK2)
+ */
+#if !defined(GKRELLM_VERSION_MAJOR) || GKRELLM_VERSION_MAJOR < 2
+#error This plugin requires GKrellM version >= 2
+#endif
+
+#define CONFIG_NAME "GKrellMLaunch"
+
+#define PLUGIN_PLACEMENT (MON_UPTIME | MON_INSERT_AFTER)
+
+#define PLUGIN_CONFIG_KEYWORD "gkrellmlaunch"
+
+#define STYLE_NAME "GKrellMLaunch"
+
+static gchar *GKrellMLaunchInfo[] =
+{
+  "<b>Usage\n\n",
+  "Label: ",
+  "This is the text that will appear on the button for the command.\n\n",
+  "Command: ",
+  "This is the binary name to run (e.g., mozilla).\n",
+  "Visible: ",
+  "Check box to allow buttons to be hidden if not used.\n\n",
+  "Use the \"Add\" button to create a new button.\n",
+  "Use the \"Replace\" button to update changes made for currently selected ",
+  "list entry.\n",
+  "Use the \"Delete\" button to delete the selected entry.\n",
+  "Use the /\\ & \\/  buttons to move selected entry up & down in position.\n",
+};
+
+static gchar GKrellMLaunchAbout[] = 
+  "GKrellMLaunch Version 0.5 (GKrellm2)\n"\
+  "GKrellM plugin to give one-click access to frequently used programs.\n\n"\
+  "Copyright (c) 2001-2002 by Lee Webb\n"\
+  "Release Date: 26/09/2002\n"\
+  "leewebb@users.sourceforge.net\n"\
+  "http://gkrellmlaunch.sourceforge.net\n\n"\
+  "Released under the GNU Public License.\n";
+
+static GkrellmMonitor *monitor;
+
+typedef struct
+{
+  gint  visible;
+  gchar *cmd;
+  gchar *label;
+
+  /* Each launcher has its own Panel & Decal */
+  GkrellmPanel *panel; 
+  GkrellmDecal *decal;
+} GLauncher;
+
+/*
+ * We need a list to hold our series of GLaunchers.
+ */
+static GList *launcherList;
+
+/* 
+ * Unlike the array version of GKrellMLaunch, where buttons were always
+ * kept in memory, regardless if they were used or not (due to the
+ * limitations of fixed size arrays), the new list implementation zaps the
+ * entire list & recreates it when apply_plugin_config is reached. Although
+ * not necessarily a major problem, the graphical effect of GKrellM
+ * deleting and (re)adding the Panels/Decals is not pretty. So we're going
+ * to use a varible to keep track of modifications to the list & only zap
+ * the list should something change.
+ */ 
+static gboolean listModified;
+
+static gint style_id;
+
+/* 
+ * Create Config tab widgets.
+ */ 
+static GtkWidget *cmdEntry;
+static GtkWidget *cmdEntryLabel;
+static GtkWidget *toggleButton;
+static GtkWidget *launcherVbox;
+/*
+ * Listbox widget for the config tab.
+ */
+static GtkWidget *launcherCList;
+
+/*
+ * Keep track of selected item in the Config listbox.
+ */
+static gint selectedRow;
+
+/* 
+ * Handle decal button presses
+ */ 
+static void buttonPress (GkrellmDecalbutton *button)
+{
+  gchar     *cmdRun = "";
+  gint      i;
+  gint      selected; 
+  GLauncher *launcher;
+  GList     *list;
+  
+  /*
+   * Perform the appropriate action acccording to the button pressed.
+   * Note: we append the '&' for the user to ensure background execution.
+   *
+   * Bill has informed me that using system() can be iffy: 
+   * "Whenever a program execs a child, the child inherits all open
+   * file descriptors and this could cause a problem because of plugins like
+   * Volume which have the audio device open.  So, for example, a user can 
+   * launch a program, then later after quitting gkrellm, can try to unload
+   * a sound module.  But this will fail if the child program launched from
+   * gkrellm is still running because it has the audio device opened."
+   * 
+   * Thus, use gkrellm_system() (a wrapper around system() that closes all
+   * open files before doing the system()).
+   * Unfortunately, such safety comes at a price: this call requires GKrellM 
+   * version 1.2.2. 
+   */ 
+  
+  selected = (GPOINTER_TO_INT (button->data));
+  /*
+   * Allocate space for cmd.
+   * Note: We're adding 2 (not 1) to the length. 
+   *       One for the '&' and one for the null.
+   *       No point having a variable just to hold a '&'.
+   */       
+  
+  /* 
+   * Move to selected button in the list 
+   */
+  for (i = 0, list = launcherList; i < selected; i += 1, list = list->next);
+  
+  launcher = (GLauncher *) list->data;
+
+  /*
+   * g_spawn_command_line_async() replaces gkrellm_system as a built in GTK2
+   * call. Runs the specified command in the background so no need to append 
+   * '&' ourselves.
+   */ 
+  cmdRun = g_strdup (launcher->cmd);
+  g_spawn_command_line_async (cmdRun, NULL);
+  
+  /*
+   * Cleanup as g_strdup doesn't automatically free()
+   */
+  g_free (cmdRun);
+  
+}
+
+static gint panel_expose_event (GtkWidget *widget, GdkEventExpose *ev)
+{
+  GLauncher *launcher;
+  GList     *list;
+  
+  /*
+   * O.K. This isn't particularly efficient, but in the interests of 
+   * maintainability, I'm going to keep this in.
+   */ 
+  for (list = launcherList; list; list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+    if (widget == launcher->panel->drawing_area)
+    {
+      gdk_draw_pixmap (widget->window,
+                       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                       launcher->panel->pixmap, ev->area.x, ev->area.y, 
+                      ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+    }
+  }  
+
+  return FALSE;
+}
+
+/*
+ * Func called by create_plugin() & apply_config() to show/hide panels 
+ * at startup according to related config item.
+ */ 
+static void setVisibility ()
+{
+  GLauncher *launcher;
+  GList     *list;
+
+  for (list = launcherList ; list ; list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+    if (launcher->visible == 0)
+    {
+      gkrellm_panel_hide (launcher->panel);
+    }
+    else
+    {
+      gkrellm_panel_show (launcher->panel);
+    }  
+  }  
+}
+  
+static void update_plugin ()
+{
+  GLauncher *launcher;
+  GList     *list;
+
+  for (list = launcherList; list; list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+    gkrellm_draw_panel_layers (launcher->panel);
+  }  
+}
+
+/* 
+ * Configuration
+ */
+static void save_plugin_config (FILE *f)
+{
+  GLauncher *launcher;
+  GList     *list;
+  gchar     *ptr;
+  
+  for (list = launcherList; list; list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+
+    /*
+     * Since labels may have spaces, we need to convert those to
+     * underscores: else sscanf won't work properly on load.
+     */
+    for (ptr = launcher->label; *ptr; ptr++)
+    {
+      if (*ptr == ' ')
+      {
+        *ptr = '_';
+      }
+    }  
+    fprintf (f, "%s visible=%d label=%s cmd=%s\n", 
+             PLUGIN_CONFIG_KEYWORD, launcher->visible,
+             launcher->label, launcher->cmd);
+  }
+}
+
+static void apply_plugin_config ()
+{
+  gchar     *string;
+  gint      i;
+  gint      row;
+  GLauncher *launcher;
+  GList     *list;
+  GList     *newList;
+  GkrellmStyle     *style;
+  GkrellmTextstyle *ts;
+  GkrellmTextstyle *ts_alt;
+
+  if (listModified)
+  {
+    /*
+     * Create a new list with the applied settings
+     * Trash the old list.
+     */
+    newList = NULL;
+
+    /*
+     * Read each row of the listbox & create a new launcher.
+     * Append each launcher to the new list.
+     */ 
+    for (row = 0; row < (GTK_CLIST (launcherCList)->rows); row += 1)
+    {
+      launcher = g_new0 (GLauncher, 1);
+      newList = g_list_append (newList, launcher);
+
+      gtk_clist_set_row_data (GTK_CLIST (launcherCList), row, launcher);
+
+      /* 
+       * Fill the visible option.
+       */ 
+      gtk_clist_get_text (GTK_CLIST (launcherCList), row, 0, &string);
+      launcher->visible = (strcmp (string, "No") ? 1 : 0);
+    
+      /* 
+       * Fill the label option.
+       */ 
+      gtk_clist_get_text (GTK_CLIST (launcherCList), row, 1, &string);
+      gkrellm_dup_string (&launcher->label, string);
+
+      /*
+       * Fill the command option.
+       */
+      gtk_clist_get_text (GTK_CLIST (launcherCList), row, 2, &string);
+      gkrellm_dup_string (&launcher->cmd, string);
+      
+    }
+
+    /*
+     * Wipe out the old list.
+     */
+    while (launcherList)
+    {
+      launcher = (GLauncher *) launcherList->data;
+      gkrellm_panel_destroy (launcher->panel);
+      launcherList = g_list_remove (launcherList, launcher);
+    }
+
+    /*
+     * And then update to the new list.
+     */
+    launcherList = newList;
+    
+    /*
+     * Since we've destroyed the old list & the panels/decals with it,
+     * we have to recreate those associated panels/decals.
+     */ 
+
+    /*
+     * First make sure we have the styles set up.
+     */
+    style = gkrellm_meter_style (style_id);
+    ts = gkrellm_meter_textstyle (style_id);
+    ts_alt = gkrellm_meter_alt_textstyle (style_id);
+     
+    for (i = 0, list = launcherList; list; i += 1, list = list->next)
+    {
+      launcher = (GLauncher *) list->data;
+      launcher->panel = gkrellm_panel_new0();
+      launcher->decal = gkrellm_create_decal_text (launcher->panel,
+                            launcher->label, ts_alt, style, -1, -1, -1);
+                            
+      /*
+       * Configure the panel to the created decal, and create it.
+       */
+      gkrellm_panel_configure (launcher->panel, NULL, style);
+      gkrellm_panel_create (launcherVbox, monitor, launcher->panel);
+
+      /*
+       * Panel's been created so convert the decal into a button.
+       */
+      gkrellm_draw_decal_text (launcher->panel, launcher->decal,
+                               launcher->label, 1);
+                               
+      gkrellm_put_decal_in_meter_button (launcher->panel, launcher->decal,
+                                         buttonPress,
+                                         GINT_TO_POINTER (i), NULL);
+      /*
+       * Connect our panel to the expose event to allow it to be drawn in 
+       * update_plugin().
+       */ 
+      gtk_signal_connect (GTK_OBJECT (launcher->panel->drawing_area),
+                          "expose_event", (GtkSignalFunc) panel_expose_event,
+                          NULL);
+                          
+    }
+    setVisibility ();
+
+    /*
+     * Reset the modification state.
+     */
+    listModified = FALSE;
+  }  
+} 
+
+static void load_plugin_config (gchar *arg)
+{
+  gchar     cmd[255];
+  gchar     label[25];
+  gchar     visible[2];
+  gchar     *ptr;
+  gint      n;
+  GLauncher *launcher;
+  GList     *list;
+
+  n = sscanf (arg, "visible=%s label=%s cmd=%[^\n]", visible, label, cmd);
+  
+  if (n == 3)
+  {
+    launcher = g_new0 (GLauncher, 1);
+    launcher->cmd = g_strdup (cmd);
+
+    /*
+     * Spaces in labels will have been converted to underscores in 
+     * save_plugin_config(). Convert them back to spaces.
+     */
+    for (ptr = label; *ptr; ptr++)
+    {
+      if (*ptr == '_')
+      {
+        *ptr = ' ';
+      }
+    }  
+    launcher->label = g_strdup (label);
+    launcher->visible = atoi (visible);
+    launcherList = g_list_append (launcherList, launcher);
+  }
+
+  for (list = launcherList; list; list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+  }  
+}
+
+static void cbMoveUp (GtkWidget *widget, gpointer drawer)
+{
+  gint      row;
+  GtkWidget *clist;
+
+  clist = launcherCList;
+  row = selectedRow;
+  
+  /*
+   * Only attempt a move if we're not on the first row.
+   */
+  if (row > 0)
+  {
+    /* 
+     * Move the selected row up one position. 
+     * Note that we have to reselect it afterwards.
+     */
+    gtk_clist_row_move (GTK_CLIST (clist), row, row - 1);
+    gtk_clist_select_row (GTK_CLIST (clist), row - 1, -1);
+    
+    selectedRow = row - 1;
+    listModified = TRUE;
+  }
+}
+
+static void cbMoveDown (GtkWidget *widget, gpointer drawer)
+{
+  gint      row;
+  GtkWidget *clist;
+       
+  clist = launcherCList;
+  row = selectedRow;
+  
+  /*
+   * Only attempt a row if we're not on the last row.
+   * Note that we have to reselect it afterwards.
+   */
+  if ((row >= 0) && (row < (GTK_CLIST (clist)->rows - 1)))
+  {
+    gtk_clist_row_move (GTK_CLIST (clist), row, row + 1);
+    gtk_clist_select_row (GTK_CLIST (clist), row + 1, -1);
+
+    selectedRow = row + 1;
+    listModified = TRUE;
+  }
+}
+
+static void cListSelected (GtkWidget *clist, gint row, gint column, 
+                          GdkEventButton *bevent, gpointer data)
+{
+  gchar *string;
+
+  /*
+   * Fill the entry widgets & check box accoring to the selected row's text
+   */ 
+  gtk_clist_get_text (GTK_CLIST (launcherCList), row, 0, &string);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 
+                                strcmp (string, "No") ? TRUE : FALSE);
+    
+  gtk_clist_get_text (GTK_CLIST (launcherCList), row, 1, &string);
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), string);
+
+  gtk_clist_get_text (GTK_CLIST (launcherCList), row, 2, &string);
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), string);
+     
+  selectedRow = row;
+}
+
+static void cListUnSelected (GtkWidget *clist, gint row, gint column, 
+                             GdkEventButton *bevent, gpointer data)
+{
+  /* 
+   * Reset the entry widgets & check box
+   */ 
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), "");
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), "");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 0);
+  
+  selectedRow = -1;
+}
+
+static void cbAdd (GtkWidget *widget, gpointer data)
+{
+  gchar *buffer[3];
+        
+  buffer[0] = (gtk_toggle_button_get_active 
+               (GTK_TOGGLE_BUTTON (toggleButton)) == TRUE ? "0" : "1");
+  buffer[1] = gkrellm_gtk_entry_get_text (&cmdEntryLabel);
+  buffer[2] = gkrellm_gtk_entry_get_text (&cmdEntry);
+   
+  /*
+   * If either of the Label or Command entries are empty, forget it.
+   */ 
+  if ((!strlen (buffer[1])) || (!strlen (buffer[2])))
+  {
+    return;
+  }
+
+  buffer[0] = gtk_toggle_button_get_active 
+              (GTK_TOGGLE_BUTTON (toggleButton)) == TRUE ? "Yes" : "No";
+  gtk_clist_append (GTK_CLIST (launcherCList), buffer);
+  listModified = TRUE;
+
+  /* 
+   * Reset the entry widgets & check box
+   */ 
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), "");
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), "");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 0);
+}
+
+static void cbReplace (GtkWidget *widget, gpointer data)
+{
+  gchar *buffer[3];
+        
+  buffer[0] = (gtk_toggle_button_get_active 
+               (GTK_TOGGLE_BUTTON (toggleButton)) == TRUE ? "0" : "1");
+  buffer[1] = gkrellm_gtk_entry_get_text (&cmdEntryLabel);
+  buffer[2] = gkrellm_gtk_entry_get_text (&cmdEntry);
+   
+  /*
+   * If either of the Label or Command entries are empty, forget it.
+   */ 
+  if ((!strlen (buffer[1])) || (!strlen (buffer[2])))
+  {
+    return;
+  }
+
+  /*
+   * If a row is selected, we're modifying an existing entry, 
+   */ 
+  if (selectedRow >= 0)
+  {
+    gtk_clist_set_text (GTK_CLIST (launcherCList), 
+                        selectedRow, 1, buffer[1]);
+    gtk_clist_set_text (GTK_CLIST (launcherCList), 
+                        selectedRow, 2, buffer[2]);
+    gtk_clist_set_text (GTK_CLIST (launcherCList), 
+                        selectedRow, 0, 
+                        gtk_toggle_button_get_active 
+                        (GTK_TOGGLE_BUTTON (toggleButton)) 
+                        == TRUE ? "Yes" : "No");
+    gtk_clist_unselect_row (GTK_CLIST (launcherCList), selectedRow, 0);
+    selectedRow = -1;
+    listModified = TRUE;
+  }
+
+  /* 
+   * Reset the entry widgets & check box
+   */ 
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), "");
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), "");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 0);
+
+  gtk_clist_unselect_row (GTK_CLIST (launcherCList), selectedRow, 0);
+}
+
+static void cbDelete (GtkWidget *widget, gpointer data)
+{
+  /* 
+   * Reset the entry widgets & check box
+   */ 
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), "");
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), "");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 0);
+
+  if (selectedRow >= 0)
+  {
+    gtk_clist_remove (GTK_CLIST (launcherCList), selectedRow);
+    selectedRow = -1;
+    listModified = TRUE;
+  }
+}
+
+/*
+ * Create a Config tab with:
+ * 1. Checkbox to make panel visible/hidden
+ * 2. Text entry widget for command to run
+ * 3. Text entry widget for button label
+ * 4. Listbox to show items
+ * 5. Info tab 
+ */ 
+static void create_plugin_tab (GtkWidget *tab_vbox)
+{
+  gchar     *titles[3] = {"Visible", "Label", "Command"};
+  gchar     *buffer[3];
+  gchar     visible[5];
+  gint      i = 0;
+  GLauncher *launcher;
+  GList     *list;
+  GtkWidget *tabs;
+  GtkWidget *vbox; 
+  GtkWidget *hbox;
+  GtkWidget *scrolled;
+  GtkWidget *text;
+  GtkWidget *label;
+  GtkWidget *button; 
+  GtkWidget *aboutLabel;
+  GtkWidget *aboutText;
+
+  /* 
+   * Make a couple of tabs.  One for Config and one for info.
+   */
+  tabs = gtk_notebook_new ();
+  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (tabs), GTK_POS_TOP);
+  gtk_box_pack_start (GTK_BOX (tab_vbox), tabs, TRUE, TRUE, 0);
+
+  /* 
+   * Setup tab: give it some scroll bars to keep the config 
+   * window size compact.
+   */
+  vbox = gkrellm_gtk_notebook_page (tabs, "Setup");
+  vbox = gkrellm_gtk_scrolled_vbox (vbox, NULL,
+                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+  /*
+   * Dynamically create the options on the Config tab according to MAX_BUTTONS.
+   */
+  
+  /* 
+   * Create text boxes to put Labels and Commands in 
+   */
+    
+  label = gtk_label_new ("Label: ");
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+
+  cmdEntryLabel = gtk_entry_new_with_max_length (255) ;
+  gtk_entry_set_text (GTK_ENTRY (cmdEntryLabel), "") ;
+  gtk_entry_set_editable (GTK_ENTRY (cmdEntryLabel), TRUE); 
+  gtk_box_pack_start (GTK_BOX (vbox), cmdEntryLabel, FALSE, FALSE, 0) ;
+    
+  label = gtk_label_new ("Command:");
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, i);
+  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+
+  cmdEntry = gtk_entry_new_with_max_length (255) ;
+  gtk_entry_set_text (GTK_ENTRY (cmdEntry), "") ;
+  gtk_entry_set_editable (GTK_ENTRY (cmdEntry), TRUE) ;
+  gtk_box_pack_start (GTK_BOX (vbox), cmdEntry, FALSE, FALSE, 0) ;
+
+  toggleButton = gtk_check_button_new_with_label ("Visible?");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggleButton), 0);
+  gtk_box_pack_start (GTK_BOX (vbox), toggleButton, FALSE, TRUE, 0);
+  
+  /*
+   * Add buttons into their own box 
+   * => Add  Replace  Delete    /\     \/  
+   */
+  hbox = gtk_hbox_new (FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+    
+  /*
+   * Add "Add", "Replace" & "Delete" buttons
+   */
+  button = gtk_button_new_with_label ("Add");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", 
+                      (GtkSignalFunc) cbAdd, NULL);
+
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+  
+  button = gtk_button_new_with_label ("Replace");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", 
+                      (GtkSignalFunc) cbReplace, NULL);
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+    
+  button = gtk_button_new_with_label ("Delete");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", 
+                      (GtkSignalFunc) cbDelete, NULL);
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+    
+  /*
+   * Add reposition buttons
+   */
+  button = gtk_button_new_with_label ("/\\");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", 
+                      (GtkSignalFunc) cbMoveUp, NULL);
+    
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+  button = gtk_button_new_with_label ("\\/");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                      (GtkSignalFunc) cbMoveDown, NULL);
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+  /*
+   * Create listbox to hold each item 
+   */ 
+  scrolled = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 
+                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); 
+    
+  /*
+   * Create the CList with 3 titles:
+   * Label, Command, Visible
+   */ 
+  launcherCList = gtk_clist_new_with_titles (3, titles);
+  gtk_clist_set_shadow_type (GTK_CLIST (launcherCList), GTK_SHADOW_OUT);
+
+  /* 
+   * Set the column widths
+   */
+  /* Label */
+  gtk_clist_set_column_width (GTK_CLIST (launcherCList), 0, 30);
+  /* Command */
+  gtk_clist_set_column_width (GTK_CLIST (launcherCList), 1, 100);
+  /* Visible */
+  gtk_clist_set_column_width (GTK_CLIST (launcherCList), 2, 200);
+
+  gtk_clist_set_column_justification (GTK_CLIST (launcherCList), 
+                                      0, GTK_JUSTIFY_LEFT);
+  gtk_clist_set_column_justification (GTK_CLIST (launcherCList), 
+                                      1, GTK_JUSTIFY_LEFT);
+  gtk_clist_set_column_justification (GTK_CLIST (launcherCList), 
+                                      2, GTK_JUSTIFY_LEFT);
+
+  /*
+   * Add signals for selecting a row in the CList. 
+   */ 
+  gtk_signal_connect (GTK_OBJECT (launcherCList), "select_row", 
+                      (GtkSignalFunc) cListSelected, NULL);
+ 
+  /*
+   * Add signal for deselecting a row in the CList. 
+   * If not, delselecting & attempting to create a new entry will overwrite
+   * the previuosly selected row.
+   */ 
+  gtk_signal_connect (GTK_OBJECT (launcherCList), "unselect_row", 
+                      (GtkSignalFunc) cListUnSelected, NULL);
+
+  /* 
+   * Add the CList to the scrolling window
+   */ 
+  gtk_container_add (GTK_CONTAINER (scrolled), launcherCList);
+    
+  /*
+   * Fill the CList with our commands etc.
+   */ 
+  for (i = 0, list = launcherList; list; i += 1, list = list->next)
+  {  
+    launcher = (GLauncher *) list->data;
+    sprintf (visible, "%s", (launcher->visible == 1 ? "Yes" : "No"));        
+             buffer[0] = visible;
+    buffer[1] = launcher->label;
+    buffer[2] = launcher->cmd;
+    gtk_clist_append (GTK_CLIST (launcherCList), buffer);
+    gtk_clist_set_row_data (GTK_CLIST (launcherCList), i, launcher);
+  }
+
+  /* 
+   * Info tab
+   */
+  vbox = gkrellm_gtk_notebook_page (tabs, "Info");
+  text = gkrellm_gtk_scrolled_text_view (vbox, NULL, GTK_POLICY_AUTOMATIC,
+                                         GTK_POLICY_AUTOMATIC);
+  gkrellm_gtk_text_view_append_strings (text, GKrellMLaunchInfo,
+                                       (sizeof (GKrellMLaunchInfo) 
+                                       / sizeof (gchar *)));
+
+  /*
+   * About tab
+   */
+  aboutText = gtk_label_new (GKrellMLaunchAbout);
+  aboutLabel = gtk_label_new ("About");
+  gtk_notebook_append_page (GTK_NOTEBOOK (tabs), aboutText, aboutLabel);
+
+}
+
+static void create_plugin (GtkWidget *vbox, gint first_create)
+{
+  gint      i;
+  GLauncher *launcher;
+  GList     *list;
+  GkrellmStyle     *style;
+  GkrellmTextstyle *ts;
+  GkrellmTextstyle *ts_alt;
+
+  launcherVbox = vbox;
+
+  if (first_create)
+  {
+    for (list = launcherList; list; list = list->next)
+    {
+      launcher = (GLauncher *) list->data;
+      launcher->panel = gkrellm_panel_new0();
+    }
+  }  
+    
+  style = gkrellm_meter_style (style_id);
+
+  /* 
+   * Each GkrellmStyle has two text styles.  The theme designer has picked the
+   * colors and font sizes, presumably based on knowledge of what you draw
+   * on your panel.  You just do the drawing.  You probably could assume
+   * the ts font is larger than the ts_alt font, but again you can be
+   * overridden by the theme designer.
+   */
+  ts = gkrellm_meter_textstyle (style_id);
+  ts_alt = gkrellm_meter_alt_textstyle (style_id);
+
+  /* 
+   * Create a text decal that will be converted to a button.  
+   * Make it the entire width of the panel.
+   */
+  for (i = 0, list = launcherList; list; i += 1, list = list->next)
+  {
+    launcher = (GLauncher *) list->data;
+    launcher->decal = gkrellm_create_decal_text (launcher->panel,
+                            launcher->label, ts_alt, style, -1, -1, -1);
+  /*
+   * Configure the panel to created decal, and create it.
+   */
+    gkrellm_panel_configure (launcher->panel, NULL, style);
+    gkrellm_panel_create (vbox, monitor, launcher->panel);
+    
+  /* 
+   * After the panel is created, the decal can be converted into a button.
+   * First draw the initial text into the text decal button and then
+   * put the text decal into a meter button.  
+   */
+    gkrellm_draw_decal_text (launcher->panel, launcher->decal, 
+                              launcher->label,1);
+    gkrellm_put_decal_in_meter_button (launcher->panel, launcher->decal, 
+                                       buttonPress, 
+                                       GINT_TO_POINTER (i), NULL);
+  }                                            
+
+  /* 
+   * Note: all of the above gkrellm_draw_decal_XXX() calls will not
+   * appear on the panel until a gkrellm_draw_panel_layers() call is
+   * made.  This will be done in update_plugin(), otherwise we would
+   * make the call here and anytime the decals are changed.
+   */
+
+  if (first_create)
+  {
+    for (list = launcherList; list; list = list->next)
+    {
+      launcher = (GLauncher *) list->data;
+      gtk_signal_connect (GTK_OBJECT (launcher->panel->drawing_area), 
+                  "expose_event", (GtkSignalFunc) panel_expose_event, NULL);
+    }                      
+    /*
+     * Setup the initial visible status of each panel
+     * according to the config item read in.
+     */ 
+    setVisibility ();
+  }
+}
+
+
+/* 
+ * The monitor structure tells GKrellM how to call the plugin routines.
+ */
+static GkrellmMonitor plugin_mon	=
+{
+  CONFIG_NAME,           /* Name, for config tab.          */
+  0,                     /* Id,  0 if a plugin             */
+  create_plugin,         /* The create function            */
+  update_plugin,         /* The update function            */
+  create_plugin_tab,     /* The config tab create function */
+  apply_plugin_config,   /* Apply the config function      */
+  save_plugin_config,    /* Save user config               */
+  load_plugin_config,    /* Load user config               */
+  PLUGIN_CONFIG_KEYWORD, /* config keyword                 */
+
+  NULL,        /* Undefined 2 */
+  NULL,        /* Undefined 1 */
+  NULL,        /* private     */
+
+  PLUGIN_PLACEMENT,    /* Insert plugin before this monitor */
+
+  NULL,               /* Handle if a plugin, filled in by GKrellM */
+  NULL                /* path if a plugin, filled in by GKrellM   */
+};
+
+/* 
+ * All GKrellM plugins must have one global routine named gkrellm_init_plugin()
+ * which returns a pointer to a filled in monitor structure.
+ */
+GkrellmMonitor* gkrellm_init_plugin ()
+{
+  /*
+   * Don't want any row in the Config tab initially selected.
+   */
+  selectedRow = -1;
+  listModified = FALSE;
+
+  style_id = gkrellm_add_meter_style (&plugin_mon, STYLE_NAME);
+  monitor = &plugin_mon;
+  return &plugin_mon;
+}

+ 65 - 0
updateconfig.sh

@@ -0,0 +1,65 @@
+#!/bin/sh
+# updateconfig.sh
+#  Script to update pre-0.3 GKrellMLaunch config items to 0.3 format.
+
+# Directory in which the user_config file lives. This will need to be
+# modified if you're using a system-wide config.
+#cd $HOME/.gkrellm
+
+# Back up the original config file, just in case...
+echo -n Backing up config file...
+#cp user_config user_config.bak
+echo Done.
+echo -n Updating GKrellMLaunch config items...
+
+# Old format is visible1 1, cmd1 rxvt, label1 rxvt on separate lines.
+# New format is visible=1, label=rxvt, cmd=rxvt on one line
+
+# Need to splce together the individual config elements for each button
+# into one line. So, loop the items & save them off
+
+# Dump the non-gkrellmlaunch items first
+#grep -v gkrellmlaunch user_config > user_config.bak
+
+gkrellmlaunch=`grep gkrellmlaunch user_config`
+ grep gkrellmlaunch user_config | sed -e 's/gkrellmlaunch visible[0-9]* \(.*\)/\1/g' | sed -e 's/gkrellmlaunch cmd[0-9]* \(.*\)/\1/g' | sed -e 's/gkrellml aunch label[0-9]* \(.*\)/\1/g'
+
+#echo $gkrellmlaunch
+j=1
+for i in `grep gkrellmlaunch user_config`
+do
+   echo "i is: $i"
+   if [ $j -eq 1 ];then
+     echo `cat ${i} | cut -b24-`
+   fi
+   if [ $j -eq 2 ];then
+     echo `cat ${i} | cut -b20-`
+   fi
+   if [ $j -eq 3 ];then
+     echo `cat ${i} | cut -b22-`
+     
+   fi
+   j=`expr $j + 1`
+done   
+#do 
+#  echo $i
+#done  
+#for item in $gkrellmlaunch
+#  do
+  # If it's not gkrellmlaunch, then it's a command/label that's been
+  # split up by the above grep. Keep looping & appending until we
+  # hit another gkrellmlaunch
+#  echo "Got $item"
+#  if [ $item != "gkrellmlaunch" ]; then
+#  for appendItem in $gkrellmlaunch
+#    do
+#      echo "Append $appendItem"
+#    done
+#  fi  
+#  done
+
+
+echo Done. 
+echo Please inspect the user_config file to confirm that everything\'s as it \
+should be. When happy, you may delete the user_config.bak file.
+