From:
http://ponce.cc/slackware/sources/repo/wmswallow.tar.Z
---
 wmswallow/CHANGELOG      |  67 +++++
 wmswallow/INSTALL        |  34 +++
 wmswallow/LICENCE        | 341 ++++++++++++++++++++++++
 wmswallow/Makefile       |  45 ++++
 wmswallow/README         | 160 +++++++++++
 wmswallow/README.solaris |  16 ++
 wmswallow/todo           | 130 +++++++++
 wmswallow/version.h      |   1 +
 wmswallow/wmswallow.c    | 678 +++++++++++++++++++++++++++++++++++++++++++++++
 wmswallow/wmswallow.spec |  56 ++++
 10 files changed, 1528 insertions(+)
 create mode 100644 wmswallow/CHANGELOG
 create mode 100644 wmswallow/INSTALL
 create mode 100644 wmswallow/LICENCE
 create mode 100644 wmswallow/Makefile
 create mode 100644 wmswallow/README
 create mode 100644 wmswallow/README.solaris
 create mode 100644 wmswallow/todo
 create mode 100644 wmswallow/version.h
 create mode 100644 wmswallow/wmswallow.c
 create mode 100644 wmswallow/wmswallow.spec

diff --git a/wmswallow/CHANGELOG b/wmswallow/CHANGELOG
new file mode 100644
index 0000000..413e394
--- /dev/null
+++ b/wmswallow/CHANGELOG
@@ -0,0 +1,67 @@
+                       -*- text -*-
+Time-stamp: <00/05/15 23:33:49 friedel>
+
+(Note: don't get confused, the dates in this file are in german-locale (de_DE),
+       because i was too lazy to use something else than 
+       ctrl-u meta-! date... but the timestamp is in C locale...)
+
+0.6.1: <Mon Mai 15 23:15:29 CEST 2000>
+Fixed eternal loop under openwindows (solaris-x86)
+      <Mon Mai 15 23:14:54 CEST 2000>
+Added wmswallow.spec for easy building of rpm :-)
+       <Fre Mai 12 15:50:12 CEST 2000>
+
+0.6: <Fre Mai 12 02:16:30 CEST 2000>
+Celebrated first wmswallow version without my favorite bug, with a beer :-)
+Made the switches work :-)
+       <Fre Mai 12 01:49:49 CEST 2000>
+Added commandline switches -managed -unmanaged. -managed is the default
+behaviour, we wait for the Window to be reparented.
+      <Fre Mai 12 01:27:47 CEST 2000>
+Added code from Jason Lowdermilk to listen to CreateWindow Events, after the
+app has been started. Then i modified it heavily, because i found it was still
+too unreliable. Now wmswallow Listens for ReparentNotify events. So, we rely
+on WindowMaker first reparenting the windows, then sleep just a second and can
+be sure that everything worked! And i don't think that the Windowmaker
+behaviour (or any other windowmanager) will change in that respect :-) Well,
+this might not work for xteddy (or other apps that are ignored by the
+windowmanager)
+       <Fre Mai 12 00:47:24 CEST 2000>
+Put code to check window for WM_CLASS and WM_NAME in extra function.
+    <Don Mai 11 17:23:13 CEST 2000>
+
+0.5.3: <Don Mai 11 01:02:02 CEST 2000>
+Fixed a nasty bug that i introduced by modyfying Jason's patch incorrectly and
+some tiny cleanups.
+      <Don Mai 11 00:54:38 CEST 2000>
+Added thanks to the contributors to README
+      <Don Mai 11 00:29:55 CEST 2000>
+Incorporated patch from Jason Lowdermilk <lowderm...@visto.com> to enable
+finding windows by WM_NAME (i confused WM_NAME with the name part of the
+property returned by XGetClassHint. The patch fixes some memory leaks as well.
+Jason says, this helps with some Java-Applications.
+        <Don Mai 11 00:10:50 CEST 2000>
+
+
+0.5.2: <Mit Mai  3 22:03:27 CEST 2000>
+Modified README
+New switch: -focus/-nofocus, to make focus-handling enabled only on demand,
+    more fixes  to focus-handling (this time for real...)
+       <Mit Mai  3 21:52:29 CEST 2000>
+Small code cleanups, fixes for focus handling (windows could "lose" focus)
+       <Mit Mai  3 07:24:09 CEST 2000>
+Keyboard focus works now.
+       <Die Mai  2 22:35:58 CEST 2000>
+Makefile modified, new target xfree tested under linux and freebsd
+       <Die Mai  2 14:00:46 CEST 2000>
+
+0.5.1: <Sam Apr 29 13:15:27 CEST 2000>
+softenwindows() is superfluous, removed
+chidren_return is now XFree'd in findnamedwindowacc()
+
+0.5: <Fre Apr 28 10:30:00 CEST 2000>
+Initial beta release, all functionality present, some small bugs, some small
+shortcomings.
+
+Shortly after freshmeat announcement i discovered a small bug in the Makefile,
+but that was fixed before the news got out.
diff --git a/wmswallow/INSTALL b/wmswallow/INSTALL
new file mode 100644
index 0000000..8120116
--- /dev/null
+++ b/wmswallow/INSTALL
@@ -0,0 +1,34 @@
+INSTALLATION:
++++++++++++++
+        untar the sources by typing something along the lines of
+
+        zcat wmswallow.tar.Z|tar cvf -
+        cd wmswallow
+        make <platform>
+
+        where platform is currently one out of
+                xfree, solaris, solaris-gcc
+
+        The xfree target works under linux and freebsd.
+
+        Linux is tested best, since i'm hacking this stuff under linux (at
+        home). I have access to several Solaris Workstations (some sparcs, and
+        2 pcs) whith quite different Installations which i regularly use, so
+        the solaris target will at least get some attention. Solaris users
+        please read README.solaris for some hints.
+
+        Other Unices might or might not get happy with the xfree target or
+        some or other... I really think using autoconf/automake for this small
+        app would be overkill. If you devise a proper patch for a different
+        Unix-flavour, i will include it, but i might not be able to test it.
+        (I have currently access to FreeBSD and AIX, in addition to my
+        "home-platforms")
+
+        After compilation put the binary somewhere you like (e.g. in 
/usr/local/bin)
+        and in case you want to delete the Sourcetree, you might want to copy 
the
+        README to /usr/doc/wmswallow
+
+        Now try
+                wmswallow -h
+        to get a basic idea how it works.
+
diff --git a/wmswallow/LICENCE b/wmswallow/LICENCE
new file mode 100644
index 0000000..a52b16e
--- /dev/null
+++ b/wmswallow/LICENCE
@@ -0,0 +1,341 @@
+
+                   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) 19yy  <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) 19yy 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.
diff --git a/wmswallow/Makefile b/wmswallow/Makefile
new file mode 100644
index 0000000..b75aa24
--- /dev/null
+++ b/wmswallow/Makefile
@@ -0,0 +1,45 @@
+MAKE=make
+CC=gcc
+CFLAGS=-Wall -g
+RM=rm -f
+X=/usr/X11R6
+INCLUDES=-I$(X)/include
+LIBPATHS=-L${X}/lib
+LIBS=-lXext
+PROG=wmswallow
+OBJS=wmswallow.o
+SH=/bin/sh
+
+default:
+       @echo "Type make <platform> to compile."
+       @echo "Currently supported platforms are:"
+       @echo "   xfree solaris solaris-gcc"
+
+xfree:
+       ${MAKE} main
+
+solaris:
+       ${MAKE} CC=cc CFLAGS="-g -Xa" X=/usr/openwin \
+               LIBPATHS="-L/usr/openwin/lib -R/usr/openwin/lib" \
+               LIBS="-lXext -lX" main
+
+solaris-gcc:
+       ${MAKE} X=/usr/openwin \
+               LIBPATHS="-L/usr/openwin/lib -R/usr/openwin/lib" \
+               LIBS="-lXext -lX" main
+
+main:  ${OBJS}
+       ${CC} ${CFLAGS} $(INCLUDES) ${OBJS} -o ${PROG} ${LIBPATHS} ${LIBS}
+
+tarball:
+       ${SH} -c "cd ..;tar cpO wmswallow/*.c wmswallow/Makefile \
+        wmswallow/todo wmswallow/LICENCE wmswallow/README \
+       wmswallow/README.solaris wmswallow/version.h \
+       wmswallow/CHANGELOG wmswallow/INSTALL wmswallow/wmswallow.spec\
+        |compress > wmswallow.tar.Z"
+
+clean:
+       ${RM} ${PROG} *~ *.o
+
+.c.o:
+       ${CC} ${CFLAGS} $(INCLUDES) -c $<
diff --git a/wmswallow/README b/wmswallow/README
new file mode 100644
index 0000000..6faaac0
--- /dev/null
+++ b/wmswallow/README
@@ -0,0 +1,160 @@
+               wmswallow
+
+       A WindowMaker dock applet to make any application dockable.
+
+       Copyright 2000 by Friedrich Delgado Friedrichs
+
+          (be sure to read the LICENCE file as well)
+
+===========================================================================
+
+Why?
+----
+       I wanted to have coolmail in my Windowmaker dock.
+
+How?
+----
+
+INSTALLATION:
++++++++++++++
+       untar the sources by typing something along the lines of
+
+       zcat wmswallow.tar.Z|tar cvf -
+       cd wmswallow
+       make <platform>
+
+       where platform is currently one out of
+               xfree, solaris, solaris-gcc
+
+       The xfree target works under linux and freebsd.
+
+       Linux is tested best, since i'm hacking this stuff under linux (at
+       home). I have access to several Solaris Workstations (some sparcs, and
+       2 pcs) whith quite different Installations which i regularly use, so
+       the solaris target will at least get some attention. Solaris users
+       please read README.solaris for some hints.
+
+       Other Unices might or might not get happy with the xfree target or
+       some or other... I really think using autoconf/automake for this small
+       app would be overkill. If you devise a proper patch for a different
+       Unix-flavour, i will include it, but i might not be able to test it.
+       (I have currently access to FreeBSD and AIX, in addition to my
+       "home-platforms")
+
+       After compilation put the binary somewhere you like (e.g. in 
/usr/local/bin)
+       and in case you want to delete the Sourcetree, you might want to copy 
the
+       README to /usr/doc/wmswallow
+
+       Now try 
+               wmswallow -h
+       to get a basic idea how it works.
+
+USE:
+++++
+       Then some things you might try out are: 
+       (i.e. lots of)
+       EXAMPLES:
+       =========
+
+-------        wmswallow coolmail coolmail
+               (Will make coolmail docked, but it starts an xterm with mailx
+                per default so you will probably want:)
+
+-------        wmswallow coolmail coolmail -e "xterm -n mutt -T mutt -e mutt"
+
+------- wmswallow glbiff glbiff
+               (glbiff is really a killer! Try it! (If you have some 3D
+                hardware) :-) Find it at
+                http://www.dgp.toronto.edu/~mac/projects/glbiff.html
+
+-------        wmswallow asclock asclock -shape -exe plan
+               (Works with the unpatched "classic" version of asclock)
+
+-------        wmswallow oclock oclock -transparent -minute red -bd green
+               (is one of my personal favorites)
+
+-------        wmswallow tuXeyes tuXeyes --puppy
+               (a nice alternative to xeyes)
+
+-------        wmswallow Lament /usr/local/bin/demos/lament -name Lament -geom 
55x57
+               (/usr/local/bin/demos is where my xscreensaver demos are
+               installed.
+               This commandline demonstrates two things:
+       1. You can give a WM_CLASS on the commandline instead of a WM_NAME
+       2. Some applications don't handle resizing well and must get the correct
+          geometry on their commandline, which is always 55x57 for dockapps.)
+
+-------        wmswallow xaos xaos
+               (This kinda obsoletes wmmand :-)
+
+-------        wmswallow xload xload -nolabel -hl LightSeaGreen -fg 
LightSeaGreen \
+               -bg black -update 5
+               (This is like wmload, but there is a frame at the edges which 
is a
+               little annoying, so wmload is a better choice)
+
+-------        wmswallow -focus XTerm
+               (Weeelll... 
+       1. wmswallow can swallow apps without starting them
+       2. it takes the first it gets
+       3. swallowed apps can take keyboard focus now! (Is that useful? I doubt
+          it, but i could not resist :-))
+
+-------        wmswallow -geom 64x64 -getclick "xterm -e top" xeyes xeyes
+               (A more advanced example. The xeyes look better with 64x64 than
+                with the default width/height of 55x57, and since xeyes ignores
+                mouseclicks, we can grab them and execute an xterm on a click.
+                Note that you must poke xeyes right in the eye! :-)
+
+-------        wmswallow -noshape -getclick gtop -geom 57x57 xload xload 
-nolabel \
+       -hl LightSeaGreen -fg LightSeaGreen -bg black -update 5
+               (This looks and behaves a little more like wmload. Executes
+                the "Gnome Systemmonitor" on a mouse click. The -noshape
+                option lets wmswallow ignore any shape the application might
+                have. I thought this would increase performance for some
+                apps, but it doesn't. [It just uses a very slight bit less
+                memory])
+------- wmswallow -unmanaged xteddy xteddy
+               (swallows the left ear of an xteddy, that will complain about 
it...
+                completely useless :-)
+------- wmswallow -focus bb xterm -bg black -fg white -T bb -fn 
"-*-*-*-*-*-*-2-*-*-*-*-*-*-*" -geometry 50x25 -e bb -driver curses
+               (utterly useless as well! :)
+
+How not?
+--------
+       When should you *not* use wmswallow?
+
+-      In general, if a special dockapp for that purpose already exists, you
+       should use it, because every instance of wmswallow has a memory
+       footprint of about 600k, and a simple dockapp usually uses less
+       ressources. If the WindowMaker developers will one day choose to
+       implement "swallowing" applications as a feature in the WindowMaker
+       dock, this will probably a much more simple and clean solution.
+
+-      You should not swallow applications over slow network links.
+       First tests show, that 2 mbit/s are more than enough, but 90kbit/s get
+       terribly hogged if you run wmswallow on a remote hosts over such a
+       link. Note that i am not referring to your hardware, but to the
+       overall throughput that can be acchieved between the two hosts.
+
+Have a lot of fun... :-)
+
+Thanks
+------
+       The following people helped and/or contributed to wmswallow:
+
+       Dan Piponi <d...@mvfx.com>:
+               Makefile fix for FreeBSD
+
+       Jason Lowdermilk <lowderm...@visto.com>:
+               diff to enable wmswallow really to look after the WM_NAME of a
+               window.
+               Valuable suggestions and code on how to identify the wanted
+               window more reliably.
+               further valuable input
+
+       honx:
+               Giving me the idea to wmswallow, by constantly nagging that
+               WindowMaker cannot swallow apps :-) Next thing to satisfy this
+               dude, somebody will have to write a pager for WindowMaker
+               (like the one for fvwm) that works *without* gnome... Somebody
+               else will have to do that, since i don't like Pagers :-)
diff --git a/wmswallow/README.solaris b/wmswallow/README.solaris
new file mode 100644
index 0000000..4af459e
--- /dev/null
+++ b/wmswallow/README.solaris
@@ -0,0 +1,16 @@
+Whew! You really want this stuff to run under solaris, huh?
+
+Well, you can try "make solaris" if you have got sun-workshop, if you use gcc
+"make solaris-gcc" *might* work. The Problem is, everybody installs libXpm in
+a different place. If you know that your sysadmin put everything that is X11
+related into, say, /usr/X11, the default targets will work. But if libXpm
+resides in /usr/local/lib you might help yourself with:
+
+make SOLX=/usr/local solaris
+
+If all fails, you will have to look at the solaris target and adjust the
+variables INCLUDES and LIBPATHS to help the compiler find the includes and
+libs.
+
+I also noticed that on one machine wmswallow appeared to generate constant
+network load (when i was using it over a remote link) so be aware of problems.
\ No newline at end of file
diff --git a/wmswallow/todo b/wmswallow/todo
new file mode 100644
index 0000000..f9d251b
--- /dev/null
+++ b/wmswallow/todo
@@ -0,0 +1,130 @@
+                                       -*- text -*-
+TODO:
+       Bugs:
+-------------
+
+       Feature-wishes:
+-----------------------
+       detect automatically if a window wants to be managed or not (should be
+       easy, but the -unmanaged switch works well, too)
+
+       Kill apps nicely when killed. (Some signal handling)
+
+       Make wmswallow not only accept mouseclicks on ButtonPress, but also get
+       some contents of the cutbuffer on (say) a middleclick, and then do
+       something user-defineable about it. (generic solution for wmnetselect
+       stuff)
+
+       Write manpage
+
+       Maybe write freebsd port
+
+       Do things reliably/the clean way
+          -> I mean, don't wait for some microsecs, when you can ask the app
+             what's up -> find out how! -> XSync seems to work...
+          -> Wait a second at the right moment helps some things greatly!
+             Still i don't know if it's the "right thing"[TM]
+
+        Problems (maybe unresolvable):
+--------------------------------------
+       WindowMaker segfaults if an instance of wmswallow hangs when
+       the wm is restarted -> Probably windowmaker bug, but can be fixed by
+       better signal-handling on behalf of wmswallow
+
+       If you swallow apps on the clip *and* in the dock at the same time,
+       the apps for the clip wander to the dock and vice versa...
+           Huh? This is most strange. I fear that looks like one of
+           WindowMaker's many bugs.. :) (Yeah, blame it on others, good
+           strategy!)
+
+       Shaped apps that change their shape will look "out of sync". This is
+       especially visible with
+        wmswallow xdaliclock xdaliclock -24 -transparent -cycle \
+                      -geometry 61x61 -fn fixed -oink-oink
+        There are other problems with xdaliclock -transparent (flicker, the
+        seconds are lagged behind respectively out of beat) which do not
+        depend on wmswallow and can be noticed as well, when
+       xdaliclock -transparent is not being swallowed.
+
+       perfmeter objects to have its mouseclicks selected
+               -> As a workaround, i make the XInputSelect Mask dependant on
+                  whether the user wants to click on the window, or not. But
+                  i'd like to do it better (i.e. force perfmeter to accept
+                  the change)
+               -> In fact, for every application that selects ButtonPress
+                  events, the same events cannot be selected twice (manpage
+                  of XSelectInput(3))
+               -> It seems, this "Problem" cannot be fixed!
+
+       click works only on the surface of the swallowed window:
+       (Obviously, because the rest of the area belongs to the
+       dock... Or can that be redeemed?) 
+
+
+===============================================================================
+DONE:
+       Make basic dockable App
+
+       Then steal code off fvwm2 to learn how to swallow stuff
+               -> done.. Wow! That's easy!
+
+       Resize swallowed window appropriately
+
+       Judge what to get by following rule:
+               1. name
+               2. class
+
+       Get command to run from commandline and spawn program.
+
+       Somehow handle shaped windows (Like xeyes)
+               -> Ok, even resizing works
+
+       Option: -updateshape (or similar) for apps that change their shape 
+               (like oclock -transparent)
+               -> is done by default behaviour! :-)
+
+       Clean up allocated space (fix memory holes)!
+               -> Looks ok now. Sending multiple Events under X11 has evil
+                  effects!
+
+       Better command-line switch handling. Following commandline-switches:
+               -noshape/-shape : Switch shape functionality on or off
+               -getclick: Define commandline to exec when window is clicked 
+               -geometry: Define geometry of swallowed application! 
+                       (Size is useful, position as well, to adjust asclock)
+               -id: Give Window-id to swallow
+
+       Freshmeat announcement
+
+       Let apps take keyboard focus
+           -> might or might not be a problem with windowmaker/dock
+           -> It wasn't... :-) wmMand used Enter and Leave events and then set
+              the focus for himself. And i blatantly stole the code... (just
+              2 lines...) :-)
+
+       The currently focused window flickers, when the shape gets updated.
+       This is especially strong with 
+            wmswallow xdaliclock xdaliclock -24 -transparent -cycle \
+                      -geometry 61x61 -fn fixed -oink-oink
+       This also interferes with focus, and it can be seen that the shape
+       gets updated in an unclean way, i.e. the shape and the graphics seem
+       "out of sync"
+            -> Action on Focus event shortened, XMapSubwindows and XMapWindow
+               weren't necessary, stealshape only grabs the shape to the
+               iconwin
+
+       Swallowing sometimes is unreliable (especially on WindowMaker start
+       with many instances) ... Why?
+               -> Theory: Maybe when several instances of wmswallow start,
+                  the tree of windows gets changed in a way that sometimes a
+                  window cannot be found anymore.
+               -> Jason helped a little, i figured the rest out... every
+                  windowmanager reparents windows, and waiting for that is
+                  very reliable...
+                       -> done!
+
+       some apps cannot be found (xmountains). Why? xmountains in particular
+       seems to lack a window-id. I didn't know that was possible...
+               -> resolved by Jason, i did not really check the WM_NAME
+
+       just made an rpm specfile
diff --git a/wmswallow/version.h b/wmswallow/version.h
new file mode 100644
index 0000000..ca61105
--- /dev/null
+++ b/wmswallow/version.h
@@ -0,0 +1 @@
+#define VERSION "0.6.1"
diff --git a/wmswallow/wmswallow.c b/wmswallow/wmswallow.c
new file mode 100644
index 0000000..8de4bd1
--- /dev/null
+++ b/wmswallow/wmswallow.c
@@ -0,0 +1,678 @@
+/* wmswallow.c */
+
+/* #define DEBUG 1 */
+          /* Sometimes i want to get quick access to this flag :-)*/ 
+
+/* Time-stamp: <00/05/15 23:13:43 friedel> */
+
+/* Copyright 2000 Friedrich Delgado Friedrichs */
+
+/* Swallow applications in the Windowmaker dock */
+/* Originally i started with asbeats 0.2 (by iznog...@bohemians.org) (simply
+   the smallest WindowMaker dockapp i could find, since there was no proper
+   Documentation to find on how to make an app dockable), which i stripped
+   down to have a basic dockable app, and then stole code from fvwm2 to
+   swallow an Application */
+/* Man, this was easy! Why did nobody implement this before? (That's me,
+   looking  astonished at the first working version at Mon Apr 17 02:16:31
+   CEST 2000 after only 4 hours of mostly learning how to program the 
X-Environment and
+   hacking and guessing a little :-) */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/shape.h>
+#include <time.h>
+#include <X11/Xatom.h>
+#include <string.h>
+
+#include "version.h"
+
+/* That's all we need from xpm.h */
+#if ! defined(_XtIntrinsic_h) && ! defined(PIXEL_ALREADY_TYPEDEFED)
+typedef unsigned long Pixel;    /* Index into colormap */
+# define PIXEL_ALREADY_TYPEDEFED
+#endif
+/* Now we got rid of that stupid libXpm dependency :-) */
+
+#define WIDTH 55
+#define HEIGHT 57 
+/* 55x57 seems to be the default size for a WindowMaker dockapp */
+/* settable by "-geometry" switch */
+
+Display *dpy;
+Window Root;
+Window iconwin,win;
+Window swallowed;
+XSizeHints mysizehints;
+
+#define MW_EVENTS      (ExposureMask | ButtonPressMask |\
+                         StructureNotifyMask |\
+                         ButtonReleaseMask |\
+                         EnterWindowMask|LeaveWindowMask)
+#define SW_EVENTS       (PropertyChangeMask | StructureNotifyMask |\
+                        ResizeRedirectMask | SubstructureNotifyMask)
+#define FIND_EVENTS     (SubstructureNotifyMask | StructureNotifyMask)
+#define READY_EVENTS     FIND_EVENTS
+#define FALSE 0
+#define TRUE (!FALSE)
+
+Pixel GetColor(char *name);
+void FlushWindow();
+void usage (char *progname);
+int parseargs(int argc, char *argv[]);
+Window findnamedwindow (char *class);
+Window findnamedwindowacc (char *class, Window window);
+int checkwindow (Window window, char *class);
+int execstuff(int argc, char *oldargv[]);
+Window startandfind(int argc, char *oldargv[], char* class);
+int printlist(FILE * stream, char * string, char **stringlist);
+int flush_expose (Window w);
+void stealshape (Window w);
+int sendexpose (Window w);
+void waitformap (Window win);
+/* int softenwindow (Window w); */ /* won't work, kept for historical reasons 
*/
+
+/* Parameters that can be customized via commandline switches */
+char *execstring=NULL;
+char *geometry=NULL;
+int getclick=FALSE;
+int shape=TRUE;
+int focus=FALSE;
+int unmanaged=FALSE;
+int winid=0;
+char *display_name=NULL; 
+
+int main(int argc,char *argv[])
+{
+  int screen;
+  int d_depth;
+  XWMHints mywmhints;
+  Pixel back_pix,fore_pix;
+
+  int i;
+  unsigned int borderwidth;
+  char *wname="wmswallow";
+
+  int remainarg, remainargc;
+
+  XEvent Event;
+  XTextProperty name;
+  XClassHint classHint;
+
+  remainarg=parseargs(argc, argv); /* remainarg > 0 afterwards */
+  remainargc=argc-remainarg;
+#ifdef DEBUG
+  fprintf(stderr, "remainarg: %d, remainargc: %d, argc: %d\n", remainarg,
+         remainargc,argc);
+  fflush(stderr);
+#endif
+
+  if (!(dpy = XOpenDisplay(display_name))) { 
+    fprintf(stderr,"wmswallow: can't open display %s\n", 
+           XDisplayName(display_name)); 
+    exit (1); 
+  } 
+  screen=DefaultScreen(dpy);
+  Root=RootWindow(dpy, screen);
+
+  /* So, now we've got everything we need to get Events from the XServer */
+  if (remainargc>1) {
+    winid=startandfind(remainargc-1, argv+remainarg+1, argv[remainarg]);
+    if (winid==0) {
+      perror("wmswallow: startandfind failed"); 
+      /* Real error handling in execstuff()*/
+      exit (1);
+    }
+  }
+
+  d_depth=DefaultDepth(dpy, screen);
+  /*   XConnectionNumber(dpy); */ /* useless */
+  mysizehints.flags=USSize|USPosition;
+  mysizehints.x=0;
+  mysizehints.y=0;
+  back_pix=GetColor("white");
+  fore_pix=GetColor("black");
+  XWMGeometry(dpy, screen, geometry, NULL, (borderwidth =1),
+             &mysizehints, &mysizehints.x, &mysizehints.y,
+             &mysizehints.width, &mysizehints.height, &i); 
+  mysizehints.width=WIDTH;
+  mysizehints.height=HEIGHT;
+  if (geometry!=NULL) {
+#ifdef DEBUG
+    fprintf(stderr,"Setting geometry to: %s\n",geometry);
+    fflush(stderr);
+#endif
+    XParseGeometry(geometry, &mysizehints.x, &mysizehints.y, 
+                  &mysizehints.width, &mysizehints.height);
+  }
+  
+  win=XCreateSimpleWindow(dpy, Root, mysizehints.x, mysizehints.y,
+                         mysizehints.width, mysizehints.height, borderwidth,
+                         fore_pix, back_pix);
+  iconwin=XCreateSimpleWindow(dpy, win, mysizehints.x, mysizehints.y,
+                             mysizehints.width, mysizehints.height, 
borderwidth,
+                             fore_pix, back_pix);
+  XSetWMNormalHints(dpy, win, &mysizehints);
+  classHint.res_name="wmswallow";
+  classHint.res_class="WMswallow";
+  XSetClassHint(dpy, win, &classHint);
+  XSelectInput(dpy, win, MW_EVENTS);
+  XSelectInput(dpy, iconwin, MW_EVENTS);
+  if(XStringListToTextProperty(&wname, 1, &name)==0)
+    {
+      fprintf(stderr, "wmswallow: can't allocate window name\n");
+      exit(-1);
+    }
+  XSetWMName(dpy, win, &name);
+  mywmhints.initial_state = WithdrawnState;
+  mywmhints.icon_window = iconwin;
+  mywmhints.icon_x = mysizehints.x;
+  mywmhints.icon_y = mysizehints.y;
+  mywmhints.window_group = win;
+  mywmhints.flags = StateHint | IconWindowHint |
+    IconPositionHint | WindowGroupHint;
+  XSetWMHints(dpy, win, &mywmhints); 
+  XSetCommand(dpy, win, argv, argc);
+
+  if (winid==0) {
+    swallowed=findnamedwindow(argv[remainarg]); /* Find which window to
+                                                  swallow*/
+#ifdef DEBUG
+    fprintf(stderr,"%s has Window-id 0x%lx\n", argv[remainarg], swallowed); 
+    fflush(stderr);
+#endif  
+  }
+  else
+    swallowed=winid;
+
+  
+  /* "Swallow" it */
+  XReparentWindow(dpy, swallowed, iconwin, 0, 0);
+  if (getclick) {
+    /* softenwindow (swallowed); */ /* Change some attributes */
+    XSelectInput(dpy, swallowed, SW_EVENTS|ButtonPressMask);
+  }
+  else {
+    XSelectInput(dpy, swallowed, SW_EVENTS); /* Workaround for apps like
+                                               perfmeter that don't let us
+                                               get their mouseclicks :-( */
+  }
+  XSetWindowBorderWidth(dpy, swallowed,0);
+  XMoveResizeWindow(dpy, swallowed, 0, 0,
+                   mysizehints.width, mysizehints.height);
+
+  /* Now we do some special juju for shaped windows: */
+
+  /* ...tell the window to repaint itself, please! */
+  if (shape) {
+    sendexpose(swallowed);
+
+    /* ... ok, window should be repainted and a shaped window should have 
updated
+       its mask accordingly! (-: End of shape-juju :-) */
+
+    /* Now steal the shape of the Window we just swallowed! */
+    stealshape(swallowed); }
+  XMapWindow(dpy,win);
+  XMapSubwindows(dpy,win);
+  FlushWindow();
+
+  while(1)
+    {
+      while (XPending(dpy))
+       {
+         XNextEvent(dpy,&Event);
+         switch(Event.type)
+           {
+           case ButtonPress:
+#ifdef DEBUG
+             fprintf (stderr, "wmswallow: Got ButtonPress Event\n");
+             fflush(stderr);
+#endif
+             if (getclick)
+               system(execstring);
+             break;
+           case Expose:
+             if(Event.xexpose.count == 0 ) {
+#ifdef DEBUG
+               fprintf (stderr, "wmswallow: Got Expose Event, count==0\n");
+               fflush(stderr);
+#endif
+               if (shape)
+                 stealshape(swallowed); /* Oclock changes its shape! That's why
+                                           we have to steal it *again* */
+               FlushWindow();
+               XMapRaised(dpy,swallowed);
+               /* the following Produces "focus-flicker" */
+               /* XMapSubwindows(dpy,win); */ 
+               /* XMapWindow(dpy,win); */
+             }
+             break;
+           case EnterNotify:
+             if (focus)
+               XSetInputFocus(dpy, swallowed, RevertToPointerRoot,
+               CurrentTime);
+             break;
+           case LeaveNotify:
+             if (focus)
+               XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot,
+               CurrentTime);
+             break;
+
+           case DestroyNotify:
+             XCloseDisplay(dpy);
+             exit(0); 
+           default:
+#ifdef DEBUG
+             /* fprintf (stderr, "wmswallow: Got Some Other Event\n");
+                             fflush(stderr); */
+#endif
+             break;      
+           }
+       }
+      XFlush(dpy);
+      usleep(50000L);
+    }
+  return 1;
+}
+
+/* int softenwindow (Window w) { */
+/*   XSetWindowAttributes attributes; */
+
+/*   attributes.override_redirect=FALSE; */
+/*   attributes.event_mask=SW_EVENTS|MW_EVENTS; */
+/*   attributes.do_not_propagate_mask=0; */
+  
+/*   XChangeWindowAttributes(dpy, w, */
+/*   CWOverrideRedirect|CWEventMask|CWDontPropagate, */
+/*                       &attributes); */
+/*   return TRUE; */
+/* } */
+
+int sendexpose (Window w) {
+  XExposeEvent xexp;
+  XEvent Event;
+  int retval;
+
+  xexp.type=Expose;
+  xexp.serial=0;
+  xexp.send_event=TRUE;
+  xexp.display=dpy;
+  xexp.window=w;
+  xexp.x=0;
+  xexp.y=0;
+  xexp.width=mysizehints.width;
+  xexp.height=mysizehints.height;
+  xexp.count=0;
+  Event.xexpose=xexp;
+  retval=XSendEvent(dpy, w, FALSE, ExposureMask, &Event);
+  /*   XFlush(dpy); */ /* ... send all queued Events  */
+  /*   usleep(5000L); */ /* ... take a tiny doze */
+  XSync(dpy, FALSE); /* I doubt if this is really better than Flushing and
+                       pausing */
+  return retval;
+}
+
+void stealshape(Window w) {
+  XShapeCombineShape (dpy, iconwin, ShapeBounding, 0, 0, w, 
+                     ShapeBounding, ShapeSet);
+  /* XShapeCombineShape (dpy, win, ShapeBounding, 0, 0, w,  */
+  /*                 ShapeBounding, ShapeSet); */
+  /*Re-read specs! */ 
+  /*   XShapeCombineShape (dpy, win, ShapeClip, 0, 0, w,  */
+  /*                 ShapeClip, ShapeSet); */
+  /*   XShapeCombineShape (dpy, iconwin, ShapeClip, 0, 0, w, */
+  /*                 ShapeClip, ShapeSet); */
+}
+
+void nocolor(char *a, char *b)
+{
+  fprintf(stderr,"wmswallow: can't %s %s\n", a,b);
+}
+
+
+int flush_expose (Window w)
+{
+  XEvent dummy;
+  int i=0;
+  while(XCheckTypedWindowEvent(dpy,w,Expose,&dummy))
+    i++;
+  return i;
+}
+
+void FlushWindow()
+{
+  flush_expose(swallowed);
+  flush_expose (iconwin);
+  flush_expose(win);
+}
+
+Pixel GetColor(char *name)
+{
+  XColor color;
+  XWindowAttributes attributes;
+  XGetWindowAttributes(dpy,Root,&attributes);
+  color.pixel=0;
+  if (!XParseColor(dpy,attributes.colormap,name,&color)) 
+    nocolor("parse",name);
+  else if(!XAllocColor (dpy,attributes.colormap,&color)) 
+    nocolor("alloc",name);
+  return color.pixel;
+}
+
+void usage(char *progname){
+  printf(
+        "wmswallow Version %s\n"
+        "               by Friedrich Delgado Friedrichs (c) 2000\n"
+        "\n"
+        "Usage:\n"
+        "  %s [<flags>] [windowname [command [args ...]]]\n"
+        "  Will swallow the first X-Window it finds with a WM_NAME or\n"
+        "           WM_CLASS matching <windowname>\n"
+        "\n"
+        "        Flags:\n"
+        " -h:                  prints this message and exits\n"
+        " -geometry <string>:  use specified geometry for swallowed\n"
+        "                      window\n"
+        " -display <string>:   connect to specified display\n"
+        " -shape:              use the shape extension (default)\n"
+        " -noshape:            don't use the shape extension\n"
+        " -focus:              Window should take focus\n"
+        " -nofocus:            Window shouldn't take focus(default)\n"
+        " -managed:            Assume window is managed by the\n"
+        "                      windowmanager (default)\n" 
+        " -unmanaged:          Assume window is not managed by the\n"
+        "                      windowmanager\n" 
+        " -getclick <string>:  on mouseclick, execute <string>\n"
+        "                      instead of passing the Event to the\n"
+        "                      swallowed window.\n"
+        " -id [0x]<hexnumber>: swallow window with id <hexnumber>\n"
+        "  The command with args will be executed, before swallowing.\n",
+        VERSION, progname);
+}
+
+/* Parse commandline args, returns first non-switch argnumber */
+int parseargs(int argc, char *argv[]){
+  int argnum;
+  int lastarg=1;
+  if (argc<2) {
+    usage(argv[0]);
+    exit(0);
+  }
+
+  for(argnum=1; argnum<argc && *argv[argnum]=='-'; lastarg=++argnum) {
+    if (!strncmp(argv[argnum],"-h",2) ||
+       !strncmp(argv[argnum],"--",2)) {
+      usage(argv[0]);
+      exit(0);
+    } else if (!strcmp(argv[argnum],"-geometry")|| 
+              !strcmp(argv[argnum],"-geom"))
+      geometry=argv[++argnum];
+    else if (!strcmp(argv[argnum],"-display"))
+      display_name = argv[++argnum];
+    else if (!strcmp(argv[argnum],"-noshape"))
+      shape=FALSE;
+    else if (!strcmp(argv[argnum],"-shape"))
+      shape=TRUE;
+    else if (!strcmp(argv[argnum],"-unmanaged"))
+      unmanaged=TRUE;
+    else if (!strcmp(argv[argnum],"-managed"))
+      unmanaged=FALSE;
+    else if (!strcmp(argv[argnum],"-nofocus"))
+      focus=FALSE;
+    else if (!strcmp(argv[argnum],"-focus"))
+      focus=TRUE;
+    else if (!strcmp(argv[argnum],"-getclick")) {
+      execstring=(char *)malloc(strlen(argv[++argnum])+1+2);
+      strcpy(execstring, argv[argnum]);
+      strcat(execstring, " &");
+      getclick=TRUE;
+    } else if (!strcmp(argv[argnum],"-id"))
+      winid=strtol(argv[++argnum], NULL, 16);
+    else {
+      usage(argv[0]);
+      exit(0);
+    }
+  }
+  return lastarg; /*Return number of first argument, that is neither a switch 
nor
+                     an argument to a switch */
+}
+
+
+/* Print a NULL-terminated list of char* onto file stream */
+int printlist(FILE * stream, char * string, char **stringlist) {
+  int i=0;
+
+  fprintf(stream, string);
+  if (stringlist!=NULL) {
+    while (stringlist[i]!=NULL) {
+      fprintf(stream, " �");
+      fprintf(stream, stringlist[i]);
+      fprintf(stream, "� ");
+      ++i;
+    }
+  } else {
+    return(TRUE);
+  }
+  return(FALSE);
+}
+
+/* Select SubstructureNotify on the root-window, start the command, then look
+   if we get Create Events for a matching window, set winid */
+Window startandfind (int argc, char *oldargv[], char* class) {
+  int found=0;
+  XEvent Event;
+  Window winreturn=(Window)0;
+  Window wintmp=(Window)0;
+
+#ifdef DEBUG
+  fprintf(stderr, "Checking for name: %s\n", class);
+  fflush(stderr);
+#endif
+
+  XSelectInput(dpy, Root, FIND_EVENTS);
+  if (!execstuff(argc, oldargv))
+    return FALSE; /* execstuff failed, should not return, but
+                    nevertheless...*/
+  while (!found) {
+    while (!found && XPending(dpy)) {
+      /* FIXME: We hang, when the application starts, but we
+        cannot find the window! */
+      XNextEvent(dpy, &Event);
+      switch (Event.type) { /* Switch, in case we check for more than one
+                              Event-Type one day */
+       /* We're waiting for the wm to reparent the window! */
+      case ReparentNotify:
+#ifdef DEBUG
+       fprintf (stderr, "wmswallow: Got ReparentNotify Event\n");
+       fflush(stderr);
+#endif
+       wintmp=Event.xreparent.window;
+       if (checkwindow(wintmp, class)) {
+         winreturn=wintmp;
+         found=TRUE;
+       } else if ((winreturn=findnamedwindowacc(class, wintmp))) {
+         found=TRUE;
+       }
+       break;
+      case CreateNotify: case MapNotify:
+       wintmp=Event.xcreatewindow.window;
+#ifdef DEBUG
+       fprintf (stderr, "wmswallow: Got CreateNotify Event for window "
+                "0x%lx\n", wintmp);
+       fflush(stderr);
+#endif
+       if (unmanaged) {
+         if (checkwindow(wintmp, class)) {
+           winreturn=wintmp;
+           found=TRUE;
+         } else if ((winreturn=findnamedwindowacc(class, wintmp))) {
+           found=TRUE;
+         }
+       }
+       break;
+      default:
+       break;
+      }
+    }
+  }
+  XSelectInput(dpy, Root, None);
+#ifdef DEBUG
+  fprintf (stderr, "wmswallow: found it"
+          "0x%lx\n", wintmp);
+  fflush(stderr);
+#endif
+  
+  waitformap(winreturn);
+  /* Ok, the window has been created, Reparented by WindowMaker and mapped */
+  /* What else can we do to make sure the window was created? */
+
+  sleep(1); /* doze just a sec, should be more than enough in any case */
+  
+  return winreturn;
+}
+
+/* Execute a command */
+int execstuff (int argc, char *oldargv[]) {
+  char **argv;
+  int i, success, forked;
+
+  argv=(char **)malloc((argc+1)*sizeof(char *));
+  
+  for (i=0; i<argc; i++) {
+    argv[i]=oldargv[i];
+  }
+  argv[i]=NULL;
+  
+  forked=fork();
+  if (forked==-1) {
+    perror("Could not fork");
+    exit(1);
+  }
+  if (forked) {
+#ifdef DEBUG
+    printlist(stderr, "Trying to execute:", argv);
+    fprintf(stderr, "\n");
+#endif
+    success=execvp(argv[0],argv);
+    if (success!=0) {
+      printlist(stderr, "Could not execute:", argv);
+      fprintf(stderr, "\n");
+      exit(1);
+    } 
+  } /* Removed the sleep, since it keeps us from getting the Create Event */
+  free(argv);
+  return(TRUE);
+}
+
+void waitformap (Window win) {
+  int found=0;
+  XEvent Event;
+
+  XSelectInput(dpy, win, READY_EVENTS);
+  found=0;
+  while (!found && XPending(dpy)) {
+    if (XCheckMaskEvent(dpy, READY_EVENTS, &Event))
+      if (Event.type==MapNotify)
+       if (Event.xmap.window==win)
+         found=TRUE;
+  }
+#ifdef DEBUG
+  fprintf (stderr, "wmswallow: Got MapNotify Event for window 0x%lx\n", win);
+  fflush(stderr);
+#endif
+  while (XCheckTypedWindowEvent(dpy, win, MapNotify, &Event))
+    ; /* Flush the map Events */
+  XSelectInput(dpy, win, None);
+}
+
+/* Find window which matches WM_NAME or WM_CLASS */
+Window findnamedwindow (char *class) {
+  /* Get All Children of the Root-Window */
+  Window result;
+  if ((result=(findnamedwindowacc (class, Root)))!=0)
+    return result;
+  else {
+    fprintf(stderr, "Could not find %s\n", class);
+    exit (1);
+  }
+}
+
+/* Recursively walk through all the windows and their children to find the
+   first one that matches WM_NAME or WM_CLASS */
+/* Only called by findnamedwindow() */
+Window findnamedwindowacc (char *class, Window window) {
+  Window root_return;
+  Window parent_return;
+  Window *children_return;
+  unsigned int nchildren_return;
+  Window runner;
+  Window result;
+  int i;
+
+  children_return=(Window *)NULL;
+  result=(Window)0;
+
+  if (checkwindow(window, class))
+    return window;
+  
+  if (XQueryTree (dpy, window, &root_return, &parent_return,
+                 &children_return, &nchildren_return)&&nchildren_return>0) {
+    for
+      (i=0,runner=*children_return;i<nchildren_return;
+       runner=children_return[++i]) {
+      if ((result=findnamedwindowacc(class, runner))!=0)
+       break; /* Leave this loop */ /* It's one of the children */
+    }
+    /* end of for loop*/ /* checked all windows to no avail */
+  } /* If the if (XQueryTree...)-part wasn't executed, wmswallow could not get
+       Windows (probably no children) */
+  if (children_return)
+    XFree(children_return);
+  return result;
+}
+
+/* Checks if the window has WM_NAME or WM_CLASS properties fitting *class */
+int checkwindow (Window window, char *class) {
+  XClassHint class_hints;
+  XTextProperty prop;
+  
+  int found=0;
+  
+  class_hints.res_name = class_hints.res_class = prop.value =(char *) NULL;
+
+  /* Check WM_CLASS properties name and class */
+  if (XGetClassHint(dpy, window, &class_hints)) {
+    if (!strcmp(class_hints.res_name, class)  ||
+       !strcmp(class_hints.res_class, class)) {
+      found = 1; /* It's this window! */
+    }
+#ifdef DEBUG
+    fprintf (stderr, "wmswallow: checkwindow: 0x%lx, class: %s, name: %s\n",
+            win, class_hints.res_class, class_hints.res_name);
+    fflush(stderr);
+#endif
+  }
+  /* Check WM_NAME property */
+  if (!found && XGetWMName(dpy, window, &prop))
+    if (prop.nitems && !strcmp(prop.value, class)) {
+      found = 1; /* (-: It's really this window, and we're lucky we guessed its
+                   name correctly :-) */
+    }
+#ifdef DEBUG
+  fprintf (stderr, "wmswallow: WM_NAME: %s\n",
+          prop.value);
+  fflush(stderr);
+#endif
+  
+  /* Clean up */
+  if (prop.value)
+    XFree(prop.value);
+  if (class_hints.res_class)
+    XFree(class_hints.res_class);
+  if (class_hints.res_name)
+    XFree(class_hints.res_name);
+  return found;
+}
diff --git a/wmswallow/wmswallow.spec b/wmswallow/wmswallow.spec
new file mode 100644
index 0000000..0ba7272
--- /dev/null
+++ b/wmswallow/wmswallow.spec
@@ -0,0 +1,56 @@
+%define name   wmswallow
+%define ver    0.6
+%define rel    1
+%define copy   GPL
+%define ich friedel <frie...@burse.uni-hamburg.de>
+%define group  X11/WindowMaker Applets
+%define realname %{name}
+Summary:       wmswallow is a WindowMaker dock applet to make any application 
dockable in the WindowMaker dock
+Name:          %{name}
+Version:       %{ver}
+Release:       %{rel}
+Copyright:     %{copy}
+Packager: %{ich}
+URL: http://burse.uni-hamburg.de/~friedel/software/wmswallow.html
+Group: %{group}
+Source: http://burse.uni-hamburg.de/~friedel/software/wmswallow/wmswallow.tar.Z
+BuildRoot: /var/tmp/%{name}-root
+#Patch: %{name}-%{ver}.patch
+%description
+-    wmswallow was mainly created to swallow coolmail in the WindowMaker dock, 
but it can
+     swallow about any X-window you conceive. 
+-    The window may receive mouseclicks, 
+-    for windows that do not get mouseclicks (like xload or xeyes), you can 
specify a
+     shell-command to execute on a click. 
+-    The geometry for the swallowed app can be specified. Only HEIGHTxWIDTH 
are used,
+     however.  
+-    Applications can be started on wmswallows commandline. An already running 
window
+     can be swallowed, either by name, class or directly by window-id 
+-    The window may receive keyboard-focus, if you specify the "-focus" 
switch. 
+-    Even windows (like xteddy or wine) that hide from the windowmanager can be
+     swallowed with the -unmanaged switch 
+%changelog
+
+%prep
+
+%setup -n %{realname}
+
+#%patch -p1
+
+%build
+make xfree
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/usr/local/bin
+cp wmswallow $RPM_BUILD_ROOT/usr/local/bin
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root)
+%doc CHANGELOG README todo INSTALL README.solaris LICENCE
+/usr/local/bin/wmswallow
+
-- 
2.7.4


-- 
To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to